@mannyc1/ts-release 0.0.6 → 0.2.2
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.
- package/ARCHITECTURE.md +124 -87
- package/CHANGELOG.md +115 -0
- package/LICENSE +21 -0
- package/README.md +272 -540
- package/SPEC.md +206 -305
- package/apps/release-ts/README.md +32 -0
- package/apps/release-ts/src/cli/command.ts +164 -0
- package/apps/release-ts/src/cli/commands.ts +351 -0
- package/apps/release-ts/src/cli/main.ts +43 -0
- package/apps/release-ts/src/cli/node-main.ts +49 -0
- package/apps/ts-release-agents/LICENSE +21 -0
- package/apps/ts-release-agents/README.md +21 -0
- package/apps/ts-release-agents/evals/cases.json +11 -0
- package/apps/ts-release-agents/manifests/claude.json +5 -0
- package/apps/ts-release-agents/manifests/codex.json +5 -0
- package/apps/ts-release-agents/package.json +11 -0
- package/apps/ts-release-agents/skills/release/SKILL.md +48 -0
- package/apps/ts-release-agents/skills/release/references/configuration.md +18 -0
- package/apps/ts-release-agents/skills/release/references/recovery.md +10 -0
- package/apps/ts-release-agents/skills/release/references/staged-workflow.md +12 -0
- package/apps/ts-release-agents/skills/release/references/target-selection.md +13 -0
- package/apps/ts-release-agents/skills/release/references/verification.md +14 -0
- package/apps/ts-release-agents/src/build.ts +105 -0
- package/apps/ts-release-agents/src/check.ts +117 -0
- package/apps/ts-release-agents/src/install.ts +121 -0
- package/apps/ts-release-agents/test/contract.test.ts +56 -0
- package/apps/ts-release-agents/tsconfig.json +5 -0
- package/dist/api/api.d.ts +15 -0
- package/dist/api/api.d.ts.map +1 -0
- package/dist/api/api.js +244 -0
- package/dist/api/api.js.map +1 -0
- package/dist/api/errors.d.ts +39 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +32 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/input.d.ts +10 -0
- package/dist/api/input.d.ts.map +1 -0
- package/dist/api/input.js +73 -0
- package/dist/api/input.js.map +1 -0
- package/dist/api/runtime.d.ts +18 -0
- package/dist/api/runtime.d.ts.map +1 -0
- package/dist/api/runtime.js +7 -0
- package/dist/api/runtime.js.map +1 -0
- package/dist/api/types.d.ts +76 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +17 -0
- package/dist/api/types.js.map +1 -0
- package/dist/bin/ts-release.js +39239 -0
- package/dist/capabilities/bun-targets.d.ts +3 -0
- package/dist/capabilities/bun-targets.d.ts.map +1 -0
- package/dist/capabilities/bun-targets.js +3 -0
- package/dist/capabilities/bun-targets.js.map +1 -0
- package/dist/capabilities/field-ownership.d.ts +17 -0
- package/dist/capabilities/field-ownership.d.ts.map +1 -0
- package/dist/capabilities/field-ownership.js +40 -0
- package/dist/capabilities/field-ownership.js.map +1 -0
- package/dist/capabilities/module.d.ts +91 -0
- package/dist/capabilities/module.d.ts.map +1 -0
- package/dist/capabilities/module.js +2 -0
- package/dist/capabilities/module.js.map +1 -0
- package/dist/capabilities/registry.d.ts +829 -0
- package/dist/capabilities/registry.d.ts.map +1 -0
- package/dist/capabilities/registry.js +291 -0
- package/dist/capabilities/registry.js.map +1 -0
- package/dist/config/config.d.ts +6 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +42 -0
- package/dist/config/config.js.map +1 -0
- package/dist/correction/coordinator.d.ts +248 -0
- package/dist/correction/coordinator.d.ts.map +1 -0
- package/dist/correction/coordinator.js +274 -0
- package/dist/correction/coordinator.js.map +1 -0
- package/dist/correction/index.d.ts +3 -0
- package/dist/correction/index.d.ts.map +1 -0
- package/dist/correction/index.js +3 -0
- package/dist/correction/index.js.map +1 -0
- package/dist/correction/intent.d.ts +111 -0
- package/dist/correction/intent.d.ts.map +1 -0
- package/dist/correction/intent.js +146 -0
- package/dist/correction/intent.js.map +1 -0
- package/dist/drivers/archive.d.ts +8 -0
- package/dist/drivers/archive.d.ts.map +1 -0
- package/dist/drivers/archive.js +101 -0
- package/dist/drivers/archive.js.map +1 -0
- package/dist/drivers/contain.d.ts +6 -0
- package/dist/drivers/contain.d.ts.map +1 -0
- package/dist/drivers/contain.js +17 -0
- package/dist/drivers/contain.js.map +1 -0
- package/dist/drivers/environment.d.ts +4 -0
- package/dist/drivers/environment.d.ts.map +1 -0
- package/dist/drivers/environment.js +18 -0
- package/dist/drivers/environment.js.map +1 -0
- package/dist/drivers/errors.d.ts +9 -0
- package/dist/drivers/errors.d.ts.map +1 -0
- package/dist/drivers/errors.js +6 -0
- package/dist/drivers/errors.js.map +1 -0
- package/dist/drivers/glob.d.ts +2 -0
- package/dist/drivers/glob.d.ts.map +1 -0
- package/dist/drivers/glob.js +162 -0
- package/dist/drivers/glob.js.map +1 -0
- package/dist/drivers/process.d.ts +48 -0
- package/dist/drivers/process.d.ts.map +1 -0
- package/dist/drivers/process.js +257 -0
- package/dist/drivers/process.js.map +1 -0
- package/dist/drivers/redact.d.ts +4 -0
- package/dist/drivers/redact.d.ts.map +1 -0
- package/dist/drivers/redact.js +24 -0
- package/dist/drivers/redact.js.map +1 -0
- package/dist/drivers/seccomp-helper-source.d.ts +7 -0
- package/dist/drivers/seccomp-helper-source.d.ts.map +1 -0
- package/dist/drivers/seccomp-helper-source.js +121 -0
- package/dist/drivers/seccomp-helper-source.js.map +1 -0
- package/dist/drivers/utils.d.ts +4 -0
- package/dist/drivers/utils.d.ts.map +1 -0
- package/dist/drivers/utils.js +5 -0
- package/dist/drivers/utils.js.map +1 -0
- package/dist/drivers/workspace.d.ts +6 -0
- package/dist/drivers/workspace.d.ts.map +1 -0
- package/dist/drivers/workspace.js +49 -0
- package/dist/drivers/workspace.js.map +1 -0
- package/dist/extensions/provider-adapter.d.ts +48 -0
- package/dist/extensions/provider-adapter.d.ts.map +1 -0
- package/dist/extensions/provider-adapter.js +64 -0
- package/dist/extensions/provider-adapter.js.map +1 -0
- package/dist/host.d.ts +33 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +20 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +19 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/model/artifact-collection.d.ts +84 -0
- package/dist/model/artifact-collection.d.ts.map +1 -0
- package/dist/model/artifact-collection.js +185 -0
- package/dist/model/artifact-collection.js.map +1 -0
- package/dist/model/authority.d.ts +89 -0
- package/dist/model/authority.d.ts.map +1 -0
- package/dist/model/authority.js +80 -0
- package/dist/model/authority.js.map +1 -0
- package/dist/model/bun-targets.d.ts +34 -0
- package/dist/model/bun-targets.d.ts.map +1 -0
- package/dist/model/bun-targets.js +17 -0
- package/dist/model/bun-targets.js.map +1 -0
- package/dist/model/canonical.d.ts +8 -0
- package/dist/model/canonical.d.ts.map +1 -0
- package/dist/model/canonical.js +205 -0
- package/dist/model/canonical.js.map +1 -0
- package/dist/model/catalog.d.ts +76 -0
- package/dist/model/catalog.d.ts.map +1 -0
- package/dist/model/catalog.js +174 -0
- package/dist/model/catalog.js.map +1 -0
- package/dist/model/digest.d.ts +53 -0
- package/dist/model/digest.d.ts.map +1 -0
- package/dist/model/digest.js +127 -0
- package/dist/model/digest.js.map +1 -0
- package/dist/model/errors.d.ts +14 -0
- package/dist/model/errors.d.ts.map +1 -0
- package/dist/model/errors.js +8 -0
- package/dist/model/errors.js.map +1 -0
- package/dist/model/primitives.d.ts +19 -0
- package/dist/model/primitives.d.ts.map +1 -0
- package/dist/model/primitives.js +18 -0
- package/dist/model/primitives.js.map +1 -0
- package/dist/model/pypi.d.ts +12 -0
- package/dist/model/pypi.d.ts.map +1 -0
- package/dist/model/pypi.js +20 -0
- package/dist/model/pypi.js.map +1 -0
- package/dist/model/python-distribution.d.ts +33 -0
- package/dist/model/python-distribution.d.ts.map +1 -0
- package/dist/model/python-distribution.js +367 -0
- package/dist/model/python-distribution.js.map +1 -0
- package/dist/model/secret-patterns.d.ts +2 -0
- package/dist/model/secret-patterns.d.ts.map +1 -0
- package/dist/model/secret-patterns.js +12 -0
- package/dist/model/secret-patterns.js.map +1 -0
- package/dist/platform/bun.d.ts +7 -0
- package/dist/platform/bun.d.ts.map +1 -0
- package/dist/platform/bun.js +15 -0
- package/dist/platform/bun.js.map +1 -0
- package/dist/platform/credentials.d.ts +32 -0
- package/dist/platform/credentials.d.ts.map +1 -0
- package/dist/platform/credentials.js +772 -0
- package/dist/platform/credentials.js.map +1 -0
- package/dist/platform/host-support.d.ts +2 -0
- package/dist/platform/host-support.d.ts.map +1 -0
- package/dist/platform/host-support.js +4 -0
- package/dist/platform/host-support.js.map +1 -0
- package/dist/platform/node.d.ts +7 -0
- package/dist/platform/node.d.ts.map +1 -0
- package/dist/platform/node.js +15 -0
- package/dist/platform/node.js.map +1 -0
- package/dist/platform/release-runtime.d.ts +11 -0
- package/dist/platform/release-runtime.d.ts.map +1 -0
- package/dist/platform/release-runtime.js +34 -0
- package/dist/platform/release-runtime.js.map +1 -0
- package/dist/platform/services.d.ts +15 -0
- package/dist/platform/services.d.ts.map +1 -0
- package/dist/platform/services.js +30 -0
- package/dist/platform/services.js.map +1 -0
- package/dist/platform/source-observer.d.ts +5 -0
- package/dist/platform/source-observer.d.ts.map +1 -0
- package/dist/platform/source-observer.js +159 -0
- package/dist/platform/source-observer.js.map +1 -0
- package/dist/provider-sdk.d.ts +14 -0
- package/dist/provider-sdk.d.ts.map +1 -0
- package/dist/provider-sdk.js +10 -0
- package/dist/provider-sdk.js.map +1 -0
- package/dist/publication/adapter.d.ts +212 -0
- package/dist/publication/adapter.d.ts.map +1 -0
- package/dist/publication/adapter.js +83 -0
- package/dist/publication/adapter.js.map +1 -0
- package/dist/publication/authority.d.ts +137 -0
- package/dist/publication/authority.d.ts.map +1 -0
- package/dist/publication/authority.js +233 -0
- package/dist/publication/authority.js.map +1 -0
- package/dist/publication/catalog-git.d.ts +37 -0
- package/dist/publication/catalog-git.d.ts.map +1 -0
- package/dist/publication/catalog-git.js +451 -0
- package/dist/publication/catalog-git.js.map +1 -0
- package/dist/publication/claim.d.ts +39 -0
- package/dist/publication/claim.d.ts.map +1 -0
- package/dist/publication/claim.js +31 -0
- package/dist/publication/claim.js.map +1 -0
- package/dist/publication/coordinator.d.ts +246 -0
- package/dist/publication/coordinator.d.ts.map +1 -0
- package/dist/publication/coordinator.js +370 -0
- package/dist/publication/coordinator.js.map +1 -0
- package/dist/publication/github.d.ts +36 -0
- package/dist/publication/github.d.ts.map +1 -0
- package/dist/publication/github.js +644 -0
- package/dist/publication/github.js.map +1 -0
- package/dist/publication/http.d.ts +69 -0
- package/dist/publication/http.d.ts.map +1 -0
- package/dist/publication/http.js +29 -0
- package/dist/publication/http.js.map +1 -0
- package/dist/publication/index.d.ts +5 -0
- package/dist/publication/index.d.ts.map +1 -0
- package/dist/publication/index.js +5 -0
- package/dist/publication/index.js.map +1 -0
- package/dist/publication/npm.d.ts +40 -0
- package/dist/publication/npm.d.ts.map +1 -0
- package/dist/publication/npm.js +359 -0
- package/dist/publication/npm.js.map +1 -0
- package/dist/publication/profiles.d.ts +136 -0
- package/dist/publication/profiles.d.ts.map +1 -0
- package/dist/publication/profiles.js +90 -0
- package/dist/publication/profiles.js.map +1 -0
- package/dist/publication/publisher.d.ts +82 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/publisher.js +53 -0
- package/dist/publication/publisher.js.map +1 -0
- package/dist/publication/pypi.d.ts +45 -0
- package/dist/publication/pypi.d.ts.map +1 -0
- package/dist/publication/pypi.js +369 -0
- package/dist/publication/pypi.js.map +1 -0
- package/dist/publication/recovery.d.ts +663 -0
- package/dist/publication/recovery.d.ts.map +1 -0
- package/dist/publication/recovery.js +252 -0
- package/dist/publication/recovery.js.map +1 -0
- package/dist/publication/report.d.ts +1061 -0
- package/dist/publication/report.d.ts.map +1 -0
- package/dist/publication/report.js +441 -0
- package/dist/publication/report.js.map +1 -0
- package/dist/recipes/config.d.ts +296 -0
- package/dist/recipes/config.d.ts.map +1 -0
- package/dist/recipes/config.js +325 -0
- package/dist/recipes/config.js.map +1 -0
- package/dist/release/capabilities.d.ts +12 -0
- package/dist/release/capabilities.d.ts.map +1 -0
- package/dist/release/capabilities.js +395 -0
- package/dist/release/capabilities.js.map +1 -0
- package/dist/release/compiler.d.ts +5 -0
- package/dist/release/compiler.d.ts.map +1 -0
- package/dist/release/compiler.js +19 -0
- package/dist/release/compiler.js.map +1 -0
- package/dist/release/config.d.ts +5 -0
- package/dist/release/config.d.ts.map +1 -0
- package/dist/release/config.js +10 -0
- package/dist/release/config.js.map +1 -0
- package/dist/release/context.d.ts +96 -0
- package/dist/release/context.d.ts.map +1 -0
- package/dist/release/context.js +168 -0
- package/dist/release/context.js.map +1 -0
- package/dist/release/graph.d.ts +271 -0
- package/dist/release/graph.d.ts.map +1 -0
- package/dist/release/graph.js +766 -0
- package/dist/release/graph.js.map +1 -0
- package/dist/release/inspect.d.ts +88 -0
- package/dist/release/inspect.d.ts.map +1 -0
- package/dist/release/inspect.js +75 -0
- package/dist/release/inspect.js.map +1 -0
- package/dist/release/prepare.d.ts +24 -0
- package/dist/release/prepare.d.ts.map +1 -0
- package/dist/release/prepare.js +1116 -0
- package/dist/release/prepare.js.map +1 -0
- package/dist/release/prepared-ref.d.ts +60 -0
- package/dist/release/prepared-ref.d.ts.map +1 -0
- package/dist/release/prepared-ref.js +131 -0
- package/dist/release/prepared-ref.js.map +1 -0
- package/dist/release/prepared-store.d.ts +90 -0
- package/dist/release/prepared-store.d.ts.map +1 -0
- package/dist/release/prepared-store.js +337 -0
- package/dist/release/prepared-store.js.map +1 -0
- package/dist/release/prepared.d.ts +172 -0
- package/dist/release/prepared.d.ts.map +1 -0
- package/dist/release/prepared.js +268 -0
- package/dist/release/prepared.js.map +1 -0
- package/dist/release/staging.d.ts +31 -0
- package/dist/release/staging.d.ts.map +1 -0
- package/dist/release/staging.js +218 -0
- package/dist/release/staging.js.map +1 -0
- package/dist/resolve/authored.d.ts +53 -0
- package/dist/resolve/authored.d.ts.map +1 -0
- package/dist/resolve/authored.js +55 -0
- package/dist/resolve/authored.js.map +1 -0
- package/dist/resolve/encode.d.ts +3 -0
- package/dist/resolve/encode.d.ts.map +1 -0
- package/dist/resolve/encode.js +21 -0
- package/dist/resolve/encode.js.map +1 -0
- package/dist/resolve/errors.d.ts +7 -0
- package/dist/resolve/errors.d.ts.map +1 -0
- package/dist/resolve/errors.js +17 -0
- package/dist/resolve/errors.js.map +1 -0
- package/dist/resolve/facts.d.ts +12 -0
- package/dist/resolve/facts.d.ts.map +1 -0
- package/dist/resolve/facts.js +18 -0
- package/dist/resolve/facts.js.map +1 -0
- package/dist/resolve/resolve.d.ts +10 -0
- package/dist/resolve/resolve.d.ts.map +1 -0
- package/dist/resolve/resolve.js +242 -0
- package/dist/resolve/resolve.js.map +1 -0
- package/dist/store.d.ts +11 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +9 -0
- package/dist/store.js.map +1 -0
- package/examples/README.md +20 -30
- package/examples/github-release/release.config.json +11 -18
- package/examples/homebrew-tap/README.md +11 -0
- package/examples/homebrew-tap/release.config.json +40 -28
- package/examples/multi-target/release.config.json +28 -53
- package/examples/npm-first-publish/release.config.json +23 -25
- package/examples/npm-only/release.config.json +22 -30
- package/examples/portable-cli/README.md +17 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-arm64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-x64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-arm64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-x64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-windows-x64.exe +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_10_15_x86_64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_11_0_arm64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_aarch64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_x86_64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-win_amd64.whl +1 -0
- package/examples/portable-cli/package.json +9 -0
- package/examples/portable-cli/release.config.json +53 -0
- package/examples/portable-cli/src/cli.ts +3 -0
- package/examples/pypi-registry/README.md +8 -0
- package/examples/scoop-bucket/README.md +10 -0
- package/examples/scoop-bucket/release.config.json +40 -30
- package/package.json +61 -154
- package/src/api/api.ts +365 -0
- package/src/api/errors.ts +36 -0
- package/src/api/input.ts +92 -0
- package/src/api/runtime.ts +14 -0
- package/src/api/types.ts +103 -0
- package/src/capabilities/bun-targets.ts +2 -0
- package/src/capabilities/field-ownership.ts +60 -0
- package/src/capabilities/module.ts +158 -0
- package/src/capabilities/registry.ts +333 -0
- package/src/config/config.ts +48 -0
- package/src/correction/coordinator.ts +336 -0
- package/src/correction/index.ts +2 -0
- package/src/correction/intent.ts +172 -0
- package/src/drivers/archive.ts +102 -0
- package/src/drivers/contain.ts +20 -0
- package/src/drivers/environment.ts +28 -0
- package/src/drivers/errors.ts +6 -0
- package/src/drivers/glob.ts +137 -0
- package/src/drivers/process.ts +340 -0
- package/src/drivers/redact.ts +31 -0
- package/src/drivers/seccomp-helper-source.ts +121 -0
- package/src/drivers/utils.ts +10 -0
- package/src/drivers/workspace.ts +40 -0
- package/src/extensions/provider-adapter.ts +99 -0
- package/src/host.ts +140 -0
- package/src/index.ts +64 -0
- package/src/model/artifact-collection.ts +237 -0
- package/src/model/authority.ts +116 -0
- package/src/model/bun-targets.ts +34 -0
- package/src/model/canonical.ts +205 -0
- package/src/model/catalog.ts +220 -0
- package/src/model/digest.ts +172 -0
- package/src/model/errors.ts +6 -0
- package/src/model/primitives.ts +37 -0
- package/src/model/pypi.ts +30 -0
- package/src/model/python-distribution.ts +360 -0
- package/src/model/secret-patterns.ts +11 -0
- package/src/platform/bun.ts +38 -0
- package/src/platform/credentials.ts +1083 -0
- package/src/platform/host-support.ts +4 -0
- package/src/platform/node.ts +38 -0
- package/src/platform/release-runtime.ts +47 -0
- package/src/platform/services.ts +57 -0
- package/src/platform/source-observer.ts +193 -0
- package/src/provider-sdk.ts +48 -0
- package/src/publication/adapter.ts +132 -0
- package/src/publication/authority.ts +397 -0
- package/src/publication/catalog-git.ts +603 -0
- package/src/publication/claim.ts +51 -0
- package/src/publication/coordinator.ts +578 -0
- package/src/publication/github.ts +954 -0
- package/src/publication/http.ts +101 -0
- package/src/publication/index.ts +4 -0
- package/src/publication/npm.ts +525 -0
- package/src/publication/profiles.ts +94 -0
- package/src/publication/publisher.ts +130 -0
- package/src/publication/pypi.ts +463 -0
- package/src/publication/recovery.ts +349 -0
- package/src/publication/report.ts +628 -0
- package/src/recipes/config.ts +395 -0
- package/src/release/capabilities.ts +459 -0
- package/src/release/compiler.ts +28 -0
- package/src/release/config.ts +12 -0
- package/src/release/context.ts +223 -0
- package/src/release/graph.ts +866 -0
- package/src/release/inspect.ts +83 -0
- package/src/release/prepare.ts +1331 -0
- package/src/release/prepared-ref.ts +193 -0
- package/src/release/prepared-store.ts +377 -0
- package/src/release/prepared.ts +299 -0
- package/src/release/staging.ts +257 -0
- package/src/resolve/authored.ts +64 -0
- package/src/resolve/encode.ts +22 -0
- package/src/resolve/errors.ts +15 -0
- package/src/resolve/facts.ts +18 -0
- package/src/resolve/resolve.ts +328 -0
- package/src/store.ts +28 -0
- package/templates/README.md +55 -59
- package/templates/bun-cli-github/README.md +12 -0
- package/templates/bun-cli-github/release.config.json +51 -0
- package/templates/github-actions/release.yml +57 -0
- package/templates/github-actions/reviewed-release.yml +80 -0
- package/templates/multi-target-homebrew/README.md +10 -0
- package/templates/multi-target-homebrew/release.config.json +43 -60
- package/templates/multi-target-scoop/README.md +10 -0
- package/templates/multi-target-scoop/release.config.json +43 -62
- package/templates/npm-github/release.config.json +25 -38
- package/templates/npm-github/reviewed-release.config.json +37 -0
- package/templates/npm-only/README.md +10 -0
- package/templates/npm-only/release.config.json +15 -30
- package/templates/portable-cli/README.md +13 -0
- package/templates/portable-cli/release.config.json +53 -0
- package/dist/config/errors.d.ts +0 -24
- package/dist/config/errors.d.ts.map +0 -1
- package/dist/config/errors.js +0 -19
- package/dist/config/errors.js.map +0 -1
- package/dist/config/load.d.ts +0 -9
- package/dist/config/load.d.ts.map +0 -1
- package/dist/config/load.js +0 -29
- package/dist/config/load.js.map +0 -1
- package/dist/config/schema.d.ts +0 -12
- package/dist/config/schema.d.ts.map +0 -1
- package/dist/config/schema.js +0 -19
- package/dist/config/schema.js.map +0 -1
- package/dist/domain/artifact.d.ts +0 -36
- package/dist/domain/artifact.d.ts.map +0 -1
- package/dist/domain/artifact.js +0 -29
- package/dist/domain/artifact.js.map +0 -1
- package/dist/domain/evidence.d.ts +0 -108
- package/dist/domain/evidence.d.ts.map +0 -1
- package/dist/domain/evidence.js +0 -96
- package/dist/domain/evidence.js.map +0 -1
- package/dist/domain/operation.d.ts +0 -153
- package/dist/domain/operation.d.ts.map +0 -1
- package/dist/domain/operation.js +0 -320
- package/dist/domain/operation.js.map +0 -1
- package/dist/domain/release.d.ts +0 -141
- package/dist/domain/release.d.ts.map +0 -1
- package/dist/domain/release.js +0 -127
- package/dist/domain/release.js.map +0 -1
- package/dist/domain/remote-state.d.ts +0 -85
- package/dist/domain/remote-state.d.ts.map +0 -1
- package/dist/domain/remote-state.js +0 -77
- package/dist/domain/remote-state.js.map +0 -1
- package/dist/domain/status.d.ts +0 -43
- package/dist/domain/status.d.ts.map +0 -1
- package/dist/domain/status.js +0 -51
- package/dist/domain/status.js.map +0 -1
- package/dist/domain/target.d.ts +0 -135
- package/dist/domain/target.d.ts.map +0 -1
- package/dist/domain/target.js +0 -137
- package/dist/domain/target.js.map +0 -1
- package/dist/host/host.d.ts +0 -32
- package/dist/host/host.d.ts.map +0 -1
- package/dist/host/host.js +0 -24
- package/dist/host/host.js.map +0 -1
- package/dist/host/http-live.d.ts +0 -6
- package/dist/host/http-live.d.ts.map +0 -1
- package/dist/host/http-live.js +0 -86
- package/dist/host/http-live.js.map +0 -1
- package/dist/host/http.d.ts +0 -43
- package/dist/host/http.d.ts.map +0 -1
- package/dist/host/http.js +0 -59
- package/dist/host/http.js.map +0 -1
- package/dist/host/platform.d.ts +0 -10
- package/dist/host/platform.d.ts.map +0 -1
- package/dist/host/platform.js +0 -114
- package/dist/host/platform.js.map +0 -1
- package/dist/host/test.d.ts +0 -23
- package/dist/host/test.d.ts.map +0 -1
- package/dist/host/test.js +0 -222
- package/dist/host/test.js.map +0 -1
- package/dist/internal/workflow-phases.d.ts +0 -3
- package/dist/internal/workflow-phases.d.ts.map +0 -1
- package/dist/internal/workflow-phases.js +0 -2
- package/dist/internal/workflow-phases.js.map +0 -1
- package/dist/internal/workspace-path.d.ts +0 -15
- package/dist/internal/workspace-path.d.ts.map +0 -1
- package/dist/internal/workspace-path.js +0 -36
- package/dist/internal/workspace-path.js.map +0 -1
- package/dist/planner/artifact-inventory.d.ts +0 -9
- package/dist/planner/artifact-inventory.d.ts.map +0 -1
- package/dist/planner/artifact-inventory.js +0 -84
- package/dist/planner/artifact-inventory.js.map +0 -1
- package/dist/planner/create-release-plan.d.ts +0 -5
- package/dist/planner/create-release-plan.d.ts.map +0 -1
- package/dist/planner/create-release-plan.js +0 -25
- package/dist/planner/create-release-plan.js.map +0 -1
- package/dist/planner/errors.d.ts +0 -81
- package/dist/planner/errors.d.ts.map +0 -1
- package/dist/planner/errors.js +0 -70
- package/dist/planner/errors.js.map +0 -1
- package/dist/planner/evidence-recorder.d.ts +0 -26
- package/dist/planner/evidence-recorder.d.ts.map +0 -1
- package/dist/planner/evidence-recorder.js +0 -330
- package/dist/planner/evidence-recorder.js.map +0 -1
- package/dist/planner/executor.d.ts +0 -58
- package/dist/planner/executor.d.ts.map +0 -1
- package/dist/planner/executor.js +0 -159
- package/dist/planner/executor.js.map +0 -1
- package/dist/planner/normalize-release.d.ts +0 -16
- package/dist/planner/normalize-release.d.ts.map +0 -1
- package/dist/planner/normalize-release.js +0 -218
- package/dist/planner/normalize-release.js.map +0 -1
- package/dist/planner/reconcile.d.ts +0 -17
- package/dist/planner/reconcile.d.ts.map +0 -1
- package/dist/planner/reconcile.js +0 -261
- package/dist/planner/reconcile.js.map +0 -1
- package/dist/planner/release-eligibility.d.ts +0 -39
- package/dist/planner/release-eligibility.d.ts.map +0 -1
- package/dist/planner/release-eligibility.js +0 -578
- package/dist/planner/release-eligibility.js.map +0 -1
- package/dist/planner/render-plan.d.ts +0 -15
- package/dist/planner/render-plan.d.ts.map +0 -1
- package/dist/planner/render-plan.js +0 -238
- package/dist/planner/render-plan.js.map +0 -1
- package/dist/planner/status.d.ts +0 -40
- package/dist/planner/status.d.ts.map +0 -1
- package/dist/planner/status.js +0 -313
- package/dist/planner/status.js.map +0 -1
- package/dist/targets/adapter-helpers.d.ts +0 -64
- package/dist/targets/adapter-helpers.d.ts.map +0 -1
- package/dist/targets/adapter-helpers.js +0 -124
- package/dist/targets/adapter-helpers.js.map +0 -1
- package/dist/targets/adapter.d.ts +0 -17
- package/dist/targets/adapter.d.ts.map +0 -1
- package/dist/targets/adapter.js +0 -2
- package/dist/targets/adapter.js.map +0 -1
- package/dist/targets/github-release.d.ts +0 -25
- package/dist/targets/github-release.d.ts.map +0 -1
- package/dist/targets/github-release.js +0 -82
- package/dist/targets/github-release.js.map +0 -1
- package/dist/targets/github.d.ts +0 -11
- package/dist/targets/github.d.ts.map +0 -1
- package/dist/targets/github.js +0 -125
- package/dist/targets/github.js.map +0 -1
- package/dist/targets/homebrew.d.ts +0 -11
- package/dist/targets/homebrew.d.ts.map +0 -1
- package/dist/targets/homebrew.js +0 -97
- package/dist/targets/homebrew.js.map +0 -1
- package/dist/targets/live.d.ts +0 -5
- package/dist/targets/live.d.ts.map +0 -1
- package/dist/targets/live.js +0 -50
- package/dist/targets/live.js.map +0 -1
- package/dist/targets/npm.d.ts +0 -10
- package/dist/targets/npm.d.ts.map +0 -1
- package/dist/targets/npm.js +0 -118
- package/dist/targets/npm.js.map +0 -1
- package/dist/targets/pypi.d.ts +0 -11
- package/dist/targets/pypi.d.ts.map +0 -1
- package/dist/targets/pypi.js +0 -103
- package/dist/targets/pypi.js.map +0 -1
- package/dist/targets/registry.d.ts +0 -25
- package/dist/targets/registry.d.ts.map +0 -1
- package/dist/targets/registry.js +0 -34
- package/dist/targets/registry.js.map +0 -1
- package/dist/targets/scoop.d.ts +0 -11
- package/dist/targets/scoop.d.ts.map +0 -1
- package/dist/targets/scoop.js +0 -78
- package/dist/targets/scoop.js.map +0 -1
- package/dist/types/effect-internal.d.ts +0 -5
- package/dist/types/effect-internal.d.ts.map +0 -1
- package/dist/types/effect-internal.js +0 -2
- package/dist/types/effect-internal.js.map +0 -1
- package/dist/workflows/config.d.ts +0 -252
- package/dist/workflows/config.d.ts.map +0 -1
- package/dist/workflows/config.js +0 -465
- package/dist/workflows/config.js.map +0 -1
- package/dist/workflows/diagnostics.d.ts +0 -62
- package/dist/workflows/diagnostics.d.ts.map +0 -1
- package/dist/workflows/diagnostics.js +0 -527
- package/dist/workflows/diagnostics.js.map +0 -1
- package/dist/workflows/evidence.d.ts +0 -26
- package/dist/workflows/evidence.d.ts.map +0 -1
- package/dist/workflows/evidence.js +0 -44
- package/dist/workflows/evidence.js.map +0 -1
- package/dist/workflows/index.d.ts +0 -7
- package/dist/workflows/index.d.ts.map +0 -1
- package/dist/workflows/index.js +0 -6
- package/dist/workflows/index.js.map +0 -1
- package/dist/workflows/init.d.ts +0 -84
- package/dist/workflows/init.d.ts.map +0 -1
- package/dist/workflows/init.js +0 -441
- package/dist/workflows/init.js.map +0 -1
- package/dist/workflows/live.d.ts +0 -9
- package/dist/workflows/live.d.ts.map +0 -1
- package/dist/workflows/live.js +0 -7
- package/dist/workflows/live.js.map +0 -1
- package/dist/workflows/options.d.ts +0 -30
- package/dist/workflows/options.d.ts.map +0 -1
- package/dist/workflows/options.js +0 -16
- package/dist/workflows/options.js.map +0 -1
- package/examples/non-strict-skips/artifacts/release-example-skips-0.1.0.tgz +0 -1
- package/examples/non-strict-skips/release.config.json +0 -31
- package/examples/pypi-registry/release.config.json +0 -31
- package/templates/github-actions/plan-and-approved-execute.yml +0 -58
- package/templates/github-actions/plan-only.yml +0 -33
- package/templates/github-actions/trusted-publishing.yml +0 -61
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
// Authored configuration plus observed facts → the canonical config, by total
|
|
2
|
+
// rules and nothing else. This is the ONLY place authored-to-canonical
|
|
3
|
+
// semantics may live: no recipe and no compiler may infer anything, because
|
|
4
|
+
// plan bytes are a function of the canonical value alone.
|
|
5
|
+
//
|
|
6
|
+
// Every rule is one of three shapes: the authored value wins, a fact fills an
|
|
7
|
+
// omission, or the two disagree and the resolver REFUSES naming both values and
|
|
8
|
+
// where each came from. Silence is never an option — a release that guesses its
|
|
9
|
+
// own identity is the defect this module exists to prevent.
|
|
10
|
+
import * as Schema from "effect/Schema"
|
|
11
|
+
import * as Semver from "semver"
|
|
12
|
+
import { MISSING_COMMIT } from "../model/errors.js"
|
|
13
|
+
import { NonEmptyName, OutputId, Version } from "../model/primitives.js"
|
|
14
|
+
import {
|
|
15
|
+
CandidateConfig,
|
|
16
|
+
type CandidateNpmPublish,
|
|
17
|
+
type CandidatePyPiPublish,
|
|
18
|
+
CanonicalNpmRegistryEndpoint,
|
|
19
|
+
NpmDistTag,
|
|
20
|
+
PyPiProjectName,
|
|
21
|
+
canonicalizeNpmRegistryEndpoint,
|
|
22
|
+
normalizePyPiProjectName
|
|
23
|
+
} from "../recipes/config.js"
|
|
24
|
+
import { AuthoredConfig } from "./authored.js"
|
|
25
|
+
import { toPlainJson } from "./encode.js"
|
|
26
|
+
import { ResolveError } from "./errors.js"
|
|
27
|
+
import { ObservedFacts } from "./facts.js"
|
|
28
|
+
|
|
29
|
+
const refuse = (field: string, reason: string): never => {
|
|
30
|
+
throw new ResolveError(field, reason)
|
|
31
|
+
}
|
|
32
|
+
const disagreement = (
|
|
33
|
+
field: string, authored: string, observed: string, source: string
|
|
34
|
+
): never =>
|
|
35
|
+
refuse(
|
|
36
|
+
`project.${field}`,
|
|
37
|
+
`project.${field} is ${JSON.stringify(authored)} in the config but ${
|
|
38
|
+
JSON.stringify(observed)
|
|
39
|
+
} ${source}. Remove the authored value or correct the source; the resolver never picks.`
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const decodeAuthored = Schema.decodeUnknownSync(AuthoredConfig, { onExcessProperty: "error" })
|
|
43
|
+
const decodeFacts = Schema.decodeUnknownSync(ObservedFacts, { onExcessProperty: "error" })
|
|
44
|
+
const decodeCandidate = Schema.decodeUnknownSync(CandidateConfig, { onExcessProperty: "error" })
|
|
45
|
+
|
|
46
|
+
const version = (
|
|
47
|
+
authored: AuthoredConfig, facts: ObservedFacts
|
|
48
|
+
): Version => {
|
|
49
|
+
const directive = authored.versionFrom
|
|
50
|
+
const observed = directive === "manifest"
|
|
51
|
+
? facts.manifestVersion
|
|
52
|
+
: directive === "git-tag"
|
|
53
|
+
? facts.headTagVersion
|
|
54
|
+
: undefined
|
|
55
|
+
const source = directive === "manifest" ? "in the package manifest" : "on the tag at HEAD"
|
|
56
|
+
if (authored.project.version !== undefined) {
|
|
57
|
+
if (observed !== undefined && observed !== authored.project.version) {
|
|
58
|
+
disagreement("version", authored.project.version, observed, source)
|
|
59
|
+
}
|
|
60
|
+
return authored.project.version
|
|
61
|
+
}
|
|
62
|
+
if (directive === undefined) {
|
|
63
|
+
return refuse(
|
|
64
|
+
"project.version",
|
|
65
|
+
"project.version is required. State it, or set versionFrom to \"manifest\" or \"git-tag\" so it can be observed."
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
if (observed === undefined) {
|
|
69
|
+
return refuse(
|
|
70
|
+
"project.version",
|
|
71
|
+
`versionFrom is ${JSON.stringify(directive)} but no version was observed ${source}.`
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
return observed
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// `{version}` is the whole grammar. An unrecognized token is a refusal, exactly
|
|
78
|
+
// as the checksum name filter treats one.
|
|
79
|
+
const tag = (authored: AuthoredConfig, resolved: Version): NonEmptyName => {
|
|
80
|
+
if (authored.project.tag !== undefined) return authored.project.tag
|
|
81
|
+
const template = authored.project.tagTemplate ?? "v{version}"
|
|
82
|
+
const rendered = template.replaceAll("{version}", resolved)
|
|
83
|
+
if (rendered.includes("{") || rendered.includes("}")) {
|
|
84
|
+
return refuse(
|
|
85
|
+
"project.tagTemplate",
|
|
86
|
+
`project.tagTemplate supports only the {version} token, got ${JSON.stringify(template)}.`
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
return NonEmptyName.make(rendered)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const requireObservedCommit = (facts: ObservedFacts): void => {
|
|
93
|
+
if (facts.commit === undefined) refuse("source.commit", MISSING_COMMIT)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const names = (
|
|
97
|
+
authored: AuthoredConfig, facts: ObservedFacts
|
|
98
|
+
): { readonly name: string, readonly packageName?: string } => {
|
|
99
|
+
const manifest = facts.manifestName
|
|
100
|
+
if (manifest !== undefined && authored.project.packageName !== undefined &&
|
|
101
|
+
manifest !== authored.project.packageName) {
|
|
102
|
+
disagreement("packageName", authored.project.packageName, manifest, "in the package manifest")
|
|
103
|
+
}
|
|
104
|
+
const name = authored.project.name ?? manifest
|
|
105
|
+
if (name === undefined) {
|
|
106
|
+
return refuse("project.name", "project.name is required when no package manifest is observed.")
|
|
107
|
+
}
|
|
108
|
+
const packageName = authored.project.packageName ?? manifest
|
|
109
|
+
return { name, ...(packageName === undefined ? {} : { packageName }) }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const repository = (authored: AuthoredConfig, facts: ObservedFacts): string | undefined => {
|
|
113
|
+
if (authored.project.repository !== undefined && facts.repository !== undefined && authored.project.repository !== facts.repository) {
|
|
114
|
+
disagreement("repository", authored.project.repository, facts.repository, "in the observed repository")
|
|
115
|
+
}
|
|
116
|
+
return authored.project.repository ?? facts.repository
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const canonicalRegistry = (value: string | undefined): CanonicalNpmRegistryEndpoint => {
|
|
120
|
+
try {
|
|
121
|
+
return CanonicalNpmRegistryEndpoint.make(
|
|
122
|
+
canonicalizeNpmRegistryEndpoint(value ?? "https://registry.npmjs.org")
|
|
123
|
+
)
|
|
124
|
+
} catch (cause) {
|
|
125
|
+
return refuse(
|
|
126
|
+
"publish.npm.registry",
|
|
127
|
+
cause instanceof Error ? cause.message : String(cause)
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const distTag = (versionValue: Version, authored: string | undefined): NpmDistTag => {
|
|
133
|
+
const normalized = Semver.valid(versionValue.toString())
|
|
134
|
+
if (normalized === null || normalized !== versionValue.toString()) {
|
|
135
|
+
return refuse(
|
|
136
|
+
"project.version",
|
|
137
|
+
`npm publication requires a canonical semantic version, got ${JSON.stringify(versionValue)}.`
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
const prerelease = Semver.prerelease(normalized) !== null
|
|
141
|
+
if (authored === undefined) {
|
|
142
|
+
if (prerelease) {
|
|
143
|
+
return refuse(
|
|
144
|
+
"publish.npm.distTag",
|
|
145
|
+
"Prerelease npm versions require an explicit non-latest distTag."
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
return NpmDistTag.make("latest")
|
|
149
|
+
}
|
|
150
|
+
let tag: NpmDistTag
|
|
151
|
+
try { tag = NpmDistTag.make(authored) } catch (cause) {
|
|
152
|
+
return refuse(
|
|
153
|
+
"publish.npm.distTag",
|
|
154
|
+
cause instanceof Error ? cause.message : String(cause)
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
if (prerelease && tag === "latest") {
|
|
158
|
+
return refuse(
|
|
159
|
+
"publish.npm.distTag",
|
|
160
|
+
"Prerelease npm versions cannot publish under the latest dist-tag."
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
return tag
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
type ResolvedProject = {
|
|
167
|
+
readonly name: string
|
|
168
|
+
readonly packageName?: string
|
|
169
|
+
readonly version: Version
|
|
170
|
+
readonly repository?: string
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const npmPublish = (
|
|
174
|
+
authored: AuthoredConfig,
|
|
175
|
+
project: ResolvedProject
|
|
176
|
+
): CandidateNpmPublish | undefined => {
|
|
177
|
+
const npm = authored.publish?.npm
|
|
178
|
+
if (npm === undefined) return undefined
|
|
179
|
+
if (authored.npmPackage === undefined) {
|
|
180
|
+
return refuse(
|
|
181
|
+
"npmPackage",
|
|
182
|
+
"publish.npm requires npmPackage to declare the exact package artifact prepared by npm pack."
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
const packageName = project.packageName ?? project.name
|
|
186
|
+
if (npm.access === "restricted" && !packageName.startsWith("@")) {
|
|
187
|
+
return refuse(
|
|
188
|
+
"publish.npm.access",
|
|
189
|
+
"npm restricted access is valid only for scoped package names."
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
const registry = canonicalRegistry(npm.registry)
|
|
193
|
+
const authentication = npm.authentication
|
|
194
|
+
if (authentication.strategy === "trusted-publishing") {
|
|
195
|
+
if (registry !== "https://registry.npmjs.org/") {
|
|
196
|
+
return refuse(
|
|
197
|
+
"publish.npm.authentication",
|
|
198
|
+
"npm trusted publishing is certified only for https://registry.npmjs.org/."
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
if (project.repository === undefined) {
|
|
202
|
+
return refuse(
|
|
203
|
+
"project.repository",
|
|
204
|
+
"npm trusted publishing requires the exact GitHub owner/repository coordinate."
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
if (authentication.attestation.repository !== project.repository) {
|
|
208
|
+
return refuse(
|
|
209
|
+
"publish.npm.authentication.attestation.repository",
|
|
210
|
+
`The attested repository ${JSON.stringify(authentication.attestation.repository)} does not match ${
|
|
211
|
+
JSON.stringify(project.repository)
|
|
212
|
+
} resolved for the package.`
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const provenance = npm.provenance ??
|
|
217
|
+
(authentication.strategy === "trusted-publishing" ? "automatic" : "disabled")
|
|
218
|
+
if (authentication.strategy === "token" && provenance === "automatic") {
|
|
219
|
+
return refuse(
|
|
220
|
+
"publish.npm.provenance",
|
|
221
|
+
"Automatic provenance is an npm trusted-publishing behavior; token mode must choose required or disabled."
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
packageArtifact: OutputId.make("npm-package"),
|
|
226
|
+
packageName: NonEmptyName.make(packageName),
|
|
227
|
+
registry,
|
|
228
|
+
distTag: distTag(project.version, npm.distTag),
|
|
229
|
+
access: npm.access ?? "public",
|
|
230
|
+
authentication,
|
|
231
|
+
provenance
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const pypiPublish = (
|
|
236
|
+
authored: AuthoredConfig,
|
|
237
|
+
project: ResolvedProject
|
|
238
|
+
): CandidatePyPiPublish | undefined => {
|
|
239
|
+
const pypi = authored.publish?.pypi
|
|
240
|
+
if (pypi === undefined) return undefined
|
|
241
|
+
const artifacts = pypi.artifacts.map((id) => OutputId.make(id)) as [OutputId, ...Array<OutputId>]
|
|
242
|
+
if (new Set(artifacts).size !== artifacts.length) {
|
|
243
|
+
return refuse("publish.pypi.artifacts", "PyPI publication cannot repeat one distribution artifact.")
|
|
244
|
+
}
|
|
245
|
+
if (pypi.authentication.strategy === "trusted-publishing") {
|
|
246
|
+
if (project.repository === undefined) {
|
|
247
|
+
return refuse("project.repository", "External PyPI trusted publishing requires the exact GitHub owner/repository coordinate.")
|
|
248
|
+
}
|
|
249
|
+
if (pypi.authentication.repository !== project.repository) {
|
|
250
|
+
return refuse(
|
|
251
|
+
"publish.pypi.authentication.repository",
|
|
252
|
+
`The external PyPI publisher repository ${JSON.stringify(pypi.authentication.repository)} does not match ${JSON.stringify(project.repository)}.`
|
|
253
|
+
)
|
|
254
|
+
}
|
|
255
|
+
let projectName: string
|
|
256
|
+
let projects: ReadonlyArray<string>
|
|
257
|
+
try {
|
|
258
|
+
projectName = normalizePyPiProjectName(project.name)
|
|
259
|
+
projects = pypi.authentication.projects.map(normalizePyPiProjectName)
|
|
260
|
+
} catch (cause) {
|
|
261
|
+
return refuse("publish.pypi", cause instanceof Error ? cause.message : String(cause))
|
|
262
|
+
}
|
|
263
|
+
if (!projects.includes(projectName)) {
|
|
264
|
+
return refuse(
|
|
265
|
+
"publish.pypi.authentication.projects",
|
|
266
|
+
`The external PyPI publisher authority set does not include ${JSON.stringify(projectName)}.`
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
if (new Set(projects).size !== projects.length) {
|
|
270
|
+
return refuse("publish.pypi.authentication.projects", "External PyPI publisher project coordinates must be unique after normalization.")
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
let projectName: PyPiProjectName
|
|
274
|
+
try { projectName = PyPiProjectName.make(normalizePyPiProjectName(project.name)) } catch (cause) {
|
|
275
|
+
return refuse("publish.pypi", cause instanceof Error ? cause.message : String(cause))
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
artifacts,
|
|
279
|
+
project: projectName,
|
|
280
|
+
version: project.version,
|
|
281
|
+
repository: pypi.repository ?? "pypi",
|
|
282
|
+
authentication: pypi.authentication
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Resolve an authored configuration and observed facts into the canonical
|
|
288
|
+
* configuration. Pure and total: the same inputs always produce the same value,
|
|
289
|
+
* and every unfillable or contradicted field raises `ResolveError`.
|
|
290
|
+
*/
|
|
291
|
+
export { MISSING_COMMIT }
|
|
292
|
+
|
|
293
|
+
export const resolveConfig = (authored: unknown, facts: unknown): CandidateConfig => {
|
|
294
|
+
const config = decodeAuthored(authored)
|
|
295
|
+
const observed = decodeFacts(facts)
|
|
296
|
+
const resolvedVersion = version(config, observed)
|
|
297
|
+
// The directives are CONSUMED here: they describe how to resolve, and the
|
|
298
|
+
// canonical world has never heard of them.
|
|
299
|
+
const { project, versionFrom: _directive, $schema: _schema, ...rest } = config
|
|
300
|
+
const { tagTemplate: _template, ...projectRest } = project
|
|
301
|
+
const resolvedNames = names(config, observed)
|
|
302
|
+
const resolvedRepository = repository(config, observed)
|
|
303
|
+
// Verified source identity is observation-owned. It must exist, but is not a
|
|
304
|
+
// human-authored config field and is not copied into canonical release intent.
|
|
305
|
+
requireObservedCommit(observed)
|
|
306
|
+
const resolvedProject = {
|
|
307
|
+
...projectRest,
|
|
308
|
+
...resolvedNames,
|
|
309
|
+
...(resolvedRepository === undefined ? {} : { repository: resolvedRepository }),
|
|
310
|
+
version: resolvedVersion,
|
|
311
|
+
tag: tag(config, resolvedVersion)
|
|
312
|
+
}
|
|
313
|
+
const npm = npmPublish(config, resolvedProject)
|
|
314
|
+
const pypi = pypiPublish(config, resolvedProject)
|
|
315
|
+
const publish = config.publish === undefined ? undefined : {
|
|
316
|
+
...config.publish,
|
|
317
|
+
...(config.publish.npm === undefined ? {} : { npm }),
|
|
318
|
+
...(config.publish.pypi === undefined ? {} : { pypi })
|
|
319
|
+
}
|
|
320
|
+
// Plain JSON, not class instances: this value goes straight to `plan`, whose
|
|
321
|
+
// decoder refuses anything with a prototype.
|
|
322
|
+
const plain = toPlainJson({
|
|
323
|
+
...rest,
|
|
324
|
+
project: resolvedProject,
|
|
325
|
+
...(publish === undefined ? {} : { publish })
|
|
326
|
+
})
|
|
327
|
+
return toPlainJson(decodeCandidate(plain)) as CandidateConfig
|
|
328
|
+
}
|
package/src/store.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported durable-store library boundary.
|
|
3
|
+
*
|
|
4
|
+
* The store service tag remains private. Hosts pass this structural value to
|
|
5
|
+
* one of the public layer constructors instead of assembling Effect contexts.
|
|
6
|
+
*/
|
|
7
|
+
export {
|
|
8
|
+
GitHubActionsPreparedStoreProvenance,
|
|
9
|
+
LocalPreparedStoreProvenance,
|
|
10
|
+
PreparedCommitHandoffError,
|
|
11
|
+
PreparedStoreError,
|
|
12
|
+
PreparedStoreProvenanceError,
|
|
13
|
+
verifyPreparedStoreProvenance,
|
|
14
|
+
makeLocalPreparedReleaseStore
|
|
15
|
+
} from "./release/prepared-store.js"
|
|
16
|
+
export type {
|
|
17
|
+
CommittedPreparedRelease,
|
|
18
|
+
PreparedBundle,
|
|
19
|
+
PreparedStoreProvenance,
|
|
20
|
+
PreparedReleaseStoreShape
|
|
21
|
+
} from "./release/prepared-store.js"
|
|
22
|
+
export {
|
|
23
|
+
PreparedManifestError,
|
|
24
|
+
PreparedReleaseV2,
|
|
25
|
+
decodePreparedRelease,
|
|
26
|
+
encodePreparedRelease
|
|
27
|
+
} from "./release/prepared.js"
|
|
28
|
+
export type { CompletePreparedReleaseRef } from "./release/prepared-ref.js"
|
package/templates/README.md
CHANGED
|
@@ -1,59 +1,55 @@
|
|
|
1
|
-
# Release
|
|
2
|
-
|
|
3
|
-
Templates are
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
The
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
```sh
|
|
57
|
-
bun run cli doctor --config release.config.json --format text
|
|
58
|
-
bun run cli check-ci --config release.config.json --workflow .github/workflows/release.yml --format markdown
|
|
59
|
-
```
|
|
1
|
+
# Release templates
|
|
2
|
+
|
|
3
|
+
Templates are complete starting points for authored configuration and GitHub
|
|
4
|
+
Actions. Replace package, repository, artifact, and provider values before use.
|
|
5
|
+
|
|
6
|
+
The smallest workflow path is automatic: one job invokes the Action once. On
|
|
7
|
+
a fresh run it selects `release`, and the Action durably commits the complete
|
|
8
|
+
bundle before publication. Copy
|
|
9
|
+
`github-actions/release.yml` with `npm-github/release.config.json`. If a host
|
|
10
|
+
gate is required, copy the two-job `github-actions/reviewed-release.yml` and
|
|
11
|
+
its paired `npm-github/reviewed-release.config.json`; its prepare job emits one
|
|
12
|
+
exact hosted reference and only its publish job has the protected environment
|
|
13
|
+
and mutation permissions. Every Action step uploads only its redacted
|
|
14
|
+
`report-ref` as a workflow artifact. Prepared bytes stay in the dedicated
|
|
15
|
+
content-addressed Action store and are not duplicated by a generic artifact
|
|
16
|
+
step.
|
|
17
|
+
|
|
18
|
+
Both templates expose only `workflow_dispatch` and require `candidate_sha`.
|
|
19
|
+
Dispatch at `refs/heads/main` and pass the exact current commit; a ref or SHA
|
|
20
|
+
mismatch rejects the entire job before checkout. The automatic template also
|
|
21
|
+
accepts optional `prepared_ref`. Leave it empty for the fresh `release` path.
|
|
22
|
+
To recover a prior automatic run, pass its exact `prepared:gha:` value: the
|
|
23
|
+
same job selects `publish`, passes no config, uses `actions: read` to load the
|
|
24
|
+
prior artifact, and never rebuilds. Config and prepared reference are mutually
|
|
25
|
+
exclusive.
|
|
26
|
+
|
|
27
|
+
The reviewed template retains the same candidate admission on both jobs. If
|
|
28
|
+
its publish job fails after preparation, rerun that failed job in the same
|
|
29
|
+
workflow run so `${{ needs.prepare.outputs.prepared-ref }}` continues to name
|
|
30
|
+
the original bundle. Do not create a new prepare run as recovery.
|
|
31
|
+
|
|
32
|
+
The trusted-publishing job installs the Node 22.22.2 and npm 11.5.1
|
|
33
|
+
publisher boundary explicitly. The reviewed prepare job has no OIDC or publish
|
|
34
|
+
authority; only its publish job installs that publisher toolchain.
|
|
35
|
+
Trusted configuration must name the invoking workflow and exact ref: the
|
|
36
|
+
automatic pair uses `release.yml`, while the reviewed pair uses
|
|
37
|
+
`reviewed-release.yml`. Keep those filenames when copying the pair, dispatch
|
|
38
|
+
it from `refs/heads/main`, or update the exact config fields deliberately. A
|
|
39
|
+
repository, workflow path/ref, hosted-runner, direct action, or certified-sink
|
|
40
|
+
mismatch fails before OIDC request material is read.
|
|
41
|
+
|
|
42
|
+
Runnable configuration templates cover npm, GitHub Releases, portable
|
|
43
|
+
binaries, typed Homebrew formulas, and typed Scoop manifests. Templates are schema-checked;
|
|
44
|
+
support still requires a default-layer vertical test and clean-candidate
|
|
45
|
+
evidence, not merely a field appearing in a template.
|
|
46
|
+
|
|
47
|
+
`npm-github` is the GitHub-hosted trusted-publishing default. `npm-only` is the
|
|
48
|
+
explicit token-mode migration template for non-OIDC hosts; it names a
|
|
49
|
+
credential reference but never contains a credential value.
|
|
50
|
+
|
|
51
|
+
All public Action templates use the exact intended monorepo coordinate
|
|
52
|
+
`mannyc2/ts-release/apps/ts-release-action@v0.2.2`. Do not switch it to a
|
|
53
|
+
floating branch. Candidate certification must stop unless the immutable tag
|
|
54
|
+
can exist at the exact result commit before a package README naming it is
|
|
55
|
+
published.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Bun CLI and GitHub Releases
|
|
2
|
+
|
|
3
|
+
This complete fixture prepares an npm package plus a Bun-compiled CLI matrix
|
|
4
|
+
attached to a GitHub Release. Build outputs are captured in the prepared bundle.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
ts-release inspect --config release.config.json
|
|
8
|
+
ts-release release --config release.config.json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Rename the project-local ids, entrypoint, target matrix, and output template
|
|
12
|
+
before releasing.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/mannyc2/ts-release/main/schema/release-config.schema.json",
|
|
3
|
+
"project": {
|
|
4
|
+
"name": "@scope/pkg",
|
|
5
|
+
"packageName": "@scope/pkg",
|
|
6
|
+
"repository": "owner/repo",
|
|
7
|
+
"version": "0.1.0",
|
|
8
|
+
"tag": "v0.1.0"
|
|
9
|
+
},
|
|
10
|
+
"npmPackage": {
|
|
11
|
+
"path": "."
|
|
12
|
+
},
|
|
13
|
+
"builds": [
|
|
14
|
+
{
|
|
15
|
+
"builder": "bun",
|
|
16
|
+
"id": "cli",
|
|
17
|
+
"entry": "src/cli.ts",
|
|
18
|
+
"targets": [
|
|
19
|
+
"linux-x64",
|
|
20
|
+
"linux-arm64",
|
|
21
|
+
"darwin-x64",
|
|
22
|
+
"darwin-arm64"
|
|
23
|
+
],
|
|
24
|
+
"output": "artifacts/pkg-{version}-{targetTriple}{ext}"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"publish": {
|
|
28
|
+
"npm": {
|
|
29
|
+
"registry": "https://registry.npmjs.org/",
|
|
30
|
+
"authentication": {
|
|
31
|
+
"strategy": "trusted-publishing",
|
|
32
|
+
"attestation": {
|
|
33
|
+
"provider": "github-actions",
|
|
34
|
+
"runner": "github-hosted",
|
|
35
|
+
"repository": "owner/repo",
|
|
36
|
+
"workflow": "release.yml",
|
|
37
|
+
"workflowRef": "refs/heads/main",
|
|
38
|
+
"allowedAction": "npm-publish-direct"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"access": "public",
|
|
42
|
+
"provenance": "automatic"
|
|
43
|
+
},
|
|
44
|
+
"github": {
|
|
45
|
+
"repository": "owner/repo",
|
|
46
|
+
"tokenEnv": "GITHUB_TOKEN",
|
|
47
|
+
"draft": true,
|
|
48
|
+
"prerelease": false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
candidate_sha:
|
|
7
|
+
description: Exact candidate commit; it must be the current main tip.
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
prepared_ref:
|
|
11
|
+
description: Optional prepared:gha reference for recovery; leave empty for a fresh release.
|
|
12
|
+
required: false
|
|
13
|
+
default: ""
|
|
14
|
+
type: string
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
release:
|
|
21
|
+
if: ${{ github.ref == 'refs/heads/main' && github.sha == inputs.candidate_sha }}
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
permissions:
|
|
24
|
+
actions: read
|
|
25
|
+
contents: write
|
|
26
|
+
id-token: write
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
persist-credentials: false
|
|
31
|
+
- uses: actions/setup-node@v4
|
|
32
|
+
with:
|
|
33
|
+
node-version: "22.22.2"
|
|
34
|
+
- uses: oven-sh/setup-bun@v2
|
|
35
|
+
with:
|
|
36
|
+
bun-version: "1.3.14"
|
|
37
|
+
- run: bun add --global npm@11.5.1
|
|
38
|
+
- name: Prime isolated Bun dependency cache
|
|
39
|
+
if: ${{ inputs.prepared_ref == '' }}
|
|
40
|
+
run: |-
|
|
41
|
+
bun install --frozen-lockfile --ignore-scripts --no-save --linker=hoisted
|
|
42
|
+
bun --no-env-file --no-install -e 'await (await import("node:fs/promises")).rm("node_modules", { recursive: true, force: true })'
|
|
43
|
+
- id: release
|
|
44
|
+
uses: mannyc2/ts-release/apps/ts-release-action@v0.2.2
|
|
45
|
+
env:
|
|
46
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
47
|
+
with:
|
|
48
|
+
command: ${{ inputs.prepared_ref == '' && 'release' || 'publish' }}
|
|
49
|
+
config: ${{ inputs.prepared_ref == '' && 'release.config.json' || '' }}
|
|
50
|
+
prepared: ${{ inputs.prepared_ref }}
|
|
51
|
+
- name: Upload redacted release report
|
|
52
|
+
if: ${{ always() && steps.release.outputs.report-ref != '' }}
|
|
53
|
+
uses: actions/upload-artifact@v4
|
|
54
|
+
with:
|
|
55
|
+
name: ts-release-report-${{ github.run_attempt }}
|
|
56
|
+
path: ${{ steps.release.outputs.report-ref }}
|
|
57
|
+
if-no-files-found: error
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: Reviewed release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
candidate_sha:
|
|
7
|
+
description: Exact candidate commit; it must be the current main tip.
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
prepare:
|
|
16
|
+
if: ${{ github.ref == 'refs/heads/main' && github.sha == inputs.candidate_sha }}
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
outputs:
|
|
19
|
+
prepared-ref: ${{ steps.prepare.outputs.prepared-ref }}
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
- uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: "22.22.2"
|
|
27
|
+
- uses: oven-sh/setup-bun@v2
|
|
28
|
+
with:
|
|
29
|
+
bun-version: "1.3.14"
|
|
30
|
+
- run: bun add --global npm@11.5.1
|
|
31
|
+
- name: Prime isolated Bun dependency cache
|
|
32
|
+
run: |-
|
|
33
|
+
bun install --frozen-lockfile --ignore-scripts --no-save --linker=hoisted
|
|
34
|
+
bun --no-env-file --no-install -e 'await (await import("node:fs/promises")).rm("node_modules", { recursive: true, force: true })'
|
|
35
|
+
- id: prepare
|
|
36
|
+
uses: mannyc2/ts-release/apps/ts-release-action@v0.2.2
|
|
37
|
+
with:
|
|
38
|
+
command: prepare
|
|
39
|
+
config: reviewed-release.config.json
|
|
40
|
+
- name: Upload redacted preparation report
|
|
41
|
+
if: ${{ always() && steps.prepare.outputs.report-ref != '' }}
|
|
42
|
+
uses: actions/upload-artifact@v4
|
|
43
|
+
with:
|
|
44
|
+
name: ts-release-prepare-report-${{ github.run_attempt }}
|
|
45
|
+
path: ${{ steps.prepare.outputs.report-ref }}
|
|
46
|
+
if-no-files-found: error
|
|
47
|
+
|
|
48
|
+
publish:
|
|
49
|
+
if: ${{ github.ref == 'refs/heads/main' && github.sha == inputs.candidate_sha }}
|
|
50
|
+
needs: prepare
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
environment: release
|
|
53
|
+
permissions:
|
|
54
|
+
contents: write
|
|
55
|
+
id-token: write
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
with:
|
|
59
|
+
persist-credentials: false
|
|
60
|
+
- uses: actions/setup-node@v4
|
|
61
|
+
with:
|
|
62
|
+
node-version: "22.22.2"
|
|
63
|
+
- uses: oven-sh/setup-bun@v2
|
|
64
|
+
with:
|
|
65
|
+
bun-version: "1.3.14"
|
|
66
|
+
- run: bun add --global npm@11.5.1
|
|
67
|
+
- id: publish
|
|
68
|
+
uses: mannyc2/ts-release/apps/ts-release-action@v0.2.2
|
|
69
|
+
env:
|
|
70
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
71
|
+
with:
|
|
72
|
+
command: publish
|
|
73
|
+
prepared: ${{ needs.prepare.outputs.prepared-ref }}
|
|
74
|
+
- name: Upload redacted publication report
|
|
75
|
+
if: ${{ always() && steps.publish.outputs.report-ref != '' }}
|
|
76
|
+
uses: actions/upload-artifact@v4
|
|
77
|
+
with:
|
|
78
|
+
name: ts-release-publish-report-${{ github.run_attempt }}
|
|
79
|
+
path: ${{ steps.publish.outputs.report-ref }}
|
|
80
|
+
if-no-files-found: error
|