v1.0.0 #8
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: publish | |
| on: | |
| push: | |
| tags: ['v*'] | |
| permissions: | |
| id-token: write # npm Trusted Publishing OIDC | |
| contents: write # GitHub Release creation | |
| concurrency: | |
| group: publish | |
| cancel-in-progress: false | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22.14.0' | |
| registry-url: https://registry.npmjs.org | |
| - name: Use npm with Trusted Publishing support | |
| run: npm install -g npm@^11.5.1 | |
| - name: Verify tag matches package.json version | |
| run: | | |
| set -eo pipefail | |
| TAG_VERSION="${GITHUB_REF_NAME#v}" | |
| PKG_VERSION="$(node -p 'require("./package.json").version')" | |
| if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then | |
| echo "::error::Tag v${TAG_VERSION} does not match package.json version ${PKG_VERSION}" | |
| exit 1 | |
| fi | |
| - name: Verify publishable file set | |
| run: | | |
| set -eo pipefail | |
| PACK_JSON="$(npm pack --dry-run --json)" | |
| PACK_JSON="${PACK_JSON}" node <<'NODE' | |
| const data = JSON.parse(process.env.PACK_JSON) | |
| const files = data[0].files.map((file) => file.path).sort() | |
| const expected = [ | |
| 'CHANGELOG.md', | |
| 'LICENSE', | |
| 'README.md', | |
| 'bin/appfigures', | |
| 'dist/af.js', | |
| 'package.json', | |
| ] | |
| if (JSON.stringify(files) !== JSON.stringify(expected)) { | |
| console.error(`Expected npm pack files ${JSON.stringify(expected)}, got ${JSON.stringify(files)}`) | |
| process.exit(1) | |
| } | |
| NODE | |
| - name: Extract release notes | |
| run: | | |
| set -eo pipefail | |
| node - "${GITHUB_REF_NAME#v}" > release-notes.md <<'NODE' | |
| const fs = require('fs') | |
| const version = process.argv[2] | |
| const content = fs.readFileSync('CHANGELOG.md', 'utf8') | |
| const escaped = version.replace(/[.+*?^$(){}|[\]\\]/g, '\\$&') | |
| const headerRe = new RegExp(`^## \\[${escaped}\\]`) | |
| const nextHeaderRe = /^## \[/ | |
| const captured = [] | |
| let inSection = false | |
| for (const line of content.split('\n')) { | |
| if (inSection && nextHeaderRe.test(line)) break | |
| if (headerRe.test(line)) { | |
| inSection = true | |
| continue | |
| } | |
| if (inSection) captured.push(line) | |
| } | |
| if (!inSection) { | |
| console.error(`No CHANGELOG section found for version ${version}`) | |
| process.exit(1) | |
| } | |
| process.stdout.write(captured.join('\n').trim() + '\n') | |
| NODE | |
| - name: Publish to npm | |
| run: | | |
| set -eo pipefail | |
| NAME="$(node -p 'require("./package.json").name')" | |
| VERSION="$(node -p 'require("./package.json").version')" | |
| TAG="$(node -e 'const version = process.argv[1]; const match = version.match(/^\d+\.\d+\.\d+-([0-9A-Za-z]+)/); if (match) process.stdout.write(match[1]);' "${VERSION}")" | |
| if npm view "${NAME}@${VERSION}" version >/dev/null 2>&1; then | |
| echo "${NAME}@${VERSION} is already published; skipping npm publish" | |
| exit 0 | |
| fi | |
| if [ -n "$TAG" ]; then | |
| npm publish --tag "$TAG" | |
| else | |
| npm publish | |
| fi | |
| - name: Create GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -eo pipefail | |
| if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then | |
| echo "Release ${GITHUB_REF_NAME} already exists; skipping" | |
| exit 0 | |
| fi | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| gh release create "${GITHUB_REF_NAME}" \ | |
| --title "@appfigures/cli v${VERSION}" \ | |
| --notes-file release-notes.md |