v1.3.0: bash whitelist + Write cwd-rewrite + image input + pi banner #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: Publish to npm | |
| # Fires whenever a tag matching v[0-9]* is pushed (e.g. v1.1.0, v1.2.0-rc1). | |
| # The workflow refuses to publish unless the tag matches package.json's | |
| # version, so a typo in either place is caught before anything reaches npm. | |
| on: | |
| push: | |
| tags: ['v[0-9]*'] | |
| jobs: | |
| publish: | |
| name: Publish on tag | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # required to create the GitHub Release | |
| id-token: write # required for npm provenance via GitHub OIDC | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| registry-url: 'https://registry.npmjs.org' | |
| cache: 'npm' | |
| - name: Verify tag matches package.json version | |
| run: | | |
| tag="${GITHUB_REF_NAME#v}" | |
| pkg=$(node -p "require('./package.json').version") | |
| if [ "$tag" != "$pkg" ]; then | |
| echo "::error::Tag $GITHUB_REF_NAME (=$tag) does not match package.json version $pkg" | |
| exit 1 | |
| fi | |
| echo "Tag and package.json agree on $pkg" | |
| - run: npm ci | |
| # Playwright is a runtime dep (browser-extract retention test runs a real | |
| # chromium against Wikipedia). `npm ci` installs the package but not the | |
| # browser binary; do that here. --with-deps brings the apt libs along. | |
| - name: Install Playwright chromium | |
| run: npx playwright install --with-deps chromium | |
| - run: npm test | |
| - run: npm run typecheck | |
| - name: Publish to npm with provenance | |
| run: npm publish --provenance --access public | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Extract CHANGELOG section for this version | |
| id: notes | |
| run: | | |
| version="${GITHUB_REF_NAME#v}" | |
| # Pull lines between "## [vX.Y.Z]" and the next "## [" header, | |
| # then trim trailing "---" separators / blank lines that | |
| # Keep-a-Changelog uses between sections. | |
| awk -v ver="$version" ' | |
| $0 ~ "^## \\[v" ver "\\]" { flag=1; next } | |
| flag && /^## \[/ { exit } | |
| flag { n++; lines[n] = $0 } | |
| END { | |
| while (n > 0 && (lines[n] == "---" || lines[n] ~ /^[[:space:]]*$/)) n-- | |
| for (i = 1; i <= n; i++) print lines[i] | |
| } | |
| ' CHANGELOG.md > /tmp/release-notes.md | |
| if [ ! -s /tmp/release-notes.md ]; then | |
| echo "::warning::No CHANGELOG section found for v$version — falling back to auto-generated notes" | |
| echo "fallback=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "fallback=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create GitHub Release (with CHANGELOG notes) | |
| if: steps.notes.outputs.fallback == 'false' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release create "$GITHUB_REF_NAME" \ | |
| --title "$GITHUB_REF_NAME" \ | |
| --notes-file /tmp/release-notes.md \ | |
| --latest \ | |
| --verify-tag | |
| - name: Create GitHub Release (auto-generated fallback) | |
| if: steps.notes.outputs.fallback == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release create "$GITHUB_REF_NAME" \ | |
| --title "$GITHUB_REF_NAME" \ | |
| --generate-notes \ | |
| --latest \ | |
| --verify-tag |