diff --git a/.github/workflows/reusable-update-dashboard.yml b/.github/workflows/reusable-update-dashboard.yml new file mode 100644 index 0000000000..15c01ade6e --- /dev/null +++ b/.github/workflows/reusable-update-dashboard.yml @@ -0,0 +1,70 @@ +name: "[Reusable] Update Release Dashboard" + +on: + workflow_call: + inputs: + environment: + description: "Target environment: production_ready | delivery_testing | production" + type: string + required: true + version: + description: "Version name (e.g. 2026.2.0)" + type: string + required: true + apk_url: + description: "Direct APK download URL" + type: string + required: false + default: "" + release_url: + description: "GitHub Release page URL" + type: string + required: false + default: "" + +permissions: + contents: write + +concurrency: + group: update-release-dashboard-gh-pages + cancel-in-progress: false + +jobs: + update: + runs-on: ubuntu-latest + + steps: + - name: Checkout gh-pages branch + uses: actions/checkout@v6 + with: + ref: gh-pages + + - name: Update status.json + env: + ENVIRONMENT: ${{ inputs.environment }} + VERSION: ${{ inputs.version }} + APK_URL: ${{ inputs.apk_url }} + RELEASE_URL: ${{ inputs.release_url }} + run: | + UPDATED_AT="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" + jq \ + --arg env "$ENVIRONMENT" \ + --arg version "$VERSION" \ + --arg updated_at "$UPDATED_AT" \ + --arg apk_url "$APK_URL" \ + --arg release_url "$RELEASE_URL" \ + '.[$env] = {version: $version, updated_at: $updated_at, apk_url: $apk_url, release_url: $release_url}' \ + status.json > status.json.tmp + mv status.json.tmp status.json + + - name: Commit and push + env: + ENVIRONMENT: ${{ inputs.environment }} + VERSION: ${{ inputs.version }} + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add status.json + git diff --cached --quiet && echo "No changes" && exit 0 + git commit -m "dashboard: update ${ENVIRONMENT} → ${VERSION}" + git push diff --git a/.github/workflows/sync-release-stage-versions.yml b/.github/workflows/sync-release-stage-versions.yml new file mode 100644 index 0000000000..297ad3bf7d --- /dev/null +++ b/.github/workflows/sync-release-stage-versions.yml @@ -0,0 +1,56 @@ +name: "Sync Release Stage Version Dropdown" +# Keeps the `version` choice list in update-release-stage.yml in sync with actual +# GitHub Release tags, since workflow_dispatch choice options must be static and +# can't be populated dynamically at trigger time. + +on: + release: + types: [published] + workflow_dispatch: {} + +permissions: + contents: write + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + ref: ${{ github.event.repository.default_branch }} + + - name: Regenerate version list + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + WORKFLOW_FILE=".github/workflows/update-release-stage.yml" + OPTIONS_FILE="$(mktemp)" + LIMIT=15 + + # Fetch published (non-draft) release tags, newest first by semantic version. + gh release list --repo "${{ github.repository }}" --limit 60 \ + --json tagName,isDraft \ + --jq '.[] | select(.isDraft==false) | .tagName' \ + | sed 's/^v//' \ + | sort -t. -k1,1nr -k2,2nr -k3,3nr \ + | head -n "$LIMIT" \ + | sed 's/^/ - /' > "$OPTIONS_FILE" + + # Replace the block between the marker comments with the freshly generated options. + awk -v optfile="$OPTIONS_FILE" ' + /# AUTO-GENERATED-VERSIONS-START/ { print; while ((getline line < optfile) > 0) print line; skip=1; next } + /# AUTO-GENERATED-VERSIONS-END/ { skip=0 } + skip != 1 { print } + ' "$WORKFLOW_FILE" > "$WORKFLOW_FILE.tmp" + mv "$WORKFLOW_FILE.tmp" "$WORKFLOW_FILE" + rm -f "$OPTIONS_FILE" + + - name: Commit and push + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add .github/workflows/update-release-stage.yml + git diff --cached --quiet && echo "No changes" && exit 0 + git commit -m "chore: sync release stage version dropdown" + git push diff --git a/.github/workflows/update-release-stage.yml b/.github/workflows/update-release-stage.yml new file mode 100644 index 0000000000..4fade6023b --- /dev/null +++ b/.github/workflows/update-release-stage.yml @@ -0,0 +1,74 @@ +name: "Promote Release Stage" +# Manually record that a version has reached Beta (Production Ready), Delivery Testing, or Production. +# Looks up the GitHub Release for that version to find the APK download URL automatically. + +on: + workflow_dispatch: + inputs: + stage: + description: "Stage to promote to" + type: choice + required: true + options: + - production_ready + - delivery_testing + - production + version: + description: "Version to promote" + type: choice + required: true + options: + # AUTO-GENERATED-VERSIONS-START (kept in sync by .github/workflows/sync-release-stage-versions.yml) + - 2026.2.1 + - 2026.2.0 + - 2026.1.0 + - 2025.4.2 + - 2025.4.0 + - 2025.3.1 + - 2025.3.0 + - 2025.2.1 + - 2025.2.0 + - 2025.1.0 + - 2024.2.2 + - 2024.2.1 + - 2024.2.0 + - 2024.1.5 + - 2024.1.4 + # AUTO-GENERATED-VERSIONS-END + +permissions: + contents: write + +jobs: + resolve-release-info: + runs-on: ubuntu-latest + outputs: + apk_url: ${{ steps.info.outputs.apk_url }} + release_url: ${{ steps.info.outputs.release_url }} + + steps: + - name: Resolve GitHub Release info + id: info + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ inputs.version }} + run: | + TAG="v${VERSION}" + RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/$TAG" + echo "release_url=$RELEASE_URL" >> "$GITHUB_OUTPUT" + + APK_URL=$(gh release view "$TAG" \ + --repo "${{ github.repository }}" \ + --json assets \ + --jq '[.assets[] | select(.name | endswith(".apk")) | .browserDownloadUrl] | first // ""' \ + 2>/dev/null || echo "") + echo "apk_url=$APK_URL" >> "$GITHUB_OUTPUT" + + update-dashboard: + needs: resolve-release-info + uses: ./.github/workflows/reusable-update-dashboard.yml + with: + environment: ${{ inputs.stage }} + version: ${{ inputs.version }} + apk_url: ${{ needs.resolve-release-info.outputs.apk_url }} + release_url: ${{ needs.resolve-release-info.outputs.release_url }}