Skip to content

Publish

Publish #934

Workflow file for this run

---
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