Skip to content

Release Extension

Release Extension #14

name: Release Extension
on:
workflow_dispatch:
inputs:
bump:
description: 'Version bump (major, minor, patch)'
required: true
type: choice
options:
- patch
- minor
- major
skip_tests:
description: 'Skip tests (for hotfixes only)'
required: false
default: false
type: boolean
permissions:
contents: write
jobs:
release:
name: Release Extension
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Bump version, commit, and tag
id: bump
run: |
NEW_VERSION=$(npm version "${{ inputs.bump }}" -m "chore: release v%s" --no-commit-hooks)
NEW_VERSION="${NEW_VERSION#v}"
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "tag=v$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Build for tests
if: ${{ !inputs.skip_tests }}
run: npm run build
- name: Verify manifests
if: ${{ !inputs.skip_tests }}
run: npm run verify:manifests
- name: Verify content-script bundle size
if: ${{ !inputs.skip_tests }}
run: npm run check:bundle-size
- name: Install Playwright (Chrome)
if: ${{ !inputs.skip_tests }}
run: npx playwright install chromium --with-deps
- name: Run Chrome E2E tests
if: ${{ !inputs.skip_tests }}
run: xvfb-run --auto-servernum --server-args='-screen 0 1920x1080x24' npm run test:e2e:chrome
env:
CI: true
- name: Install Playwright (Firefox)
if: ${{ !inputs.skip_tests }}
run: npx playwright install firefox --with-deps
- name: Run Firefox smoke test
if: ${{ !inputs.skip_tests }}
run: npm run test:e2e:firefox
env:
CI: true
- uses: actions/upload-artifact@v4
if: failure() && !inputs.skip_tests
with:
name: playwright-report
path: |
playwright-report/
test-results/
retention-days: 7
- name: Build and package extensions
run: |
npm run zip
npm run zip:firefox
- name: List zip outputs
run: |
ls -la .output
find .output -type f -name "*.zip" -print
- name: Resolve zip paths
id: zips
run: |
CHROME_ZIP=$(find .output -type f -name "*-chrome.zip" -print -quit)
FIREFOX_ZIP=$(find .output -type f -name "*-firefox.zip" -print -quit)
SOURCES_ZIP=$(find .output -type f -name "*-sources.zip" -print -quit)
if [ -z "$CHROME_ZIP" ] || [ -z "$FIREFOX_ZIP" ] || [ -z "$SOURCES_ZIP" ]; then
echo "Error: expected zip assets not found."
find .output -type f -name "*.zip" -print
exit 1
fi
echo "chrome=$CHROME_ZIP" >> $GITHUB_OUTPUT
echo "firefox=$FIREFOX_ZIP" >> $GITHUB_OUTPUT
echo "sources=$SOURCES_ZIP" >> $GITHUB_OUTPUT
- name: Validate manifest version matches bump
run: |
MANIFEST_PATH=".output/chrome-mv3/manifest.json"
FIREFOX_MANIFEST_PATH=".output/firefox-mv3/manifest.json"
if [ ! -f "$MANIFEST_PATH" ]; then
echo "Error: $MANIFEST_PATH not found. Build output is missing."
exit 1
fi
if [ ! -f "$FIREFOX_MANIFEST_PATH" ]; then
echo "Error: $FIREFOX_MANIFEST_PATH not found. Build output is missing."
exit 1
fi
MANIFEST_VERSION=$(jq -r '.version' "$MANIFEST_PATH")
FIREFOX_VERSION=$(jq -r '.version' "$FIREFOX_MANIFEST_PATH")
if [ -z "$MANIFEST_VERSION" ] || [ "$MANIFEST_VERSION" = "null" ]; then
echo "Error: version could not be resolved from manifest."
exit 1
fi
if [ -z "$FIREFOX_VERSION" ] || [ "$FIREFOX_VERSION" = "null" ]; then
echo "Error: version could not be resolved from Firefox manifest."
exit 1
fi
if [ "$MANIFEST_VERSION" != "${{ steps.bump.outputs.version }}" ]; then
echo "Error: manifest ($MANIFEST_VERSION) != bump (${{ steps.bump.outputs.version }})"
exit 1
fi
if [ "$FIREFOX_VERSION" != "${{ steps.bump.outputs.version }}" ]; then
echo "Error: firefox manifest ($FIREFOX_VERSION) != bump (${{ steps.bump.outputs.version }})"
exit 1
fi
- name: Generate release changelog
run: |
PREV_TAG=$(git tag --sort=-v:refname | grep '^v' | sed -n '2p')
{
echo "# Changelog"
echo
if [ -n "$PREV_TAG" ]; then
git log --no-merges --pretty=format:"- %s (%h)" "$PREV_TAG..HEAD"
else
git log --no-merges --pretty=format:"- %s (%h)"
fi
echo
} > release-notes.md
- name: Push version commit and tag
run: |
git push origin "HEAD:${GITHUB_REF_NAME}"
git push origin "${{ steps.bump.outputs.tag }}"
- uses: actions/upload-artifact@v4
with:
name: extension-${{ steps.bump.outputs.version }}
path: |
${{ steps.zips.outputs.chrome }}
${{ steps.zips.outputs.firefox }}
${{ steps.zips.outputs.sources }}
if-no-files-found: error
retention-days: 90
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.bump.outputs.tag }}
name: Release ${{ steps.bump.outputs.tag }}
files: |
${{ steps.zips.outputs.chrome }}
${{ steps.zips.outputs.firefox }}
${{ steps.zips.outputs.sources }}
body_path: release-notes.md