Manage releases #4
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
| # .github/workflows/manage-releases.yml | |
| # Copyright (C) 2005-2026 Giorgio Maone <https://maone.net> | |
| # | |
| # SPDX-License-Identifier: GPL-3.0-or-later | |
| # Triggered by *1984 tags pushed by tools/deploy2tor.sh. | |
| # | |
| # For the current tag: | |
| # - Creates a GitHub Release named after the regular version (no 1984 suffix) | |
| # - Attaches the XPI from dist.torproject.org (always present) | |
| # - Attaches the AMO XPI from secure.informaction.com (if already uploaded) | |
| # - Attaches the Chrome ZIP from secure.informaction.com (if already uploaded) | |
| # | |
| # Additionally, for pre-release tags only: | |
| # - Derives the corresponding stable version (strips trailing .9xx from VER) | |
| # and finds its GitHub release | |
| # - If it is missing the AMO XPI, checks informaction.com and uploads | |
| # it if now available | |
| # | |
| # Required secrets: only the automatic GITHUB_TOKEN. | |
| name: Manage releases | |
| on: | |
| push: | |
| tags: | |
| - '*1984' | |
| workflow_dispatch: | |
| inputs: | |
| tor_tag: | |
| description: 'Tag to process (e.g., 13.5.0.1984)' | |
| required: true | |
| jobs: | |
| release: | |
| name: Create / update current release | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| outputs: | |
| version: ${{ steps.meta.outputs.version }} | |
| prerelease: ${{ steps.meta.outputs.prerelease }} | |
| steps: | |
| - name: Derive version and pre-release flag | |
| id: meta | |
| run: | | |
| # Use workflow_dispatch input if provided, otherwise use the pushed tag | |
| TOR_TAG="${{ github.event.inputs.tor_tag || github.ref_name }}" | |
| echo "tor_tag=${TOR_TAG}" >> "$GITHUB_OUTPUT" | |
| # Strip the Tor suffix to obtain the regular version. | |
| # Stable: 13.6.15.1984 → 13.6.15 (strip .1984) | |
| # Pre: 13.6.15.90101984 → 13.6.15.901 (strip 01984) | |
| # Both cases share "01984" at the tail; stable also has a leading dot. | |
| VER="${TOR_TAG%01984}" | |
| VER="${VER%.1984}" | |
| echo "version=${VER}" >> "$GITHUB_OUTPUT" | |
| # Stable = suffix is exactly ".1984" or ".01984"; anything else is pre. | |
| SUFFIX="${TOR_TAG#"${VER}"}" | |
| if [[ "$SUFFIX" =~ ^\.0?1984$ ]]; then | |
| echo "prerelease=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "prerelease=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Extract changelog | |
| id: changelog | |
| env: | |
| VER: ${{ steps.meta.outputs.version }} | |
| PRERELEASE: ${{ steps.meta.outputs.prerelease }} | |
| run: | | |
| VER_SHORT="${VER%.0}" | |
| VER_SHORTER="${VER_SHORT%.0}" | |
| REG_TAG="" | |
| for candidate in "$VER" "v$VER" "$VER_SHORT" "v$VER_SHORT" \ | |
| "$VER_SHORTER" "v$VER_SHORTER"; do | |
| if git tag --points-at "$candidate" >/dev/null 2>&1; then | |
| REG_TAG="$candidate" | |
| break | |
| fi | |
| done | |
| if [[ -z "$REG_TAG" ]]; then | |
| echo "No regular tag found on this commit for '$VER'; changelog will be empty." >&2 | |
| touch /tmp/changelog.md | |
| else | |
| if [[ "$PRERELEASE" == "true" ]]; then | |
| # Pre-release: extract from tag annotation | |
| git tag -l --format='%(contents)' "$REG_TAG" > /tmp/changelog.md | |
| echo "Using annotation from tag '$REG_TAG'." | |
| else | |
| # Extract the version from REG_TAG (remove leading 'v' if present) | |
| CHANGELOG_VER="${REG_TAG#v}" | |
| echo "Fetching changelog for stable release ${CHANGELOG_VER} from noscript.net..." | |
| CHANGELOG_VER_ESCAPED="${CHANGELOG_VER//./\.}" | |
| curl -L "https://noscript.net/changelog" | \ | |
| grep -A1000 "v $CHANGELOG_VER_ESCAPED$" | \ | |
| grep -m1 -B1000 '^$' > /tmp/changelog.md | |
| fi | |
| fi | |
| - name: Download XPI from dist.torproject.org | |
| id: tor_xpi | |
| env: | |
| TOR_TAG: ${{ steps.meta.outputs.tor_tag }} | |
| run: | | |
| FILE="noscript-${TOR_TAG}.xpi" | |
| URL="https://dist.torproject.org/torbrowser/noscript/${FILE}" | |
| echo "Downloading ${URL}" | |
| curl -fsSL --retry 3 -o "$FILE" "$URL" | |
| ls -lh "$FILE" | |
| echo "file=${FILE}" >> "$GITHUB_OUTPUT" | |
| echo "label=${FILE}#auto-updated from torproject.org" >> "$GITHUB_OUTPUT" | |
| - name: Download AMO XPI from informaction.com | |
| id: amo_xpi | |
| env: | |
| VER: ${{ steps.meta.outputs.version }} | |
| PRERELEASE: ${{ steps.meta.outputs.prerelease }} | |
| run: | | |
| FILE="noscript-${VER}.xpi" | |
| if [[ "$PRERELEASE" == "true" ]]; then | |
| SUBPATH="betas" | |
| LABEL_SOURCE="mozilla.org" | |
| else | |
| SUBPATH="releases" | |
| LABEL_SOURCE="informaction.com" | |
| fi | |
| URL="https://secure.informaction.com/download/${SUBPATH}/${FILE}" | |
| echo "Trying ${URL}" | |
| if curl -fsSL --retry 3 -o "$FILE" "$URL" 2>/dev/null; then | |
| ls -lh "$FILE" | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| echo "file=${FILE}" >> "$GITHUB_OUTPUT" | |
| echo "label=${FILE}#auto-updated from ${LABEL_SOURCE}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "AMO XPI not yet available at ${URL}, skipping." | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download Chrome ZIP from informaction.com | |
| id: chrome_zip | |
| env: | |
| VER: ${{ steps.meta.outputs.version }} | |
| PRERELEASE: ${{ steps.meta.outputs.prerelease }} | |
| run: | | |
| FILE="noscript-${VER}-chrome.zip" | |
| if [[ "$PRERELEASE" == "true" ]]; then | |
| SUBPATH="betas" | |
| else | |
| SUBPATH="releases" | |
| fi | |
| URL="https://secure.informaction.com/download/${SUBPATH}/${FILE}" | |
| echo "Trying ${URL}" | |
| if curl -fsSL --retry 3 -o "$FILE" "$URL" 2>/dev/null; then | |
| ls -lh "$FILE" | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| echo "file=${FILE}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Chrome ZIP not yet available at ${URL}, skipping." | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create / update GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.meta.outputs.tor_tag }} | |
| name: ${{ steps.meta.outputs.version }} | |
| prerelease: ${{ steps.meta.outputs.prerelease }} | |
| body_path: /tmp/changelog.md | |
| files: | | |
| ${{ steps.tor_xpi.outputs.file }} | |
| ${{ steps.amo_xpi.outputs.found == 'true' && steps.amo_xpi.outputs.file || '' }} | |
| ${{ steps.chrome_zip.outputs.found == 'true' && steps.chrome_zip.outputs.file || '' }} | |
| # ── Backfill AMO XPI on the corresponding stable release ───────────────── | |
| # | |
| # Only runs for pre-release tags. For a tag like 13.5.2.90101984, VER is | |
| # "13.5.2.901" — the trailing .9xx is stripped to derive the stable base | |
| # version "13.5.2", whose release is then checked and patched if needed. | |
| # Stable tags are excluded because the release job already handles attaching | |
| # the AMO XPI (if available) at creation time. | |
| backfill-stable-amo: | |
| name: Backfill AMO XPI on corresponding stable release | |
| needs: release | |
| if: needs.release.outputs.prerelease == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Check and backfill AMO XPI if missing | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| VER: ${{ needs.release.outputs.version }} | |
| PRERELEASE: ${{ needs.release.outputs.prerelease }} | |
| run: | | |
| # Derive the stable base version: | |
| # - stable tag (13.5.2.1984) → VER=13.5.2 → STABLE_VER=13.5.2 | |
| # - pre tag (13.5.2.90101984) → VER=13.5.2.901 → STABLE_VER=13.5.2 | |
| # Strip any trailing .9xx component to reach the stable version. | |
| LAST_COMPONENT="${VER##*.}" | |
| if [[ "$LAST_COMPONENT" =~ ^9[0-9]{2,}$ ]]; then | |
| STABLE_VER="${VER%.*}" | |
| else | |
| STABLE_VER="$VER" | |
| fi | |
| echo "Stable base version to check: ${STABLE_VER}" | |
| # Find the GitHub release whose name matches STABLE_VER. | |
| STABLE_TAG=$(gh release list \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --limit 100 \ | |
| --json tagName,name,isPrerelease \ | |
| --jq \ | |
| --arg sv "$STABLE_VER" \ | |
| '[.[] | select(.isPrerelease == false) | |
| | select(.name == $sv)] | first | .tagName' \ | |
| 2>/dev/null || true) | |
| if [[ -z "$STABLE_TAG" || "$STABLE_TAG" == "null" ]]; then | |
| echo "No stable GitHub release found for version '${STABLE_VER}', nothing to backfill." | |
| exit 0 | |
| fi | |
| echo "Stable release tag: ${STABLE_TAG}" | |
| # Check whether it already has the AMO XPI asset. | |
| HAS_AMO=$(gh release view "$STABLE_TAG" \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --json assets \ | |
| --jq \ | |
| --arg f "noscript-${STABLE_VER}.xpi" \ | |
| '.assets[] | select(.name == $f) | .name' \ | |
| 2>/dev/null || true) | |
| if [[ -n "$HAS_AMO" ]]; then | |
| echo "Release '${STABLE_TAG}' already has the AMO XPI, nothing to do." | |
| exit 0 | |
| fi | |
| FILE="noscript-${STABLE_VER}.xpi" | |
| URL="https://secure.informaction.com/download/releases/${FILE}" | |
| echo "AMO XPI missing from '${STABLE_TAG}', checking ${URL} ..." | |
| if curl -fsSL --retry 3 -o "$FILE" "$URL" 2>/dev/null; then | |
| ls -lh "$FILE" | |
| gh release upload "$STABLE_TAG" "$FILE" \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --clobber | |
| echo "Uploaded ${FILE} to release ${STABLE_TAG}." | |
| else | |
| echo "AMO XPI for '${STABLE_VER}' not yet available at ${URL}, skipping." | |
| fi |