Files
proxyswitcher/.github/workflows/release.yml
T
wt e88fb193df
Build and publish extension / Build extension packages (push) Successful in 50s
Build and publish extension / Publish stores and attach release assets (push) Skipped
fix rsync
2026-10-09 16:38:53 +07:00

211 lines
7.8 KiB
YAML

name: Build and publish extension
on:
push:
branches:
- "**"
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: "Version to validate (for example 1.0.1)"
required: true
type: string
permissions:
contents: read
jobs:
build:
name: Build extension packages
runs-on: ubuntu-latest
steps:
- name: Check out source
uses: actions/checkout@v4
with:
ref: ${{ github.event.release.tag_name || github.ref }}
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Validate release version
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'
env:
RELEASE_VERSION: ${{ github.event.release.tag_name || inputs.version }}
run: |
python - <<'PY'
import json, os, re
expected = os.environ["RELEASE_VERSION"].removeprefix("v")
for path in ("manifest.json", "manifest.chrome.json"):
actual = json.load(open(path, encoding="utf-8"))["version"]
if actual != expected:
raise SystemExit(f"{path}: version {actual!r} does not match release {expected!r}")
if not re.fullmatch(r"\d+(\.\d+){1,3}", expected):
raise SystemExit(f"Release version must be numeric, got {expected!r}")
PY
- name: Install web-ext
run: npm install --global web-ext
- name: Prepare Firefox source
run: |
python - <<'PY'
from pathlib import Path
import shutil
source = Path('.')
target = Path('dist/firefox-source')
excluded = {'.git', '.github', 'dist', 'web-ext-artifacts', 'scripts',
'manifest.chrome.json', 'background-chrome.js',
'background-service-worker.js', 'browser-api.js'}
target.mkdir(parents=True, exist_ok=True)
for item in source.iterdir():
if item.name in excluded:
continue
destination = target / item.name
if item.is_dir():
shutil.copytree(item, destination, dirs_exist_ok=True)
else:
shutil.copy2(item, destination)
PY
- name: Build Firefox package
run: |
web-ext build \
--source-dir dist/firefox-source \
--artifacts-dir dist/firefox \
--filename proxyswitcherforkbywt-firefox.xpi \
--overwrite-dest
- name: Build Chrome package
run: python scripts/build-chrome.py
- name: Upload packages for this push
uses: actions/upload-artifact@v4
with:
name: extension-packages-${{ github.sha }}
if-no-files-found: error
path: |
dist/firefox/proxyswitcherforkbywt-firefox.xpi
web-ext-artifacts/proxyswitcherforkbywt-chrome.zip
publish:
name: Publish stores and attach release assets
if: github.event_name == 'release' && github.event.action == 'published'
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
env:
AMO_JWT_ISSUER: ${{ secrets.AMO_JWT_ISSUER }}
AMO_JWT_SECRET: ${{ secrets.AMO_JWT_SECRET }}
CWS_PUBLISHER_ID: ${{ secrets.CWS_PUBLISHER_ID }}
CWS_EXTENSION_ID: ${{ secrets.CWS_EXTENSION_ID }}
CWS_CLIENT_ID: ${{ secrets.CWS_CLIENT_ID }}
CWS_CLIENT_SECRET: ${{ secrets.CWS_CLIENT_SECRET }}
CWS_REFRESH_TOKEN: ${{ secrets.CWS_REFRESH_TOKEN }}
steps:
- name: Check out release source
uses: actions/checkout@v4
with:
ref: ${{ github.event.release.tag_name }}
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Download build packages
uses: actions/download-artifact@v4
with:
name: extension-packages-${{ github.sha }}
path: dist/packages
- name: Set up Firefox signing tools
run: |
npm install --global web-ext
python - <<'PY'
from pathlib import Path
import shutil
source = Path('.')
target = Path('dist/firefox-source')
excluded = {'.git', '.github', 'dist', 'web-ext-artifacts', 'scripts',
'manifest.chrome.json', 'background-chrome.js',
'background-service-worker.js', 'browser-api.js'}
target.mkdir(parents=True, exist_ok=True)
for item in source.iterdir():
if item.name in excluded:
continue
destination = target / item.name
if item.is_dir():
shutil.copytree(item, destination, dirs_exist_ok=True)
else:
shutil.copy2(item, destination)
PY
- name: Sign and submit Firefox package to AMO
run: |
test -n "$AMO_JWT_ISSUER" || { echo 'Missing AMO_JWT_ISSUER secret'; exit 1; }
test -n "$AMO_JWT_SECRET" || { echo 'Missing AMO_JWT_SECRET secret'; exit 1; }
web-ext sign \
--source-dir dist/firefox-source \
--artifacts-dir dist/firefox-signed \
--api-key "$AMO_JWT_ISSUER" \
--api-secret "$AMO_JWT_SECRET" \
--channel listed \
--approval-timeout 900000 \
--no-input
firefox_xpi=$(find dist/firefox-signed -maxdepth 1 -name '*.xpi' -print -quit)
test -n "$firefox_xpi" || { echo 'AMO did not return a signed XPI'; exit 1; }
cp "$firefox_xpi" dist/packages/proxyswitcherforkbywt-firefox-signed.xpi
- name: Upload Chrome package to Chrome Web Store
run: |
set -euo pipefail
for name in CWS_PUBLISHER_ID CWS_EXTENSION_ID CWS_CLIENT_ID CWS_CLIENT_SECRET CWS_REFRESH_TOKEN; do
test -n "${!name}" || { echo "Missing $name secret"; exit 1; }
done
token=$(curl --fail --silent --show-error \
--data-urlencode "client_id=$CWS_CLIENT_ID" \
--data-urlencode "client_secret=$CWS_CLIENT_SECRET" \
--data-urlencode "refresh_token=$CWS_REFRESH_TOKEN" \
--data-urlencode 'grant_type=refresh_token' \
https://oauth2.googleapis.com/token | python -c 'import json,sys; print(json.load(sys.stdin)["access_token"])')
chrome_zip=$(find dist/packages -name 'proxyswitcherforkbywt-chrome.zip' -print -quit)
test -f "$chrome_zip" || { echo "Missing Chrome package: $chrome_zip"; exit 1; }
curl --fail --silent --show-error \
-X POST \
-H "Authorization: Bearer $token" \
-H 'Content-Type: application/zip' \
--data-binary "@$chrome_zip" \
"https://chromewebstore.googleapis.com/upload/v2/publishers/$CWS_PUBLISHER_ID/items/$CWS_EXTENSION_ID:upload"
curl --fail --silent --show-error \
-X POST \
-H "Authorization: Bearer $token" \
"https://chromewebstore.googleapis.com/v2/publishers/$CWS_PUBLISHER_ID/items/$CWS_EXTENSION_ID:publish"
- name: Attach signed Firefox and Chrome packages to release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release upload "${{ github.event.release.tag_name }}" \
dist/packages/proxyswitcherforkbywt-firefox-signed.xpi \
"$chrome_zip" \
--clobber
- name: Upload signed packages as workflow artifacts
uses: actions/upload-artifact@v4
with:
name: signed-extension-packages-${{ github.event.release.tag_name }}
if-no-files-found: error
path: |
dist/packages/proxyswitcherforkbywt-firefox-signed.xpi
dist/packages/**/proxyswitcherforkbywt-chrome.zip