forge-template 0.3.1__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.
- forge_template-0.3.1/.gitattributes +12 -0
- forge_template-0.3.1/.github/ISSUE_TEMPLATE/bug_report.yml +42 -0
- forge_template-0.3.1/.github/ISSUE_TEMPLATE/config.yml +5 -0
- forge_template-0.3.1/.github/ISSUE_TEMPLATE/feature_request.yml +26 -0
- forge_template-0.3.1/.github/dependabot.yml +12 -0
- forge_template-0.3.1/.github/labels.toml +100 -0
- forge_template-0.3.1/.github/pull_request_template.md +16 -0
- forge_template-0.3.1/.github/workflows/release.yml +137 -0
- forge_template-0.3.1/.github/workflows/test-template.yml +211 -0
- forge_template-0.3.1/.gitignore +220 -0
- forge_template-0.3.1/.pre-commit-config.yaml +46 -0
- forge_template-0.3.1/AGENTS.md +1 -0
- forge_template-0.3.1/CLAUDE.md +374 -0
- forge_template-0.3.1/CONTRIBUTING.md +275 -0
- forge_template-0.3.1/LICENSE +21 -0
- forge_template-0.3.1/PKG-INFO +148 -0
- forge_template-0.3.1/README.md +124 -0
- forge_template-0.3.1/SECURITY.md +24 -0
- forge_template-0.3.1/copier.yml +256 -0
- forge_template-0.3.1/docs/README.md +69 -0
- forge_template-0.3.1/docs/adr/0001-record-architecture-decisions.md +37 -0
- forge_template-0.3.1/docs/adr/0002-copier-over-cookiecutter.md +47 -0
- forge_template-0.3.1/docs/adr/0003-two-repo-split.md +40 -0
- forge_template-0.3.1/docs/adr/0004-build-backend-and-versioning.md +57 -0
- forge_template-0.3.1/docs/adr/0005-git-cliff-for-changelogs.md +43 -0
- forge_template-0.3.1/docs/adr/0006-mypy-default-pyright-optional.md +44 -0
- forge_template-0.3.1/docs/adr/0007-mkdocs-pinned-below-2.md +43 -0
- forge_template-0.3.1/docs/adr/0008-remove-make-task-runner.md +48 -0
- forge_template-0.3.1/docs/adr/0009-branch-and-pr-workflow.md +56 -0
- forge_template-0.3.1/docs/adr/0010-forge-architectural-terminology.md +61 -0
- forge_template-0.3.1/docs/adr/0011-forge-foundation-guarantees.md +72 -0
- forge_template-0.3.1/docs/adr/0012-conservative-foundation-scope.md +78 -0
- forge_template-0.3.1/docs/adr/0013-python-support-policy.md +70 -0
- forge_template-0.3.1/docs/adr/0014-editor-neutral-foundation.md +60 -0
- forge_template-0.3.1/docs/adr/0015-owner-local-runtime-configuration.md +78 -0
- forge_template-0.3.1/docs/adr/0016-owner-local-environment-inputs.md +78 -0
- forge_template-0.3.1/docs/adr/0017-owner-local-structured-logging.md +79 -0
- forge_template-0.3.1/docs/adr/0018-owner-local-paths-and-resources.md +87 -0
- forge_template-0.3.1/docs/adr/0019-owner-local-exceptions.md +96 -0
- forge_template-0.3.1/docs/adr/0020-generated-project-secret-safeguards.md +78 -0
- forge_template-0.3.1/docs/adr/0021-defer-sbom-and-release-provenance.md +86 -0
- forge_template-0.3.1/docs/adr/0022-pin-github-actions-by-full-commit-sha.md +69 -0
- forge_template-0.3.1/docs/adr/0023-projectspec-protocol-v1.md +64 -0
- forge_template-0.3.1/docs/adr/0024-component-manifest-protocol-v1.md +73 -0
- forge_template-0.3.1/docs/adr/0025-deterministic-composition-order.md +93 -0
- forge_template-0.3.1/docs/adr/0026-file-conflict-and-override-rules.md +105 -0
- forge_template-0.3.1/docs/adr/0027-template-variable-contract.md +99 -0
- forge_template-0.3.1/docs/adr/0028-composition-contract-fixtures.md +99 -0
- forge_template-0.3.1/docs/adr/0029-stable-template-engine-api.md +90 -0
- forge_template-0.3.1/docs/adr/0030-generated-project-validation.md +66 -0
- forge_template-0.3.1/docs/adr/0031-library-archetype-contract.md +67 -0
- forge_template-0.3.1/docs/adr/0032-render-component-content-paths.md +68 -0
- forge_template-0.3.1/docs/adr/0033-migrate-library-production-catalogue.md +89 -0
- forge_template-0.3.1/docs/adr/0034-select-cli-application-reference-archetype.md +77 -0
- forge_template-0.3.1/docs/adr/0035-implement-cli-application-archetype.md +91 -0
- forge_template-0.3.1/docs/adr/0036-publish-the-engine-to-pypi.md +104 -0
- forge_template-0.3.1/docs/adr/README.md +49 -0
- forge_template-0.3.1/docs/cli-application-archetype.md +241 -0
- forge_template-0.3.1/docs/component-manifests.md +322 -0
- forge_template-0.3.1/docs/composition-fixtures.md +108 -0
- forge_template-0.3.1/docs/composition-order.md +159 -0
- forge_template-0.3.1/docs/configuration-ownership.md +139 -0
- forge_template-0.3.1/docs/editor-integration.md +128 -0
- forge_template-0.3.1/docs/environment-variables.md +183 -0
- forge_template-0.3.1/docs/exception-ownership.md +181 -0
- forge_template-0.3.1/docs/file-conflicts.md +223 -0
- forge_template-0.3.1/docs/foundation-guarantees.md +189 -0
- forge_template-0.3.1/docs/foundation-scope.md +244 -0
- forge_template-0.3.1/docs/generated-project-validation.md +119 -0
- forge_template-0.3.1/docs/github-action-pinning.md +128 -0
- forge_template-0.3.1/docs/library-archetype.md +275 -0
- forge_template-0.3.1/docs/paths-and-resources.md +143 -0
- forge_template-0.3.1/docs/project-spec.md +227 -0
- forge_template-0.3.1/docs/python-support.md +146 -0
- forge_template-0.3.1/docs/roadmap-v1/ARCHITECTURE.md +108 -0
- forge_template-0.3.1/docs/roadmap-v1/README.md +144 -0
- forge_template-0.3.1/docs/roadmap-v1/REPOSITORY-OWNERSHIP.md +133 -0
- forge_template-0.3.1/docs/roadmap-v1/ROADMAP.md +39 -0
- forge_template-0.3.1/docs/roadmap-v1/github-issues/CROSS-REPO-DEPENDENCIES.md +37 -0
- forge_template-0.3.1/docs/roadmap-v1/github-issues/GITHUB-SETUP.md +51 -0
- forge_template-0.3.1/docs/roadmap-v1/github-issues/forge-template/ISSUE-INDEX.md +74 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/00-governance-and-principles/README.md +32 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/01-python-core/README.md +23 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/02-developer-experience/README.md +28 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/03-quality-and-ci/README.md +25 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/04-runtime-and-configuration/README.md +52 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/05-security-and-supply-chain/README.md +60 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/06-extension-and-composition-contract/README.md +47 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/07-forge-cli-integration/README.md +29 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/08-reference-archetype-validation/README.md +51 -0
- forge_template-0.3.1/docs/roadmap-v1/roadmap/09-blueprint-compatibility/README.md +24 -0
- forge_template-0.3.1/docs/secret-handling.md +133 -0
- forge_template-0.3.1/docs/structured-logging.md +179 -0
- forge_template-0.3.1/docs/supply-chain-provenance.md +156 -0
- forge_template-0.3.1/docs/template-engine-api.md +260 -0
- forge_template-0.3.1/docs/template-variables.md +212 -0
- forge_template-0.3.1/docs/terminology.md +286 -0
- forge_template-0.3.1/pyproject.toml +225 -0
- forge_template-0.3.1/scripts/check_wheel.py +135 -0
- forge_template-0.3.1/scripts/labels.py +188 -0
- forge_template-0.3.1/scripts/verify-ci.sh +89 -0
- forge_template-0.3.1/src/forge_template/__init__.py +75 -0
- forge_template-0.3.1/src/forge_template/adr.py +145 -0
- forge_template-0.3.1/src/forge_template/component_manifest.py +691 -0
- forge_template-0.3.1/src/forge_template/components/__init__.py +5 -0
- forge_template-0.3.1/src/forge_template/components/cli/component.toml +48 -0
- forge_template-0.3.1/src/forge_template/components/cli/content/src/{{project.package_name}}/__init__.py.jinja +10 -0
- forge_template-0.3.1/src/forge_template/components/cli/content/src/{{project.package_name}}/__main__.py.jinja +6 -0
- forge_template-0.3.1/src/forge_template/components/cli/content/src/{{project.package_name}}/cli.py.jinja +57 -0
- forge_template-0.3.1/src/forge_template/components/cli/content/src/{{project.package_name}}/py.typed +0 -0
- forge_template-0.3.1/src/forge_template/components/cli/content/tests/__init__.py +0 -0
- forge_template-0.3.1/src/forge_template/components/cli/content/tests/test_cli.py.jinja +48 -0
- forge_template-0.3.1/src/forge_template/components/cli/extensions/archetype-metadata.toml.jinja +1 -0
- forge_template-0.3.1/src/forge_template/components/cli/extensions/build-configuration.toml.jinja +3 -0
- forge_template-0.3.1/src/forge_template/components/cli/extensions/build-system.toml.jinja +2 -0
- forge_template-0.3.1/src/forge_template/components/cli/extensions/classifiers.toml.jinja +1 -0
- forge_template-0.3.1/src/forge_template/components/cli/extensions/entry-points.toml.jinja +2 -0
- forge_template-0.3.1/src/forge_template/components/cli/extensions/readme-project-shape.md.jinja +20 -0
- forge_template-0.3.1/src/forge_template/components/cli/extensions/runtime-dependencies.toml.jinja +1 -0
- forge_template-0.3.1/src/forge_template/components/library/component.toml +39 -0
- forge_template-0.3.1/src/forge_template/components/library/content/src/{{project.package_name}}/__init__.py.jinja +10 -0
- forge_template-0.3.1/src/forge_template/components/library/content/src/{{project.package_name}}/py.typed +0 -0
- forge_template-0.3.1/src/forge_template/components/library/content/tests/__init__.py +0 -0
- forge_template-0.3.1/src/forge_template/components/library/content/tests/test_smoke.py.jinja +7 -0
- forge_template-0.3.1/src/forge_template/components/library/extensions/archetype-metadata.toml.jinja +5 -0
- forge_template-0.3.1/src/forge_template/components/library/extensions/build-configuration.toml.jinja +18 -0
- forge_template-0.3.1/src/forge_template/components/library/extensions/build-system.toml.jinja +10 -0
- forge_template-0.3.1/src/forge_template/components/library/extensions/gitignore-project-shape.jinja +3 -0
- forge_template-0.3.1/src/forge_template/components/library/extensions/readme-project-shape.md.jinja +6 -0
- forge_template-0.3.1/src/forge_template/components/library/options.schema.json +19 -0
- forge_template-0.3.1/src/forge_template/composition.py +172 -0
- forge_template-0.3.1/src/forge_template/engine.py +1173 -0
- forge_template-0.3.1/src/forge_template/file_conflicts.py +331 -0
- forge_template-0.3.1/src/forge_template/foundation/__init__.py +6 -0
- forge_template-0.3.1/src/forge_template/foundation/content/.editorconfig +15 -0
- forge_template-0.3.1/src/forge_template/foundation/content/.gitattributes +10 -0
- forge_template-0.3.1/src/forge_template/foundation/content/.gitignore.jinja +31 -0
- forge_template-0.3.1/src/forge_template/foundation/content/.python-version.jinja +1 -0
- forge_template-0.3.1/src/forge_template/foundation/content/CONTRIBUTING.md.jinja +42 -0
- forge_template-0.3.1/src/forge_template/foundation/content/LICENSE.jinja +40 -0
- forge_template-0.3.1/src/forge_template/foundation/content/README.md.jinja +40 -0
- forge_template-0.3.1/src/forge_template/foundation/content/SECURITY.md.jinja +33 -0
- forge_template-0.3.1/src/forge_template/foundation/content/pyproject.toml.jinja +159 -0
- forge_template-0.3.1/src/forge_template/foundation/foundation.toml +37 -0
- forge_template-0.3.1/src/forge_template/foundation_source.py +187 -0
- forge_template-0.3.1/src/forge_template/github_actions.py +81 -0
- forge_template-0.3.1/src/forge_template/project_spec.py +178 -0
- forge_template-0.3.1/src/forge_template/py.typed +0 -0
- forge_template-0.3.1/src/forge_template/render.py +285 -0
- forge_template-0.3.1/src/forge_template/schema.py +291 -0
- forge_template-0.3.1/src/forge_template/template_variables.py +441 -0
- forge_template-0.3.1/template/.copier-answers.yml.jinja +3 -0
- forge_template-0.3.1/template/.editorconfig +15 -0
- forge_template-0.3.1/template/.env.example.jinja +7 -0
- forge_template-0.3.1/template/.gitattributes +11 -0
- forge_template-0.3.1/template/.github/CODEOWNERS.jinja +7 -0
- forge_template-0.3.1/template/.github/ISSUE_TEMPLATE/bug_report.yml.jinja +38 -0
- forge_template-0.3.1/template/.github/ISSUE_TEMPLATE/config.yml +1 -0
- forge_template-0.3.1/template/.github/ISSUE_TEMPLATE/feature_request.yml.jinja +26 -0
- forge_template-0.3.1/template/.github/pull_request_template.md.jinja +12 -0
- forge_template-0.3.1/template/.github/workflows/ci.yml.jinja +172 -0
- forge_template-0.3.1/template/.github/{% if dependency_updates == 'dependabot' %}dependabot.yml{% endif %}.jinja +39 -0
- forge_template-0.3.1/template/.gitignore.jinja +40 -0
- forge_template-0.3.1/template/.pre-commit-config.yaml.jinja +35 -0
- forge_template-0.3.1/template/.python-version.jinja +1 -0
- forge_template-0.3.1/template/CHANGELOG.md.jinja +16 -0
- forge_template-0.3.1/template/CONTRIBUTING.md.jinja +97 -0
- forge_template-0.3.1/template/LICENSE.jinja +35 -0
- forge_template-0.3.1/template/README.md.jinja +142 -0
- forge_template-0.3.1/template/SECURITY.md.jinja +36 -0
- forge_template-0.3.1/template/pyproject.toml.jinja +293 -0
- forge_template-0.3.1/template/src/{{package_name}}/__init__.py.jinja +10 -0
- forge_template-0.3.1/template/src/{{package_name}}/py.typed +0 -0
- forge_template-0.3.1/template/tests/__init__.py +0 -0
- forge_template-0.3.1/template/tests/test_smoke.py.jinja +7 -0
- forge_template-0.3.1/template/{% if dependency_updates == 'renovate' %}renovate.json{% endif %}.jinja +52 -0
- forge_template-0.3.1/template/{% if use_docs %}docs{% endif %}/adr/0001-record-architecture-decisions.md.jinja +26 -0
- forge_template-0.3.1/template/{% if use_docs %}docs{% endif %}/adr/README.md.jinja +8 -0
- forge_template-0.3.1/template/{% if use_docs %}docs{% endif %}/index.md.jinja +11 -0
- forge_template-0.3.1/template/{% if use_docs %}docs{% endif %}/reference.md.jinja +3 -0
- forge_template-0.3.1/template/{% if use_docs %}mkdocs.yml{% endif %}.jinja +49 -0
- forge_template-0.3.1/tests/__init__.py +0 -0
- forge_template-0.3.1/tests/composition_contract.py +153 -0
- forge_template-0.3.1/tests/conftest.py +164 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/changelog/component.toml +13 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/changelog/content/a-top.txt +1 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/changelog/content/nested/a-deep.txt +1 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/changelog/content/z-top.txt +1 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/coverage/component.toml +18 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/coverage/content/.coveragerc +2 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/coverage/extensions/ci-step.yml.jinja +2 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/documentation/component.toml +13 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/documentation/content/mkdocs.yml.jinja +1 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/github/component.toml +18 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/github/content/ci.yml.jinja +5 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/github/options.schema.json +10 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/library/component.toml +14 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/library/content/pyproject.toml.jinja +7 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/library/options.schema.json +16 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/library-v2/component.toml +21 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/library-v2/content/src/{{project.package_name}}/py.typed +0 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/library-v2/extensions/pyproject-build-system.toml.jinja +2 -0
- forge_template-0.3.1/tests/fixtures/component_manifests/library-v2/options.schema.json +11 -0
- forge_template-0.3.1/tests/fixtures/foundation/content/pyproject.toml.jinja +6 -0
- forge_template-0.3.1/tests/fixtures/foundation/foundation.toml +6 -0
- forge_template-0.3.1/tests/fixtures/golden/extension.json +43 -0
- forge_template-0.3.1/tests/fixtures/golden/full.json +81 -0
- forge_template-0.3.1/tests/fixtures/golden/minimal.json +18 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/colliding-first/component.toml +13 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/colliding-first/content/shared.txt +1 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/colliding-second/component.toml +13 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/colliding-second/content/shared.txt +1 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/conflicting-first/component.toml +13 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/conflicting-first/content/placeholder.txt +1 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/conflicting-second/component.toml +13 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/conflicting-second/content/placeholder.txt +1 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/cycle-a/component.toml +13 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/cycle-a/content/placeholder.txt +1 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/cycle-b/component.toml +13 -0
- forge_template-0.3.1/tests/fixtures/invalid_components/cycle-b/content/placeholder.txt +1 -0
- forge_template-0.3.1/tests/test_adr.py +121 -0
- forge_template-0.3.1/tests/test_cli_archetype.py +166 -0
- forge_template-0.3.1/tests/test_cli_build.py +209 -0
- forge_template-0.3.1/tests/test_combos.py +113 -0
- forge_template-0.3.1/tests/test_component_manifest.py +733 -0
- forge_template-0.3.1/tests/test_composition.py +223 -0
- forge_template-0.3.1/tests/test_composition_contract.py +159 -0
- forge_template-0.3.1/tests/test_engine.py +695 -0
- forge_template-0.3.1/tests/test_file_conflicts.py +428 -0
- forge_template-0.3.1/tests/test_foundation_source.py +159 -0
- forge_template-0.3.1/tests/test_generated_project_validation.py +304 -0
- forge_template-0.3.1/tests/test_github_actions.py +69 -0
- forge_template-0.3.1/tests/test_library_archetype.py +247 -0
- forge_template-0.3.1/tests/test_library_build.py +172 -0
- forge_template-0.3.1/tests/test_project_spec.py +244 -0
- forge_template-0.3.1/tests/test_render.py +364 -0
- forge_template-0.3.1/tests/test_schema.py +206 -0
- forge_template-0.3.1/tests/test_template_variables.py +494 -0
- forge_template-0.3.1/tests/test_update.py +279 -0
- forge_template-0.3.1/uv.lock +1152 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Normalise to LF in the repository. Without this, Windows checkouts get CRLF
|
|
2
|
+
# and a fresh clone's checked-out template/*.jinja files would render CRLF
|
|
3
|
+
# into every scaffolded project.
|
|
4
|
+
* text=auto eol=lf
|
|
5
|
+
|
|
6
|
+
*.png binary
|
|
7
|
+
*.jpg binary
|
|
8
|
+
*.gif binary
|
|
9
|
+
*.ico binary
|
|
10
|
+
*.pdf binary
|
|
11
|
+
*.zip binary
|
|
12
|
+
*.whl binary
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report something that isn't working as expected
|
|
3
|
+
labels: ["type:bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what-happened
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened?
|
|
9
|
+
description: What did you expect instead?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: reproduce
|
|
15
|
+
attributes:
|
|
16
|
+
label: Steps to reproduce
|
|
17
|
+
description: >
|
|
18
|
+
Include the answers (or which combo, if this is about
|
|
19
|
+
`tests/test_combos.py`) that reproduce it.
|
|
20
|
+
placeholder: |
|
|
21
|
+
1.
|
|
22
|
+
2.
|
|
23
|
+
3.
|
|
24
|
+
validations:
|
|
25
|
+
required: true
|
|
26
|
+
|
|
27
|
+
- type: input
|
|
28
|
+
id: template-version
|
|
29
|
+
attributes:
|
|
30
|
+
label: Template version
|
|
31
|
+
description: The tag `copier` scaffolded from, or `main` at a commit SHA
|
|
32
|
+
placeholder: "e.g. v0.1.1"
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
35
|
+
|
|
36
|
+
- type: input
|
|
37
|
+
id: copier-version
|
|
38
|
+
attributes:
|
|
39
|
+
label: Copier version
|
|
40
|
+
placeholder: "e.g. 9.4.1 (uv run copier --version)"
|
|
41
|
+
validations:
|
|
42
|
+
required: false
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an idea or enhancement
|
|
3
|
+
labels: ["type:feature"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: What problem does this solve?
|
|
9
|
+
description: What are you trying to do that isn't possible or easy today?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: solution
|
|
15
|
+
attributes:
|
|
16
|
+
label: Proposed solution
|
|
17
|
+
description: What would you like to happen?
|
|
18
|
+
validations:
|
|
19
|
+
required: false
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: alternatives
|
|
23
|
+
attributes:
|
|
24
|
+
label: Alternatives considered
|
|
25
|
+
validations:
|
|
26
|
+
required: false
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Shared GitHub label taxonomy for create-forge and forge-template.
|
|
2
|
+
#
|
|
3
|
+
# This is the source of truth -- applied with `uv run poe labels:sync`
|
|
4
|
+
# (scripts/labels.py), which also accepts `--repo OWNER/NAME` so the same
|
|
5
|
+
# manifest drives forge-template. See CONTRIBUTING.md's Labels section.
|
|
6
|
+
#
|
|
7
|
+
# Group labels are namespaced "<group>:<label>" (e.g. "area:cli"). Entries
|
|
8
|
+
# under [unprefixed] keep GitHub's stock names -- "good first issue" and
|
|
9
|
+
# "help wanted" are special-cased by GitHub's own issue-discovery UI, so
|
|
10
|
+
# renaming them would cost real functionality for no benefit.
|
|
11
|
+
#
|
|
12
|
+
# Most `type:` values mirror the Conventional Commits prefixes both repos
|
|
13
|
+
# already enforce via their commit-msg hook. `type:epic` and `type:decision`
|
|
14
|
+
# classify roadmap planning work that does not map to a single commit.
|
|
15
|
+
|
|
16
|
+
[groups.area]
|
|
17
|
+
description = "Which part of the system an issue touches."
|
|
18
|
+
family = "blue"
|
|
19
|
+
|
|
20
|
+
[groups.area.labels]
|
|
21
|
+
cli = { color = "0a3069", description = "The Typer commands and their prompts" }
|
|
22
|
+
registry = { color = "0550ae", description = "templates.toml and the models that validate it" }
|
|
23
|
+
copier = { color = "0969da", description = "The Copier integration and copier.yml surface" }
|
|
24
|
+
template = { color = "218bff", description = "forge-template's scaffolded files and tasks" }
|
|
25
|
+
ci = { color = "54aeff", description = "GitHub Actions workflows and the checks they run" }
|
|
26
|
+
tests = { color = "80ccff", description = "The test suites and fixtures themselves" }
|
|
27
|
+
docs = { color = "b6e3ff", description = "README, CONTRIBUTING, ADRs, and other documentation" }
|
|
28
|
+
packaging = { color = "cae8ff", description = "pyproject.toml, dependencies, and the built wheel" }
|
|
29
|
+
release = { color = "ddf4ff", description = "Tagging, changelog generation, and the release workflow" }
|
|
30
|
+
|
|
31
|
+
[groups.type]
|
|
32
|
+
description = "What kind of work an issue or PR represents."
|
|
33
|
+
family = "purple"
|
|
34
|
+
|
|
35
|
+
[groups.type.labels]
|
|
36
|
+
epic = { color = "2f0f5f", description = "A roadmap stage grouping related child issues" }
|
|
37
|
+
decision = { color = "5526a5", description = "An architectural or product decision is required" }
|
|
38
|
+
bug = { color = "3e1f79", description = "Something isn't working" }
|
|
39
|
+
feature = { color = "6639ba", description = "New capability or request" }
|
|
40
|
+
refactor = { color = "8250df", description = "Structural change with no behaviour change" }
|
|
41
|
+
perf = { color = "a475f9", description = "Performance improvement" }
|
|
42
|
+
docs = { color = "c297ff", description = "Documentation-only change" }
|
|
43
|
+
test = { color = "d8b9ff", description = "Test-only change" }
|
|
44
|
+
chore = { color = "ecd8ff", description = "Maintenance with no user-facing effect" }
|
|
45
|
+
|
|
46
|
+
[groups.priority]
|
|
47
|
+
description = "How urgently an issue should be picked up."
|
|
48
|
+
family = "red"
|
|
49
|
+
|
|
50
|
+
[groups.priority.labels]
|
|
51
|
+
critical = { color = "82071e", description = "Drop everything" }
|
|
52
|
+
high = { color = "cf222e", description = "Should be next" }
|
|
53
|
+
medium = { color = "ff8182", description = "Normal priority" }
|
|
54
|
+
low = { color = "ffcecb", description = "Nice to have" }
|
|
55
|
+
|
|
56
|
+
[groups.size]
|
|
57
|
+
description = "Rough estimate of how much work an issue is."
|
|
58
|
+
family = "green"
|
|
59
|
+
|
|
60
|
+
[groups.size.labels]
|
|
61
|
+
xs = { color = "dafbe1", description = "Trivial -- minutes" }
|
|
62
|
+
s = { color = "aceebb", description = "Small -- a sitting" }
|
|
63
|
+
m = { color = "6fdd8b", description = "Medium -- a day or two" }
|
|
64
|
+
l = { color = "2da44e", description = "Large -- the better part of a week" }
|
|
65
|
+
xl = { color = "116329", description = "Extra large -- consider breaking it up" }
|
|
66
|
+
|
|
67
|
+
[groups.status]
|
|
68
|
+
description = "Where an issue stands, independent of priority or size."
|
|
69
|
+
family = "slate"
|
|
70
|
+
|
|
71
|
+
[groups.status.labels]
|
|
72
|
+
blocked = { color = "24292f", description = "Waiting on something outside this issue" }
|
|
73
|
+
needs-decision = { color = "57606a", description = "Blocked on a choice only a maintainer can make" }
|
|
74
|
+
needs-info = { color = "6e7781", description = "Waiting on more information before work can start" }
|
|
75
|
+
in-progress = { color = "8c959f", description = "Actively being worked on" }
|
|
76
|
+
deferred = { color = "afb8c1", description = "Confirmed out of scope for now, not forgotten" }
|
|
77
|
+
|
|
78
|
+
[groups.roadmap]
|
|
79
|
+
description = "Which Forge Foundation roadmap stage owns the work."
|
|
80
|
+
family = "orange"
|
|
81
|
+
|
|
82
|
+
[groups.roadmap.labels]
|
|
83
|
+
"00" = { color = "fff8c5", description = "Forge roadmap Stage 00 — Governance and Principles" }
|
|
84
|
+
"01" = { color = "fae17d", description = "Forge roadmap Stage 01 — Python Core" }
|
|
85
|
+
"02" = { color = "f7c843", description = "Forge roadmap Stage 02 — Developer Experience" }
|
|
86
|
+
"03" = { color = "f2b134", description = "Forge roadmap Stage 03 — Quality and CI" }
|
|
87
|
+
"04" = { color = "ed9b2d", description = "Forge roadmap Stage 04 — Runtime and Configuration" }
|
|
88
|
+
"05" = { color = "e78626", description = "Forge roadmap Stage 05 — Security and Supply Chain" }
|
|
89
|
+
"06" = { color = "df7020", description = "Forge roadmap Stage 06 — Extension and Composition" }
|
|
90
|
+
"07" = { color = "d45d1a", description = "Forge roadmap Stage 07 — Forge CLI Integration" }
|
|
91
|
+
"08" = { color = "bd4914", description = "Forge roadmap Stage 08 — Reference Archetype Validation" }
|
|
92
|
+
"09" = { color = "9f3610", description = "Forge roadmap Stage 09 — Blueprint Compatibility" }
|
|
93
|
+
|
|
94
|
+
# Repository-wide metadata that is clearer without a namespace. GitHub
|
|
95
|
+
# special-cases `good first issue` and `help wanted` in its discovery UI.
|
|
96
|
+
[unprefixed]
|
|
97
|
+
"good first issue" = { color = "7057ff", description = "Good for newcomers" }
|
|
98
|
+
"help wanted" = { color = "008672", description = "Extra attention is needed" }
|
|
99
|
+
"cross-repo" = { color = "1f6feb", description = "Coordinates work across create-forge and forge-template" }
|
|
100
|
+
"breaking-change" = { color = "b60205", description = "May require an incompatible migration or coordinated release" }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What does this change do, and why? -->
|
|
4
|
+
|
|
5
|
+
## Checklist
|
|
6
|
+
|
|
7
|
+
- [ ] `uv run poe check` passes locally
|
|
8
|
+
- [ ] `uv run poe combos` passes, if this touches `template/` or `copier.yml`
|
|
9
|
+
- [ ] `uv run poe update` passes, if this edits a file that already exists in
|
|
10
|
+
released projects
|
|
11
|
+
- [ ] An ADR is added under `docs/adr/`, if this makes a real architectural call
|
|
12
|
+
- [ ] A `_migrations` block is added, if any `template/` path was renamed or
|
|
13
|
+
deleted (see CLAUDE.md's invariant 3)
|
|
14
|
+
- [ ] Any conditional file I touched still ends in a real trailing newline
|
|
15
|
+
(invariant 1)
|
|
16
|
+
- [ ] Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
name: Release template
|
|
2
|
+
|
|
3
|
+
# Tags are how Copier resolves "latest version" and how engine clients resolve
|
|
4
|
+
# package compatibility. pyproject.toml is the one version source: bump it in
|
|
5
|
+
# a reviewed PR, then run this workflow to create the matching tag and release.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
inputs:
|
|
10
|
+
dry_run:
|
|
11
|
+
description: Print the tag without creating it
|
|
12
|
+
type: boolean
|
|
13
|
+
default: false
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
UV_VERSION: "0.12.0"
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
release:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0
|
|
28
|
+
|
|
29
|
+
- name: Read and validate version
|
|
30
|
+
id: version
|
|
31
|
+
shell: bash
|
|
32
|
+
run: |
|
|
33
|
+
version=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
|
|
34
|
+
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
35
|
+
echo "::error::project.version must be a final SemVer release, found: $version"
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
next="v$version"
|
|
40
|
+
latest=$(git tag -l 'v*' --sort=-v:refname | head -1)
|
|
41
|
+
if git rev-parse --verify --quiet "refs/tags/$next" >/dev/null; then
|
|
42
|
+
echo "::error::tag already exists: $next"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
if [ -n "$latest" ] && [ "$(printf '%s\n%s\n' "$latest" "$next" | sort -V | tail -1)" != "$next" ]; then
|
|
46
|
+
echo "::error::project version $next is not newer than $latest"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
echo "latest=${latest:-none}" >> "$GITHUB_OUTPUT"
|
|
51
|
+
echo "next=$next" >> "$GITHUB_OUTPUT"
|
|
52
|
+
echo "### ${latest:-none} → $next" >> "$GITHUB_STEP_SUMMARY"
|
|
53
|
+
|
|
54
|
+
- name: Changes since last release
|
|
55
|
+
id: notes
|
|
56
|
+
run: |
|
|
57
|
+
latest="${{ steps.version.outputs.latest }}"
|
|
58
|
+
{
|
|
59
|
+
echo "notes<<EOF"
|
|
60
|
+
if [ "$latest" = "none" ]; then
|
|
61
|
+
echo "Initial release."
|
|
62
|
+
else
|
|
63
|
+
git log "${latest}..HEAD" --pretty='- %s' --no-merges
|
|
64
|
+
fi
|
|
65
|
+
echo "EOF"
|
|
66
|
+
} >> "$GITHUB_OUTPUT"
|
|
67
|
+
|
|
68
|
+
- name: Warn on breaking template changes
|
|
69
|
+
run: |
|
|
70
|
+
latest="${{ steps.version.outputs.latest }}"
|
|
71
|
+
[ "$latest" = "none" ] && exit 0
|
|
72
|
+
moved=$(git diff --name-status "$latest..HEAD" -- template/ \
|
|
73
|
+
| grep -E '^(R|D)' || true)
|
|
74
|
+
if [ -n "$moved" ] && ! grep -q '_migrations' copier.yml; then
|
|
75
|
+
echo "::warning::Template files moved or deleted with no _migrations block:"
|
|
76
|
+
echo "$moved"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
- name: Create tag
|
|
80
|
+
if: ${{ !inputs.dry_run }}
|
|
81
|
+
run: |
|
|
82
|
+
git config user.name "github-actions[bot]"
|
|
83
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
84
|
+
git tag -a "${{ steps.version.outputs.next }}" \
|
|
85
|
+
-m "Release ${{ steps.version.outputs.next }}"
|
|
86
|
+
git push origin "${{ steps.version.outputs.next }}"
|
|
87
|
+
|
|
88
|
+
- name: GitHub release
|
|
89
|
+
if: ${{ !inputs.dry_run }}
|
|
90
|
+
env:
|
|
91
|
+
GH_TOKEN: ${{ github.token }}
|
|
92
|
+
run: |
|
|
93
|
+
gh release create "${{ steps.version.outputs.next }}" \
|
|
94
|
+
--title "${{ steps.version.outputs.next }}" \
|
|
95
|
+
--notes "${{ steps.notes.outputs.notes }}
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
Existing projects can pull this in with \`uvx copier update --trust\`."
|
|
99
|
+
|
|
100
|
+
# ---------------------------------------------------------------------------
|
|
101
|
+
# Publishes the public engine package built from the same commit the tag
|
|
102
|
+
# above points to. Uses PyPI Trusted Publishing (OIDC) -- no stored token.
|
|
103
|
+
# ADR 0036: only the public engine facade and content trees ship in this
|
|
104
|
+
# wheel; scripts/check_wheel.py (already required by CI's `wheel` job)
|
|
105
|
+
# re-verifies that here as a release-time safety net.
|
|
106
|
+
# ---------------------------------------------------------------------------
|
|
107
|
+
publish:
|
|
108
|
+
name: Publish to PyPI
|
|
109
|
+
runs-on: ubuntu-latest
|
|
110
|
+
needs: release
|
|
111
|
+
if: ${{ !inputs.dry_run }}
|
|
112
|
+
permissions:
|
|
113
|
+
id-token: write
|
|
114
|
+
environment:
|
|
115
|
+
name: pypi
|
|
116
|
+
url: https://pypi.org/p/forge-template
|
|
117
|
+
steps:
|
|
118
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
119
|
+
|
|
120
|
+
- name: Install uv
|
|
121
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
122
|
+
with:
|
|
123
|
+
version: ${{ env.UV_VERSION }}
|
|
124
|
+
enable-cache: true
|
|
125
|
+
python-version: "3.13"
|
|
126
|
+
|
|
127
|
+
- name: Install dependencies
|
|
128
|
+
run: uv sync --all-groups
|
|
129
|
+
|
|
130
|
+
- name: Check wheel contents
|
|
131
|
+
run: uv run poe check:wheel
|
|
132
|
+
|
|
133
|
+
- name: Build
|
|
134
|
+
run: uv build
|
|
135
|
+
|
|
136
|
+
- name: Publish
|
|
137
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
name: Test template
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
# Catches upstream breakage (new ruff rules, uv releases) before users do.
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: "0 6 * * 1"
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
env:
|
|
20
|
+
UV_VERSION: "0.12.0"
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
# ---------------------------------------------------------------------------
|
|
24
|
+
# Cheap checks on the template repo itself.
|
|
25
|
+
# ---------------------------------------------------------------------------
|
|
26
|
+
lint:
|
|
27
|
+
name: Lint template
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
31
|
+
|
|
32
|
+
- name: Install uv
|
|
33
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
34
|
+
with:
|
|
35
|
+
version: ${{ env.UV_VERSION }}
|
|
36
|
+
enable-cache: true
|
|
37
|
+
python-version: "3.13"
|
|
38
|
+
|
|
39
|
+
- name: Install dependencies
|
|
40
|
+
run: uv sync --all-groups
|
|
41
|
+
|
|
42
|
+
# Same gate as `uv run pre-commit run --all-files` locally: ruff,
|
|
43
|
+
# shellcheck, and the whitespace/EOF hooks that guard invariant 1.
|
|
44
|
+
- name: Pre-commit
|
|
45
|
+
run: uv run pre-commit run --all-files --show-diff-on-failure
|
|
46
|
+
|
|
47
|
+
# copier.yml layout, computed-value defaults, the versioning /
|
|
48
|
+
# versioning_resolved indirection, question <-> template/** usage, and
|
|
49
|
+
# the docs/adr/ set -- see src/forge_template/{schema,adr}.py.
|
|
50
|
+
- name: Schema and unit tests
|
|
51
|
+
run: uv run poe check
|
|
52
|
+
|
|
53
|
+
# ---------------------------------------------------------------------------
|
|
54
|
+
# Scaffold every combination, then run the checks the generated CI runs.
|
|
55
|
+
# tests/test_combos.py is the single definition of every assertion here --
|
|
56
|
+
# see tests/conftest.py's --from-git option and _git_identity fixture (no
|
|
57
|
+
# manual `git config` step needed; the fixture supplies one when the runner
|
|
58
|
+
# has none, closing the bug class documented in CLAUDE.md's "Validation").
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
scaffold:
|
|
61
|
+
name: ${{ matrix.name }}
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
needs: lint
|
|
64
|
+
strategy:
|
|
65
|
+
fail-fast: false
|
|
66
|
+
matrix:
|
|
67
|
+
include:
|
|
68
|
+
- name: uv_build + static
|
|
69
|
+
combo: c1-uvbuild-static
|
|
70
|
+
- name: hatchling + static
|
|
71
|
+
combo: c2-hatch-static
|
|
72
|
+
- name: hatchling + vcs
|
|
73
|
+
combo: c3-hatch-vcs
|
|
74
|
+
- name: kitchen sink (all conditionals on)
|
|
75
|
+
combo: c4-kitchen-sink
|
|
76
|
+
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
79
|
+
with:
|
|
80
|
+
# Copier needs tag history to record _commit in the answers file.
|
|
81
|
+
fetch-depth: 0
|
|
82
|
+
|
|
83
|
+
- name: Install uv
|
|
84
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
85
|
+
with:
|
|
86
|
+
version: ${{ env.UV_VERSION }}
|
|
87
|
+
enable-cache: true
|
|
88
|
+
python-version: "3.13"
|
|
89
|
+
|
|
90
|
+
- name: Install dependencies
|
|
91
|
+
run: uv sync --all-groups
|
|
92
|
+
|
|
93
|
+
- name: Scaffold and verify -- ${{ matrix.combo }}
|
|
94
|
+
run: uv run pytest -m combos -k ${{ matrix.combo }} --from-git -v
|
|
95
|
+
|
|
96
|
+
# ---------------------------------------------------------------------------
|
|
97
|
+
# Windows smoke test — path separators, line endings, missing Unix tools.
|
|
98
|
+
# ---------------------------------------------------------------------------
|
|
99
|
+
windows:
|
|
100
|
+
name: Windows smoke
|
|
101
|
+
runs-on: windows-latest
|
|
102
|
+
needs: lint
|
|
103
|
+
steps:
|
|
104
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
105
|
+
with:
|
|
106
|
+
fetch-depth: 0
|
|
107
|
+
|
|
108
|
+
- name: Install uv
|
|
109
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
110
|
+
with:
|
|
111
|
+
version: ${{ env.UV_VERSION }}
|
|
112
|
+
enable-cache: true
|
|
113
|
+
python-version: "3.13"
|
|
114
|
+
|
|
115
|
+
- name: Install dependencies
|
|
116
|
+
run: uv sync --all-groups
|
|
117
|
+
|
|
118
|
+
- name: Scaffold and verify -- c1-uvbuild-static
|
|
119
|
+
run: uv run pytest -m combos -k c1-uvbuild-static --from-git -v
|
|
120
|
+
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
# Real uv build/install/import proof for the production Library and CLI
|
|
123
|
+
# archetypes -- tests/test_library_build.py, tests/test_cli_build.py.
|
|
124
|
+
# ---------------------------------------------------------------------------
|
|
125
|
+
archetype:
|
|
126
|
+
name: Archetype builds
|
|
127
|
+
runs-on: ubuntu-latest
|
|
128
|
+
needs: lint
|
|
129
|
+
steps:
|
|
130
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
131
|
+
|
|
132
|
+
- name: Install uv
|
|
133
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
134
|
+
with:
|
|
135
|
+
version: ${{ env.UV_VERSION }}
|
|
136
|
+
enable-cache: true
|
|
137
|
+
python-version: "3.13"
|
|
138
|
+
|
|
139
|
+
- name: Install dependencies
|
|
140
|
+
run: uv sync --all-groups
|
|
141
|
+
|
|
142
|
+
- name: Build every production archetype
|
|
143
|
+
run: uv run poe archetype
|
|
144
|
+
|
|
145
|
+
# ---------------------------------------------------------------------------
|
|
146
|
+
# copier update from the last release to HEAD must not explode, and local
|
|
147
|
+
# edits survive a merge. tests/test_update.py's two scenarios each skip
|
|
148
|
+
# themselves (not fail) when no tag exists yet -- the very first run.
|
|
149
|
+
# ---------------------------------------------------------------------------
|
|
150
|
+
update-compat:
|
|
151
|
+
name: copier update compatibility
|
|
152
|
+
runs-on: ubuntu-latest
|
|
153
|
+
needs: lint
|
|
154
|
+
steps:
|
|
155
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
156
|
+
with:
|
|
157
|
+
fetch-depth: 0
|
|
158
|
+
|
|
159
|
+
- name: Install uv
|
|
160
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
161
|
+
with:
|
|
162
|
+
version: ${{ env.UV_VERSION }}
|
|
163
|
+
enable-cache: true
|
|
164
|
+
python-version: "3.13"
|
|
165
|
+
|
|
166
|
+
- name: Install dependencies
|
|
167
|
+
run: uv sync --all-groups
|
|
168
|
+
|
|
169
|
+
- name: copier update scenarios
|
|
170
|
+
run: uv run pytest -m update -v
|
|
171
|
+
|
|
172
|
+
# ---------------------------------------------------------------------------
|
|
173
|
+
# Verifies the built wheel ships the public engine facade and content
|
|
174
|
+
# trees but excludes this repo's own CI tooling (adr.py, render.py,
|
|
175
|
+
# schema.py, github_actions.py) -- see ADR 0036 and scripts/check_wheel.py.
|
|
176
|
+
# ---------------------------------------------------------------------------
|
|
177
|
+
wheel:
|
|
178
|
+
name: Wheel contents
|
|
179
|
+
runs-on: ubuntu-latest
|
|
180
|
+
needs: lint
|
|
181
|
+
steps:
|
|
182
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
183
|
+
|
|
184
|
+
- name: Install uv
|
|
185
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
186
|
+
with:
|
|
187
|
+
version: ${{ env.UV_VERSION }}
|
|
188
|
+
enable-cache: true
|
|
189
|
+
python-version: "3.13"
|
|
190
|
+
|
|
191
|
+
- name: Install dependencies
|
|
192
|
+
run: uv sync --all-groups
|
|
193
|
+
|
|
194
|
+
- name: Check wheel
|
|
195
|
+
run: uv run poe check:wheel
|
|
196
|
+
|
|
197
|
+
# ---------------------------------------------------------------------------
|
|
198
|
+
# Single required status check for branch protection.
|
|
199
|
+
# ---------------------------------------------------------------------------
|
|
200
|
+
all-green:
|
|
201
|
+
name: All checks passed
|
|
202
|
+
runs-on: ubuntu-latest
|
|
203
|
+
needs: [lint, scaffold, windows, archetype, update-compat, wheel]
|
|
204
|
+
if: always()
|
|
205
|
+
steps:
|
|
206
|
+
- name: Verify
|
|
207
|
+
run: |
|
|
208
|
+
if echo "${{ join(needs.*.result, ',') }}" | grep -qE 'failure|cancelled'; then
|
|
209
|
+
echo "::error::One or more jobs failed"; exit 1
|
|
210
|
+
fi
|
|
211
|
+
echo "All jobs passed."
|