modwire 4.0.0__tar.gz → 4.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {modwire-4.0.0 → modwire-4.0.2}/.github/modwire-ecosystem.yml +3 -1
- {modwire-4.0.0 → modwire-4.0.2}/.github/scripts/reconcile_ecosystem.py +11 -6
- modwire-4.0.0/.github/workflows/python-github-release.yml → modwire-4.0.2/.github/workflows/python-release-assets.yml +7 -5
- {modwire-4.0.0 → modwire-4.0.2}/.github/workflows/release.yml +17 -16
- {modwire-4.0.0 → modwire-4.0.2}/CHANGELOG.md +14 -0
- {modwire-4.0.0/src/modwire.egg-info → modwire-4.0.2}/PKG-INFO +1 -1
- {modwire-4.0.0 → modwire-4.0.2}/docs/governance/github-ecosystem.md +5 -4
- {modwire-4.0.0 → modwire-4.0.2}/docs/governance/python-workflows.md +26 -22
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/_version.py +3 -3
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/projects/ecosystem.py +3 -1
- {modwire-4.0.0 → modwire-4.0.2/src/modwire.egg-info}/PKG-INFO +1 -1
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire.egg-info/SOURCES.txt +1 -1
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire.egg-info/scm_file_list.json +1 -1
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire.egg-info/scm_version.json +2 -2
- {modwire-4.0.0 → modwire-4.0.2}/tests/test_ecosystem_contract.py +1 -0
- {modwire-4.0.0 → modwire-4.0.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.github/workflows/ci.yml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.github/workflows/python-package.yml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.github/workflows/python-release-build.yml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.gitignore +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.modwire/boundaries.yaml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/.modwire/shape.yaml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/CONTRIBUTING.md +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/LICENSE +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/MANIFEST.in +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/Makefile +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/README.md +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/docs/wiki/Development-checks.md +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/docs/wiki/Home.md +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/docs/wiki/Reporting-bugs.md +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/docs/wiki/Requesting-features.md +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/pyproject.toml +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/setup.cfg +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/app.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/analyzer.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/analyzers/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/analyzers/analyzer_base.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/analyzers/backward.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/analyzers/no_cycles.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/analyzers/no_reentry.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/base.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/collector.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/tags/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/tags/matcher.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/tags/tag_map.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/base.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/collector.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/reporters/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/reporters/base.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/reporters/callables.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/reporters/clusters.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/reporters/coherence.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/reporters/exports.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/insights/reporters/hotspots.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/map/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/map/base.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/map/collector.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/map/loader.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/base.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/collector.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/abstract_class_resolver.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/callable_resolver.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/class_resolver.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/file_resolver.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/import_resolver.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/property_resolver.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/signature_resolver.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/symbol_resolver.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/code/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/code/package.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/code/reader.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/code/writer.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/facade.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/layers/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/layers/app.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/modules/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/modules/app.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/projects/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/projects/app.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/py.typed +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/base.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/config/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/config/architecture.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/config/layers.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/config/modules.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/config/modwire.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/config/projects.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/config/shape.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/report/__init__.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire/shared/report/base.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire.egg-info/dependency_links.txt +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire.egg-info/requires.txt +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/src/modwire.egg-info/top_level.txt +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/tests/test_architecture.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/tests/test_models.py +0 -0
- {modwire-4.0.0 → modwire-4.0.2}/uv.lock +0 -0
|
@@ -62,7 +62,9 @@ workflows:
|
|
|
62
62
|
release_entrypoint: .github/workflows/release.yml
|
|
63
63
|
verify_reusable: .github/workflows/python-package.yml
|
|
64
64
|
release_build_reusable: .github/workflows/python-release-build.yml
|
|
65
|
-
|
|
65
|
+
release_assets_reusable: .github/workflows/python-release-assets.yml
|
|
66
|
+
release_driver: github_release
|
|
67
|
+
release_event: published
|
|
66
68
|
release_tag_pattern: ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$
|
|
67
69
|
artifact_name: python-package-distributions
|
|
68
70
|
pypi_environment: pypi
|
|
@@ -40,7 +40,7 @@ def workflow_drift(contract: EcosystemContract) -> list[str]:
|
|
|
40
40
|
contract.workflows.release_entrypoint,
|
|
41
41
|
contract.workflows.verify_reusable,
|
|
42
42
|
contract.workflows.release_build_reusable,
|
|
43
|
-
contract.workflows.
|
|
43
|
+
contract.workflows.release_assets_reusable,
|
|
44
44
|
)
|
|
45
45
|
contents: dict[str, str] = {}
|
|
46
46
|
for relative_path in workflow_paths:
|
|
@@ -74,7 +74,7 @@ def workflow_drift(contract: EcosystemContract) -> list[str]:
|
|
|
74
74
|
required_references = {
|
|
75
75
|
contract.workflows.release_entrypoint: (
|
|
76
76
|
contract.workflows.release_build_reusable,
|
|
77
|
-
contract.workflows.
|
|
77
|
+
contract.workflows.release_assets_reusable,
|
|
78
78
|
contract.workflows.actions.download_artifact,
|
|
79
79
|
contract.workflows.actions.publish_pypi,
|
|
80
80
|
),
|
|
@@ -88,7 +88,7 @@ def workflow_drift(contract: EcosystemContract) -> list[str]:
|
|
|
88
88
|
contract.workflows.actions.setup_python,
|
|
89
89
|
contract.workflows.actions.upload_artifact,
|
|
90
90
|
),
|
|
91
|
-
contract.workflows.
|
|
91
|
+
contract.workflows.release_assets_reusable: (
|
|
92
92
|
contract.workflows.actions.download_artifact,
|
|
93
93
|
),
|
|
94
94
|
}
|
|
@@ -102,19 +102,24 @@ def workflow_drift(contract: EcosystemContract) -> list[str]:
|
|
|
102
102
|
"python - <<",
|
|
103
103
|
"SETUPTOOLS_SCM_PRETEND_VERSION",
|
|
104
104
|
"softprops/",
|
|
105
|
-
"types: [published]",
|
|
106
105
|
):
|
|
107
106
|
if forbidden in release or forbidden in release_build:
|
|
108
107
|
errors.append(f"release workflows contain forbidden pattern {forbidden}")
|
|
109
108
|
if contract.workflows.artifact_name not in release or contract.workflows.artifact_name not in release_build:
|
|
110
109
|
errors.append("release artifact name differs from the workflow contract")
|
|
111
|
-
|
|
110
|
+
release_assets = contents.get(contract.workflows.release_assets_reusable, "")
|
|
112
111
|
if (
|
|
113
112
|
"workflow_call:" not in verify
|
|
114
113
|
or "workflow_call:" not in release_build
|
|
115
|
-
or "workflow_call:" not in
|
|
114
|
+
or "workflow_call:" not in release_assets
|
|
116
115
|
):
|
|
117
116
|
errors.append("reusable workflows must use workflow_call")
|
|
117
|
+
if "release:" not in release or "types: [published]" not in release:
|
|
118
|
+
errors.append("release.yml must be driven by a published GitHub Release")
|
|
119
|
+
if "skip-existing: true" not in release:
|
|
120
|
+
errors.append("release.yml must make PyPI publication idempotent")
|
|
121
|
+
if '--repo "$GITHUB_REPOSITORY"' not in release_assets:
|
|
122
|
+
errors.append("release assets must target GITHUB_REPOSITORY explicitly")
|
|
118
123
|
return errors
|
|
119
124
|
|
|
120
125
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
name: Reusable Python
|
|
1
|
+
name: Reusable Python release assets
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
workflow_call:
|
|
5
5
|
inputs:
|
|
6
6
|
release-tag:
|
|
7
|
-
description:
|
|
7
|
+
description: Published GitHub Release tag receiving the distributions.
|
|
8
8
|
required: true
|
|
9
9
|
type: string
|
|
10
10
|
artifact-name:
|
|
@@ -18,7 +18,7 @@ permissions:
|
|
|
18
18
|
|
|
19
19
|
jobs:
|
|
20
20
|
publish:
|
|
21
|
-
name:
|
|
21
|
+
name: Attach distributions to GitHub release
|
|
22
22
|
runs-on: ubuntu-latest
|
|
23
23
|
steps:
|
|
24
24
|
- name: Download release distributions
|
|
@@ -27,8 +27,10 @@ jobs:
|
|
|
27
27
|
name: ${{ inputs.artifact-name }}
|
|
28
28
|
path: dist/
|
|
29
29
|
|
|
30
|
-
- name:
|
|
30
|
+
- name: Upload GitHub release assets
|
|
31
31
|
env:
|
|
32
32
|
GH_TOKEN: ${{ github.token }}
|
|
33
33
|
RELEASE_TAG: ${{ inputs.release-tag }}
|
|
34
|
-
run:
|
|
34
|
+
run: >-
|
|
35
|
+
gh release upload "$RELEASE_TAG" dist/* --clobber
|
|
36
|
+
--repo "$GITHUB_REPOSITORY"
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
name: Release
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
- "v*"
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
7
6
|
|
|
8
7
|
permissions:
|
|
9
8
|
contents: read
|
|
@@ -13,11 +12,22 @@ jobs:
|
|
|
13
12
|
name: Build release distributions
|
|
14
13
|
uses: ./.github/workflows/python-release-build.yml
|
|
15
14
|
with:
|
|
16
|
-
release-tag: ${{ github.
|
|
15
|
+
release-tag: ${{ github.event.release.tag_name }}
|
|
16
|
+
|
|
17
|
+
publish-github-assets:
|
|
18
|
+
name: Attach distributions to GitHub release
|
|
19
|
+
needs: build
|
|
20
|
+
uses: ./.github/workflows/python-release-assets.yml
|
|
21
|
+
with:
|
|
22
|
+
release-tag: ${{ github.event.release.tag_name }}
|
|
23
|
+
permissions:
|
|
24
|
+
contents: write
|
|
17
25
|
|
|
18
26
|
publish-pypi:
|
|
19
27
|
name: Publish distributions to PyPI
|
|
20
|
-
needs:
|
|
28
|
+
needs:
|
|
29
|
+
- build
|
|
30
|
+
- publish-github-assets
|
|
21
31
|
runs-on: ubuntu-latest
|
|
22
32
|
environment:
|
|
23
33
|
name: pypi
|
|
@@ -33,14 +43,5 @@ jobs:
|
|
|
33
43
|
|
|
34
44
|
- name: Publish distributions with Trusted Publishing
|
|
35
45
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
name: Publish GitHub release
|
|
39
|
-
needs:
|
|
40
|
-
- build
|
|
41
|
-
- publish-pypi
|
|
42
|
-
uses: ./.github/workflows/python-github-release.yml
|
|
43
|
-
with:
|
|
44
|
-
release-tag: ${{ github.ref_name }}
|
|
45
|
-
permissions:
|
|
46
|
-
contents: write
|
|
46
|
+
with:
|
|
47
|
+
skip-existing: true
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.2 - 2026-07-11
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Release asset uploads now target `GITHUB_REPOSITORY` explicitly when running
|
|
8
|
+
from a reusable workflow without a repository checkout.
|
|
9
|
+
|
|
10
|
+
## 4.0.1 - 2026-07-11
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- GitHub Release publication now drives distribution building, asset
|
|
15
|
+
attachment, and idempotent PyPI Trusted Publishing.
|
|
16
|
+
|
|
3
17
|
## 4.0.0 - 2026-07-11
|
|
4
18
|
|
|
5
19
|
### Breaking Changes
|
|
@@ -116,7 +116,7 @@ Every coordinator epic should state:
|
|
|
116
116
|
## Workflow contract
|
|
117
117
|
|
|
118
118
|
The complete [Python workflow contract](python-workflows.md) defines the
|
|
119
|
-
coordinator's reusable CI, release-build, and
|
|
119
|
+
coordinator's reusable CI, release-build, and release-assets workflows plus the
|
|
120
120
|
small repository-local entrypoints. Action versions, filenames, tag syntax,
|
|
121
121
|
artifact naming, and environment naming are part of the ecosystem SSOT.
|
|
122
122
|
Member repositories call a reviewed workflow-contract tag such as
|
|
@@ -132,9 +132,10 @@ The reusable workflow must always:
|
|
|
132
132
|
|
|
133
133
|
Package release workflows remain local because publishing environments,
|
|
134
134
|
package names, and PyPI Trusted Publisher identities are repository-specific.
|
|
135
|
-
Only the credential-bearing PyPI job is local; build and GitHub Release
|
|
136
|
-
come from the coordinator's reusable workflows.
|
|
137
|
-
|
|
135
|
+
Only the credential-bearing PyPI job is local; build and GitHub Release asset
|
|
136
|
+
logic come from the coordinator's reusable workflows. Publishing a GitHub
|
|
137
|
+
Release is the event that drives PyPI publication. Releases must never require
|
|
138
|
+
a pre-existing `.dev` directory.
|
|
138
139
|
|
|
139
140
|
## Ecosystem integration gate
|
|
140
141
|
|
|
@@ -11,29 +11,31 @@ PyPI environment are declared under `workflows` in
|
|
|
11
11
|
| --- | --- |
|
|
12
12
|
| `ci.yml` | Repository-local triggers and any package-specific supplemental checks. |
|
|
13
13
|
| `python-package.yml` | Reusable Python matrix tests, Ruff, build, Twine check, and optional artifact upload. |
|
|
14
|
-
| `release.yml` | Repository-local
|
|
14
|
+
| `release.yml` | Repository-local GitHub Release trigger and PyPI Trusted Publishing job. |
|
|
15
15
|
| `python-release-build.yml` | Reusable strict tag validation, clean SCM-derived build, Twine check, version check, and artifact upload. |
|
|
16
|
-
| `python-
|
|
16
|
+
| `python-release-assets.yml` | Reusable attachment of verified distributions to the published GitHub Release. |
|
|
17
17
|
|
|
18
18
|
CI and release entrypoints are consistently named `ci.yml` and `release.yml`.
|
|
19
19
|
Reusable implementations are consistently prefixed with `python-`. Jobs use
|
|
20
|
-
the verbs `verify`, `build`, `publish-pypi`, and `publish-github`.
|
|
20
|
+
the verbs `verify`, `build`, `publish-pypi`, and `publish-github-assets`.
|
|
21
21
|
|
|
22
22
|
## Release contract
|
|
23
23
|
|
|
24
24
|
1. Merge only after `ci.yml` passes.
|
|
25
25
|
2. Create and push a stable `vMAJOR.MINOR.PATCH` tag.
|
|
26
|
-
3.
|
|
27
|
-
4. The
|
|
26
|
+
3. Publish a GitHub Release targeting that existing tag.
|
|
27
|
+
4. The `release.published` event passes the Release tag to the reusable build.
|
|
28
|
+
5. The build backend derives the version from the tag. Workflows never rewrite
|
|
28
29
|
`pyproject.toml`, override setuptools-scm, or inspect wheels with embedded
|
|
29
30
|
Python programs.
|
|
30
|
-
|
|
31
|
+
6. The reusable build creates one wheel and one source distribution, runs
|
|
31
32
|
Twine, confirms both filenames contain the tag version, and uploads one
|
|
32
33
|
immutable workflow artifact named `python-package-distributions`.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
7. The reusable release-assets job attaches those distributions to the GitHub
|
|
35
|
+
Release.
|
|
36
|
+
8. The repository-local `publish-pypi` job then downloads that artifact and
|
|
37
|
+
uses PyPI Trusted Publishing with only `id-token: write`. Publication is
|
|
38
|
+
idempotent so a rerun can recover a partial release without overwriting PyPI.
|
|
37
39
|
|
|
38
40
|
PyPI currently does not support Trusted Publishing from a reusable workflow.
|
|
39
41
|
Therefore the small `publish-pypi` job must remain directly in each
|
|
@@ -79,8 +81,8 @@ and, when necessary, reusable workflow inputs differ.
|
|
|
79
81
|
name: Release
|
|
80
82
|
|
|
81
83
|
on:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
release:
|
|
85
|
+
types: [published]
|
|
84
86
|
|
|
85
87
|
permissions:
|
|
86
88
|
contents: read
|
|
@@ -89,10 +91,18 @@ jobs:
|
|
|
89
91
|
build:
|
|
90
92
|
uses: 9orky/modwire/.github/workflows/python-release-build.yml@workflows-v1
|
|
91
93
|
with:
|
|
92
|
-
release-tag: ${{ github.
|
|
94
|
+
release-tag: ${{ github.event.release.tag_name }}
|
|
93
95
|
|
|
94
|
-
publish-
|
|
96
|
+
publish-github-assets:
|
|
95
97
|
needs: build
|
|
98
|
+
uses: 9orky/modwire/.github/workflows/python-release-assets.yml@workflows-v1
|
|
99
|
+
with:
|
|
100
|
+
release-tag: ${{ github.event.release.tag_name }}
|
|
101
|
+
permissions:
|
|
102
|
+
contents: write
|
|
103
|
+
|
|
104
|
+
publish-pypi:
|
|
105
|
+
needs: [build, publish-github-assets]
|
|
96
106
|
runs-on: ubuntu-latest
|
|
97
107
|
environment:
|
|
98
108
|
name: pypi
|
|
@@ -105,14 +115,8 @@ jobs:
|
|
|
105
115
|
name: python-package-distributions
|
|
106
116
|
path: dist/
|
|
107
117
|
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
needs: [build, publish-pypi]
|
|
111
|
-
uses: 9orky/modwire/.github/workflows/python-github-release.yml@workflows-v1
|
|
112
|
-
with:
|
|
113
|
-
release-tag: ${{ github.ref_name }}
|
|
114
|
-
permissions:
|
|
115
|
-
contents: write
|
|
118
|
+
with:
|
|
119
|
+
skip-existing: true
|
|
116
120
|
```
|
|
117
121
|
|
|
118
122
|
## Updating the standard
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '4.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (4, 0,
|
|
21
|
+
__version__ = version = '4.0.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (4, 0, 2)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g614b6c4e6'
|
|
@@ -84,7 +84,9 @@ class WorkflowContract(ModwireConfigModel):
|
|
|
84
84
|
release_entrypoint: str
|
|
85
85
|
verify_reusable: str
|
|
86
86
|
release_build_reusable: str
|
|
87
|
-
|
|
87
|
+
release_assets_reusable: str
|
|
88
|
+
release_driver: Literal["github_release"]
|
|
89
|
+
release_event: Literal["published"]
|
|
88
90
|
release_tag_pattern: str
|
|
89
91
|
artifact_name: str
|
|
90
92
|
pypi_environment: str
|
|
@@ -14,8 +14,8 @@ uv.lock
|
|
|
14
14
|
.github/ISSUE_TEMPLATE/feature_request.yml
|
|
15
15
|
.github/scripts/reconcile_ecosystem.py
|
|
16
16
|
.github/workflows/ci.yml
|
|
17
|
-
.github/workflows/python-github-release.yml
|
|
18
17
|
.github/workflows/python-package.yml
|
|
18
|
+
.github/workflows/python-release-assets.yml
|
|
19
19
|
.github/workflows/python-release-build.yml
|
|
20
20
|
.github/workflows/release.yml
|
|
21
21
|
.modwire/boundaries.yaml
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
".github/ISSUE_TEMPLATE/feature_request.yml",
|
|
95
95
|
".github/workflows/release.yml",
|
|
96
96
|
".github/workflows/python-release-build.yml",
|
|
97
|
-
".github/workflows/python-
|
|
97
|
+
".github/workflows/python-release-assets.yml",
|
|
98
98
|
".github/workflows/ci.yml",
|
|
99
99
|
".github/workflows/python-package.yml"
|
|
100
100
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/boundaries/analyzers/analyzer_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/abstract_class_resolver.py
RENAMED
|
File without changes
|
{modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/callable_resolver.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/property_resolver.py
RENAMED
|
File without changes
|
{modwire-4.0.0 → modwire-4.0.2}/src/modwire/architecture/shape/resolvers/signature_resolver.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|