diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..332958e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,91 @@ +# Creates a GitHub release automatically whenever a new version lands on main. +# +# How to release: bump "version" in src/manifest.json and package.json, add a +# "## ()" section to CHANGELOG.md, merge to main. This +# workflow then runs the tests, builds the Chrome zip and publishes the +# release "v" with that changelog section as release notes. +# If the tag already exists nothing happens, so other pushes to main are safe. +name: Release + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: release + cancel-in-progress: false + +jobs: + release: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Read version + id: version + run: | + VERSION=$(node -p "require('./src/manifest.json').version") + PKG=$(node -p "require('./package.json').version") + if [ "$VERSION" != "$PKG" ]; then + echo "::error::src/manifest.json ($VERSION) and package.json ($PKG) have different versions" + exit 1 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + if git ls-remote --exit-code --tags origin "refs/tags/v$VERSION" > /dev/null; then + echo "v$VERSION is already released, nothing to do." + echo "release=false" >> "$GITHUB_OUTPUT" + else + echo "release=true" >> "$GITHUB_OUTPUT" + fi + + - uses: actions/setup-node@v4 + if: steps.version.outputs.release == 'true' + with: + node-version: 22 + + - name: Run tests + if: steps.version.outputs.release == 'true' + run: | + npm install --no-save --no-audit --no-fund + npx playwright install chromium + npm test + + - name: Build Chrome zip + if: steps.version.outputs.release == 'true' + run: sh scripts/package-chrome.sh + + - name: Release notes from CHANGELOG.md + if: steps.version.outputs.release == 'true' + env: + VERSION: ${{ steps.version.outputs.version }} + run: | + awk -v v="$VERSION" ' + /^## / { if (found) exit; if (index($0, "## " v " ") == 1 || $0 == "## " v) { found = 1; next } } + found { print } + ' CHANGELOG.md > notes.md + if [ ! -s notes.md ]; then + echo "::warning::No CHANGELOG.md section for $VERSION, using a default text" + echo "GTA 6 Blocker $VERSION" > notes.md + fi + cat >> notes.md <<'EOF' + + ### Install + - **Chrome / Edge / Brave:** download the zip below, unzip it, open `chrome://extensions`, turn on Developer mode and click **Load unpacked**. + - **Safari:** build it on a Mac with `Build Safari Extension.command` (see the README). + EOF + cat notes.md + + - name: Publish release + if: steps.version.outputs.release == 'true' + env: + GH_TOKEN: ${{ github.token }} + VERSION: ${{ steps.version.outputs.version }} + run: | + gh release create "v$VERSION" "dist/gta6-blocker-chrome-$VERSION.zip" \ + --target "$GITHUB_SHA" \ + --title "GTA 6 Blocker $VERSION" \ + --notes-file notes.md diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8fc3ec2 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,22 @@ +# Runs the extension tests on every pull request, so a broken change is +# caught before it is merged (and before the release workflow picks it up). +name: Test + +on: + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: npm install --no-save --no-audit --no-fund + - run: npx playwright install chromium + - run: npm test diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3082211..8b42444 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,6 +24,18 @@ There is no bundler or build step on purpose: the code in `src/` is exactly what - Keep it dependency-free and compatible with both browsers: use the `ext` handle from `shared.js` (works as `browser` in Safari and `chrome` in Chromium), and only Manifest V3 APIs Safari supports. - No analytics, remote code or network requests. Privacy is a feature. +## Releasing + +Releases are created automatically by `.github/workflows/release.yml`: + +1. Bump `version` in `src/manifest.json` **and** `package.json` (they must match). +2. Add a `## ()` section at the top of `CHANGELOG.md`. +3. Merge to `main`. + +The workflow runs the tests, builds `gta6-blocker-chrome-.zip` and publishes the GitHub release `v` with the changelog section as notes. Pushes that don't change the version do nothing. Pull requests run the tests via `.github/workflows/test.yml`. + +The Safari app is not built in CI, because it has to be signed on a Mac. Build it locally and attach it to the release if you want to ship it. + ## Code style - Plain modern JavaScript, 2-space indent, single quotes, semicolons. diff --git a/scripts/package-chrome.ps1 b/scripts/package-chrome.ps1 index d2bcf86..814fd67 100644 --- a/scripts/package-chrome.ps1 +++ b/scripts/package-chrome.ps1 @@ -6,5 +6,5 @@ $dist = Join-Path $root "dist" New-Item -ItemType Directory -Force -Path $dist | Out-Null $out = Join-Path $dist ("gta6-blocker-chrome-" + $manifest.version + ".zip") if (Test-Path $out) { Remove-Item $out } -Compress-Archive -Path (Join-Path $root "src\*") -DestinationPath $out +Get-ChildItem (Join-Path $root "src") -Exclude "_metadata" | Compress-Archive -DestinationPath $out Write-Host "Created $out" diff --git a/scripts/package-chrome.sh b/scripts/package-chrome.sh index 4dbc25a..6e73c5e 100755 --- a/scripts/package-chrome.sh +++ b/scripts/package-chrome.sh @@ -5,5 +5,5 @@ cd "$(dirname "$0")/.." VERSION=$(sed -n 's/.*"version": *"\([^"]*\)".*/\1/p' src/manifest.json | head -n 1) mkdir -p dist OUT="dist/gta6-blocker-chrome-$VERSION.zip" -(cd src && zip -r -X "../$OUT" . -x "*.DS_Store" -x "icons/icon-512.png") +(cd src && zip -r -X "../$OUT" . -x "*.DS_Store" -x "icons/icon-512.png" -x "_metadata/*") echo "Created $OUT"