Stage v2.6.0 #4
Workflow file for this run
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: Stage npm Release | |
| run-name: Stage ${{ github.ref_name }} | |
| # Runs only at a signed release tag, dispatched by build.yml's release job. | |
| # This file is frozen at the tag it runs from, so build.yml rehearses the same | |
| # pack, install, and load procedure on every push to main. | |
| on: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| shell: bash | |
| concurrency: | |
| group: stage-${{ github.repository }}-${{ github.ref }} | |
| cancel-in-progress: false | |
| queue: single | |
| jobs: | |
| validate: | |
| name: Validate signed release tag | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| package_name: ${{ steps.identity.outputs.package_name }} | |
| tag_object_sha: ${{ steps.identity.outputs.tag_object_sha }} | |
| version: ${{ steps.identity.outputs.version }} | |
| steps: | |
| - name: Checkout the release tag | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Verify tag, version, and signatures | |
| id: identity | |
| env: | |
| EXPECTED_PACKAGE_NAME: "@photostructure/sqlite" | |
| EXPECTED_REPOSITORY_URL: git+https://github.com/photostructure/node-sqlite.git | |
| GH_TOKEN: ${{ github.token }} | |
| REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| if [[ ! "$REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || \ | |
| [[ "$GITHUB_REF" != "refs/tags/$REF_NAME" ]]; then | |
| echo "::error::This workflow must run at a vMAJOR.MINOR.PATCH tag, not $GITHUB_REF" | |
| exit 1 | |
| fi | |
| PACKAGE_NAME="$(node -p "require('./package.json').name")" | |
| VERSION="$(node -p "require('./package.json').version")" | |
| REPOSITORY_URL="$(node -p "require('./package.json').repository.url")" | |
| if [[ "$PACKAGE_NAME" != "$EXPECTED_PACKAGE_NAME" || \ | |
| "$REPOSITORY_URL" != "$EXPECTED_REPOSITORY_URL" ]]; then | |
| echo "::error::The tagged package identity does not match this repository" | |
| exit 1 | |
| fi | |
| if [[ "$REF_NAME" != "v$VERSION" ]]; then | |
| echo "::error::Tag $REF_NAME does not match package version $VERSION" | |
| exit 1 | |
| fi | |
| REF_OBJECT_TYPE="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$REF_NAME" --jq '.object.type' | |
| )" | |
| TAG_OBJECT_SHA="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$REF_NAME" --jq '.object.sha' | |
| )" | |
| if [[ "$REF_OBJECT_TYPE" != tag ]]; then | |
| echo "::error::$REF_NAME must be an annotated tag" | |
| exit 1 | |
| fi | |
| TAG_TARGET_TYPE="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.object.type' | |
| )" | |
| TAG_TARGET_SHA="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.object.sha' | |
| )" | |
| TAG_VERIFIED="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.verification.verified' | |
| )" | |
| COMMIT_VERIFIED="$( | |
| gh api "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA" --jq '.commit.verification.verified' | |
| )" | |
| if [[ "$TAG_TARGET_TYPE" != commit || "$TAG_TARGET_SHA" != "$GITHUB_SHA" ]]; then | |
| echo "::error::Tag $REF_NAME does not point directly to the workflow commit" | |
| exit 1 | |
| fi | |
| if [[ "$TAG_VERIFIED" != true || "$COMMIT_VERIFIED" != true ]]; then | |
| echo "::error::The release commit and annotated tag must both have verified signatures" | |
| exit 1 | |
| fi | |
| { | |
| echo "package_name=$PACKAGE_NAME" | |
| echo "tag_object_sha=$TAG_OBJECT_SHA" | |
| echo "version=$VERSION" | |
| } >> "$GITHUB_OUTPUT" | |
| prebuild-mac-win: | |
| name: Build ${{ matrix.target }} from the release tag | |
| needs: validate | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: darwin-x64 | |
| runner: macos-15-intel | |
| - target: darwin-arm64 | |
| runner: macos-14 | |
| - target: win32-x64 | |
| runner: windows-latest | |
| - target: win32-arm64 | |
| runner: windows-11-arm | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - name: Checkout the release tag | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Install the release Node.js toolchain | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: 24.19.0 | |
| package-manager-cache: false | |
| - run: npm ci --ignore-scripts | |
| - run: npm run build:native | |
| - name: Upload the prebuild | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: prebuild-${{ matrix.target }} | |
| path: prebuilds/ | |
| if-no-files-found: error | |
| retention-days: 1 | |
| - run: git diff --exit-code | |
| prebuild-linux-glibc: | |
| name: Build linux-${{ matrix.arch }}-glibc from the release tag | |
| needs: validate | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: x64 | |
| runner: ubuntu-24.04 | |
| - arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - name: Checkout the release tag | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Install the release Node.js toolchain | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: 24.19.0 | |
| package-manager-cache: false | |
| - run: npm ci --ignore-scripts | |
| - name: Build in Debian 11 for glibc 2.31 compatibility | |
| env: | |
| TARGET_ARCH: ${{ matrix.arch }} | |
| run: npm run build:native:linux | |
| - name: Upload the prebuild | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: prebuild-linux-${{ matrix.arch }}-glibc | |
| path: prebuilds/ | |
| if-no-files-found: error | |
| retention-days: 1 | |
| - run: git diff --exit-code | |
| prebuild-linux-musl: | |
| name: Build linux-${{ matrix.arch }}-musl from the release tag | |
| needs: validate | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: x64 | |
| runner: ubuntu-24.04 | |
| platform: linux/amd64 | |
| - arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| platform: linux/arm64 | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - name: Checkout the release tag | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Build in Alpine Linux | |
| env: | |
| DOCKER_PLATFORM: ${{ matrix.platform }} | |
| run: | | |
| docker run --rm \ | |
| -v "$PWD:/tmp/project" \ | |
| --entrypoint /bin/sh \ | |
| --platform "$DOCKER_PLATFORM" \ | |
| node:22-alpine \ | |
| -c 'apk add build-base git python3 py3-setuptools --update-cache && cd /tmp/project && npm ci --ignore-scripts && npm run build:native' | |
| - name: Upload the prebuild | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: prebuild-linux-${{ matrix.arch }}-musl | |
| path: prebuilds/ | |
| if-no-files-found: error | |
| retention-days: 1 | |
| - run: git diff --exit-code | |
| pack: | |
| name: Build and pack the exact release | |
| needs: | |
| - validate | |
| - prebuild-mac-win | |
| - prebuild-linux-glibc | |
| - prebuild-linux-musl | |
| runs-on: ubuntu-24.04 | |
| env: | |
| EXPECTED_PACKAGE_NAME: ${{ needs.validate.outputs.package_name }} | |
| EXPECTED_VERSION: ${{ needs.validate.outputs.version }} | |
| steps: | |
| - name: Checkout the release tag | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Install the release Node.js toolchain | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| # Node.js 24.19.0 bundles npm 11.17.0; the floor check below is what enforces the minimum. | |
| node-version: 24.19.0 | |
| package-manager-cache: false | |
| - name: Verify the release npm version | |
| run: node scripts/verify-npm-version.mjs 11.10.0 | |
| - run: npm ci --ignore-scripts | |
| - name: Download exact-tag prebuilds | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: prebuild-* | |
| path: ./prebuilds | |
| merge-multiple: true | |
| - name: Verify that all eight prebuilds arrived | |
| run: npm run release:verify-prebuilds -- --project-root . | |
| - name: Build JavaScript and type declarations | |
| run: npm run build:dist | |
| - name: Pack and inventory the package | |
| run: | | |
| npm run release:pack-package -- \ | |
| --project-root . \ | |
| --artifact-dir package-artifact \ | |
| --expected-name "$EXPECTED_PACKAGE_NAME" \ | |
| --expected-version "$EXPECTED_VERSION" | |
| - run: git diff --exit-code | |
| - name: Upload the exact package | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: npm-package-${{ github.ref_name }} | |
| path: package-artifact/ | |
| if-no-files-found: error | |
| retention-days: 1 | |
| verify-package-mac-win: | |
| name: Test packed package on Node.js ${{ matrix.node-version }} / ${{ matrix.os }} | |
| needs: pack | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [macos-15-intel, macos-14, windows-latest, windows-11-arm] | |
| node-version: [22, 24, 26] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Install the package-test toolchain | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| # Node.js 24.19.0 bundles npm 11.17.0; the floor check below is what enforces the minimum. | |
| node-version: 24.19.0 | |
| package-manager-cache: false | |
| - name: Verify the package-test npm version | |
| run: node scripts/verify-npm-version.mjs 11.10.0 | |
| - run: npm ci --ignore-scripts | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: npm-package-${{ github.ref_name }} | |
| path: package-artifact/ | |
| - name: Install the packed package with the dependency age gate | |
| # The exact release tarball is the subject under test. | |
| run: | # zizmor: ignore[adhoc-packages] | |
| npm run release:install-package -- \ | |
| --project-root . \ | |
| --artifact-dir package-artifact \ | |
| --install-root package-install | |
| - name: Install the target Node.js runtime | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| package-manager-cache: false | |
| - name: Load the packed package | |
| run: | | |
| npm run release:load-package -- \ | |
| --project-root . \ | |
| --install-root package-install | |
| - run: git diff --exit-code | |
| verify-package-ubuntu: | |
| name: Test packed package on Node.js ${{ matrix.node-version }} / ${{ matrix.os }} ${{ matrix.arch }} | |
| needs: pack | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-22.04, ubuntu-24.04] | |
| arch: [x64, arm64] | |
| node-version: [22, 24, 26] | |
| runs-on: ${{ matrix.arch == 'arm64' && format('{0}-arm', matrix.os) || matrix.os }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Install the package-test toolchain | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| # Node.js 24.19.0 bundles npm 11.17.0; the floor check below is what enforces the minimum. | |
| node-version: 24.19.0 | |
| package-manager-cache: false | |
| - name: Verify the package-test npm version | |
| run: node scripts/verify-npm-version.mjs 11.10.0 | |
| - run: npm ci --ignore-scripts | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: npm-package-${{ github.ref_name }} | |
| path: package-artifact/ | |
| - name: Install the packed package with the dependency age gate | |
| # The exact release tarball is the subject under test. | |
| run: | # zizmor: ignore[adhoc-packages] | |
| npm run release:install-package -- \ | |
| --project-root . \ | |
| --artifact-dir package-artifact \ | |
| --install-root package-install | |
| - name: Install the target Node.js runtime | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| package-manager-cache: false | |
| - name: Load the packed package | |
| run: | | |
| npm run release:load-package -- \ | |
| --project-root . \ | |
| --install-root package-install | |
| - run: git diff --exit-code | |
| verify-package-alpine: | |
| name: Test packed package on Node.js ${{ matrix.node-version }} / Alpine ${{ matrix.arch }} | |
| needs: pack | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| arch: [x64, arm64] | |
| node-version: [22, 24, 26] | |
| include: | |
| - arch: x64 | |
| runner: ubuntu-24.04 | |
| platform: linux/amd64 | |
| - arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| platform: linux/arm64 | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: npm-package-${{ github.ref_name }} | |
| path: package-artifact/ | |
| - name: Install the packed package with the dependency age gate | |
| env: | |
| DOCKER_PLATFORM: ${{ matrix.platform }} | |
| run: | | |
| docker run --rm \ | |
| -v "$PWD:/tmp/project" \ | |
| --entrypoint /bin/sh \ | |
| --platform "$DOCKER_PLATFORM" \ | |
| node:24.19.0-alpine \ | |
| -c 'cd /tmp/project && node scripts/verify-npm-version.mjs 11.10.0 && npm ci --ignore-scripts && npm run release:install-package -- --project-root . --artifact-dir package-artifact --install-root package-install' | |
| - name: Load the packed package on the target Node.js runtime | |
| env: | |
| DOCKER_PLATFORM: ${{ matrix.platform }} | |
| NODE_VERSION: ${{ matrix.node-version }} | |
| run: | | |
| docker run --rm \ | |
| -v "$PWD:/tmp/project" \ | |
| --entrypoint /bin/sh \ | |
| --platform "$DOCKER_PLATFORM" \ | |
| "node:${NODE_VERSION}-alpine" \ | |
| -c 'cd /tmp/project && npm run release:load-package -- --project-root . --install-root package-install' | |
| - run: git diff --exit-code | |
| stage: | |
| name: Stage package on npm | |
| needs: | |
| - validate | |
| - pack | |
| - verify-package-mac-win | |
| - verify-package-ubuntu | |
| - verify-package-alpine | |
| runs-on: ubuntu-24.04 | |
| env: | |
| EXPECTED_PACKAGE_NAME: ${{ needs.validate.outputs.package_name }} | |
| EXPECTED_TAG_OBJECT_SHA: ${{ needs.validate.outputs.tag_object_sha }} | |
| EXPECTED_VERSION: ${{ needs.validate.outputs.version }} | |
| permissions: | |
| contents: read | |
| id-token: write # Authenticate npm Trusted Publishing with OIDC. | |
| steps: | |
| # This job deliberately has no checkout, no cache, no project dependency | |
| # install, no repository secret, and no third-party action: it is the only | |
| # job that can publish, so it runs nothing from the repository. | |
| - name: Download the exact package | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: npm-package-${{ github.ref_name }} | |
| path: package-artifact/ | |
| - name: Install the release Node.js toolchain | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| # Node.js 24.19.0 bundles npm 11.17.0; the floor check below is what enforces the minimum. | |
| node-version: 24.19.0 | |
| package-manager-cache: false | |
| registry-url: https://registry.npmjs.org | |
| - name: Verify the release npm version | |
| env: | |
| MIN_NPM_VERSION: "11.15.0" | |
| run: | | |
| # Every other lane calls scripts/verify-npm-version.mjs. This job has | |
| # no checkout by design, so its floor check has to be self-contained. | |
| NPM_VERSION="$(npm --version)" | |
| if ! node -e ' | |
| const parse = (v) => /^(\d{1,9})\.(\d{1,9})\.(\d{1,9})/.exec(v).slice(1, 4).map(Number); | |
| const [reqMajor, reqMinor, reqPatch] = parse(process.env.MIN_NPM_VERSION); | |
| const [major, minor, patch] = parse(process.argv[1]); | |
| process.exit( | |
| major > reqMajor || | |
| (major === reqMajor && | |
| (minor > reqMinor || (minor === reqMinor && patch >= reqPatch))) | |
| ? 0 | |
| : 1, | |
| ); | |
| ' "$NPM_VERSION"; then | |
| echo "::error::npm $MIN_NPM_VERSION or later is required for staged publishing, but this toolchain has $NPM_VERSION" | |
| exit 1 | |
| fi | |
| - name: Stage the npm package | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| # download-artifact already verified this artifact's digest. What is | |
| # left to check is identity: that the one tarball here is the package | |
| # this tag promised. | |
| TARBALL_COUNT="$(find package-artifact -maxdepth 1 -type f -name '*.tgz' | wc -l)" | |
| if [[ "$TARBALL_COUNT" -ne 1 ]]; then | |
| echo "::error::Expected exactly one package tarball, found $TARBALL_COUNT" | |
| exit 1 | |
| fi | |
| PACK_FILENAME="$(node -e ' | |
| const { readFileSync } = require("node:fs") | |
| const entries = JSON.parse(readFileSync("package-artifact/PACK.json", "utf8")) | |
| if (entries.length !== 1) throw new Error("Expected one pack record, found " + entries.length) | |
| const entry = entries[0] | |
| if (entry.name !== process.env.EXPECTED_PACKAGE_NAME || | |
| entry.version !== process.env.EXPECTED_VERSION) { | |
| throw new Error("Unexpected pack identity: " + entry.name + "@" + entry.version) | |
| } | |
| process.stdout.write(entry.filename) | |
| ')" | |
| TARBALL="package-artifact/$PACK_FILENAME" | |
| if [[ ! -f "$TARBALL" ]]; then | |
| echo "::error::Pack record names $PACK_FILENAME, which is not here" | |
| exit 1 | |
| fi | |
| MANIFEST_PATH="$RUNNER_TEMP/packed-package.json" | |
| tar -xOf "$TARBALL" package/package.json > "$MANIFEST_PATH" | |
| MANIFEST_PATH="$MANIFEST_PATH" node -e ' | |
| const { readFileSync } = require("node:fs") | |
| const pkg = JSON.parse(readFileSync(process.env.MANIFEST_PATH, "utf8")) | |
| if (pkg.name !== process.env.EXPECTED_PACKAGE_NAME || | |
| pkg.version !== process.env.EXPECTED_VERSION) { | |
| throw new Error("Unexpected packed manifest: " + pkg.name + "@" + pkg.version) | |
| } | |
| ' | |
| REF_OBJECT_TYPE="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$REF_NAME" --jq '.object.type' | |
| )" | |
| TAG_OBJECT_SHA="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$REF_NAME" --jq '.object.sha' | |
| )" | |
| TAG_TARGET_TYPE="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.object.type' | |
| )" | |
| TAG_TARGET_SHA="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.object.sha' | |
| )" | |
| TAG_VERIFIED="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.verification.verified' | |
| )" | |
| COMMIT_VERIFIED="$( | |
| gh api "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA" --jq '.commit.verification.verified' | |
| )" | |
| if [[ "$REF_OBJECT_TYPE" != tag || \ | |
| "$TAG_OBJECT_SHA" != "$EXPECTED_TAG_OBJECT_SHA" || \ | |
| "$TAG_TARGET_TYPE" != commit || "$TAG_TARGET_SHA" != "$GITHUB_SHA" || \ | |
| "$TAG_VERIFIED" != true || "$COMMIT_VERIFIED" != true ]]; then | |
| echo "::error::Tag $REF_NAME moved or lost its verified release identity" | |
| exit 1 | |
| fi | |
| npm stage publish "./$TARBALL" --ignore-scripts | |
| github-release: | |
| name: Create immutable GitHub release | |
| needs: | |
| - validate | |
| - stage | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: write # Create the immutable release for the signed tag. | |
| steps: | |
| - name: Create GitHub release | |
| env: | |
| EXPECTED_TAG_OBJECT_SHA: ${{ needs.validate.outputs.tag_object_sha }} | |
| GH_TOKEN: ${{ github.token }} | |
| TAG: ${{ github.ref_name }} | |
| run: | | |
| REF_OBJECT_TYPE="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$TAG" --jq '.object.type' | |
| )" | |
| TAG_OBJECT_SHA="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$TAG" --jq '.object.sha' | |
| )" | |
| TAG_TARGET_TYPE="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.object.type' | |
| )" | |
| TAG_TARGET_SHA="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.object.sha' | |
| )" | |
| TAG_VERIFIED="$( | |
| gh api "repos/$GITHUB_REPOSITORY/git/tags/$TAG_OBJECT_SHA" --jq '.verification.verified' | |
| )" | |
| COMMIT_VERIFIED="$( | |
| gh api "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA" --jq '.commit.verification.verified' | |
| )" | |
| if [[ "$REF_OBJECT_TYPE" != tag || "$TAG_TARGET_TYPE" != commit || \ | |
| "$TAG_OBJECT_SHA" != "$EXPECTED_TAG_OBJECT_SHA" || \ | |
| "$TAG_TARGET_SHA" != "$GITHUB_SHA" || "$TAG_VERIFIED" != true || \ | |
| "$COMMIT_VERIFIED" != true ]]; then | |
| echo "::error::Tag $TAG moved or lost its verified release identity" | |
| exit 1 | |
| fi | |
| gh release create "$TAG" \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --verify-tag \ | |
| --generate-notes |