Release Extension #14
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: 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 |