diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b9267d8b..391106d4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,12 +14,18 @@ on: permissions: contents: read # workflow default (least privilege); only stage-publish also needs id-token, granted on that job +concurrency: + group: publish-${{ github.workflow }} # serialize publishes; no dist-tag races + cancel-in-progress: false # queue, don't kill an in-flight publish + jobs: verify: runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: { persist-credentials: false } + with: + persist-credentials: false + fetch-depth: 0 # full history for the ancestry check below - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' # pin >= 22.14.0 @@ -35,13 +41,13 @@ jobs: RELEASE_TAG: ${{ github.event.release.tag_name }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} run: | - git fetch origin "$DEFAULT_BRANCH" --depth=1 git merge-base --is-ancestor "$GITHUB_SHA" "origin/$DEFAULT_BRANCH" \ || { echo "release $RELEASE_TAG not reachable from $DEFAULT_BRANCH — refusing"; exit 1; } stage-publish: needs: verify runs-on: ubuntu-latest + timeout-minutes: 15 # cap a hung publish permissions: contents: read id-token: write # OIDC trusted publishing: only this job mints the token