Publish #934
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: Publish | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| publish_now: | |
| description: Publish immediately without evaluating the release gate. | |
| required: true | |
| default: false | |
| type: boolean | |
| confirmation: | |
| description: 'Required when publish_now is true: type "publish @overkill-dev packages".' | |
| required: false | |
| type: string | |
| permissions: {} | |
| concurrency: | |
| group: publish-main | |
| jobs: | |
| evaluate-gate: | |
| runs-on: ubuntu-latest | |
| name: Evaluate GitHub release gate | |
| permissions: | |
| contents: read # required for actions/checkout to read the workflow source | |
| issues: read # required by the release gate to inspect open issue activity | |
| pull-requests: read # required by the release gate to inspect open PR activity | |
| outputs: | |
| should_publish: ${{ steps.force-publish.outputs.should_publish || steps.release-gate.outputs.should_publish }} | |
| reason: ${{ steps.force-publish.outputs.reason || steps.release-gate.outputs.reason }} | |
| main_head_sha: ${{ steps.main-head.outputs.main_head_sha }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: main | |
| persist-credentials: false | |
| - name: Resolve main commit | |
| id: main-head | |
| run: echo "main_head_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
| - name: Confirm manual publish override | |
| id: force-publish | |
| if: inputs.publish_now | |
| env: | |
| CONFIRMATION: ${{ inputs.confirmation }} | |
| run: | | |
| if [ "${CONFIRMATION}" != "publish @overkill-dev packages" ]; then | |
| echo "::error::Manual publish override requires confirmation: publish @overkill-dev packages" | |
| exit 1 | |
| fi | |
| echo "should_publish=true" >> "$GITHUB_OUTPUT" | |
| echo "reason=manual publish override confirmed" >> "$GITHUB_OUTPUT" | |
| - name: Use Node.js from package metadata | |
| if: ${{ !inputs.publish_now }} | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version-file: package.json | |
| - name: Install dependencies | |
| if: ${{ !inputs.publish_now }} | |
| run: npm ci | |
| - name: Verify registry signatures for installed dependencies | |
| if: ${{ !inputs.publish_now }} | |
| run: npm audit signatures | |
| - name: Verify `@packtory/github-release-gate` ships with a provenance attestation | |
| if: ${{ !inputs.publish_now }} | |
| run: | | |
| version=$(jq -r '.devDependencies["@packtory/github-release-gate"]' package.json) | |
| spec="@packtory/github-release-gate@${version}" | |
| attestation=$(npm view "${spec}" --json | jq -r '.dist.attestations // empty') | |
| if [ -z "${attestation}" ]; then | |
| echo "::error::${spec} is missing a provenance attestation; refusing to evaluate release gate" | |
| exit 1 | |
| fi | |
| echo "Verified ${spec} has a registered provenance attestation." | |
| - name: Compile TypeScript | |
| if: ${{ !inputs.publish_now }} | |
| run: npx just compile | |
| - name: Evaluate GitHub release gate | |
| id: release-gate | |
| if: ${{ !inputs.publish_now }} | |
| run: npx github-release-gate | |
| env: | |
| CI_WORKFLOW_FILE: continuous-integration.yml | |
| DEFAULT_BRANCH: main | |
| DEPENDENCY_ONLY_MIN_AGE_DAYS: "7" | |
| GITHUB_TOKEN: ${{ github.token }} | |
| MAX_LATENCY_HOURS: "24" | |
| QUIET_PERIOD_MINUTES: "45" | |
| - name: Log gate decision when publish is skipped | |
| if: ${{ !inputs.publish_now && steps.release-gate.outputs.should_publish != 'true' }} | |
| env: | |
| GATE_REASON: ${{ steps.release-gate.outputs.reason }} | |
| run: echo "Skipping publish because ${GATE_REASON}." | |
| publish: | |
| needs: evaluate-gate | |
| if: needs.evaluate-gate.outputs.should_publish == 'true' | |
| runs-on: ubuntu-latest | |
| name: Publish packages | |
| permissions: | |
| contents: read # required for actions/checkout to read the workflow source | |
| id-token: write # required by npm trusted publishing to mint the OIDC token | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: ${{ needs.evaluate-gate.outputs.main_head_sha }} | |
| persist-credentials: false | |
| - name: Use Node.js from package metadata | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version-file: package.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Verify registry signatures for installed dependencies | |
| run: npm audit signatures | |
| - name: Verify `@packtory/cli` ships with a provenance attestation | |
| run: | | |
| version=$(jq -r '.devDependencies["@packtory/cli"]' package.json) | |
| spec="@packtory/cli@${version}" | |
| attestation=$(npm view "${spec}" --json | jq -r '.dist.attestations // empty') | |
| if [ -z "${attestation}" ]; then | |
| echo "::error::${spec} is missing a provenance attestation; refusing to publish" | |
| exit 1 | |
| fi | |
| echo "Verified ${spec} has a registered provenance attestation." | |
| - name: Compile TypeScript | |
| run: npx just compile | |
| - name: Publish packages | |
| id: publish-packages | |
| continue-on-error: true | |
| run: npx packtory publish --no-dry-run | |
| - name: Re-publish after a transient sigstore failure | |
| if: steps.publish-packages.outcome == 'failure' | |
| run: | | |
| sleep 10 | |
| npx packtory publish --no-dry-run |