name: Build and Release APK # Build an APK and publish it as a GitHub Release whenever commits land on main # (for example when a pull request is merged). Can also be run manually. on: push: branches: [ main ] workflow_dispatch: inputs: first_deploy: description: "First Cloudflare deploy: skip carrying over the other channel (the site does not exist yet)" type: boolean default: false # Allow the built-in token to create releases and upload the APK. permissions: contents: write # Don't let two pushes to main race on the same release. concurrency: group: release-${{ github.ref }} cancel-in-progress: false jobs: build: name: Build APK and publish release # workflow_dispatch can be aimed at any branch from the Actions UI. Releases # are what the in-app updater installs, so only main may produce one — # anything else is a no-op rather than shipping unreviewed code to everyone. if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest outputs: version: ${{ steps.stage.outputs.version }} env: # Stamps the APK as a production-channel build, versioned with the run # number that matches the tag published below. PLG_CHANNEL: production steps: - name: Checkout uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: zulu java-version: '17' cache: gradle - name: Set up Android SDK uses: android-actions/setup-android@v4 - name: Build debug APK run: ./gradlew assembleDebug --no-daemon --stacktrace - name: Stage APK for release id: stage run: | set -euo pipefail # The series comes from gradle.properties, which is the same file the # build read when it stamped the APK — so the tag and what is inside # it cannot name different versions. series="$(sed -n 's/^plgVersionSeries=//p' gradle.properties)" test -n "$series" offset="$(sed -n 's/^plgVersionRunOffset=//p' gradle.properties)" test -n "$offset" # Same arithmetic as build.gradle.kts, so the tag names the APK's own number. version="v${series}.$(( ${{ github.run_number }} + offset ))" src="app/build/outputs/apk/debug/app-debug.apk" dest="ProLibertateGames-${version}.apk" cp "$src" "$dest" # The same build again under a name that never changes. GitHub's # /releases/latest/download/ redirect needs a constant file # name, so this second copy is what makes a permanent download link # possible — the versioned copy stays as the traceable one. cp "$src" "ProLibertateGames.apk" echo "version=$version" >> "$GITHUB_OUTPUT" echo "apk=$dest" >> "$GITHUB_OUTPUT" - name: Upload APK as workflow artifact uses: actions/upload-artifact@v4 with: name: plg-prod-staged path: ${{ steps.stage.outputs.apk }} if-no-files-found: error # Publishes the build to https://plg.wallacenet.ca (Cloudflare Pages), which is # the only release channel: the in-app updater reads latest.json from there. # # Both workflows deploy into one Pages site, and a deploy replaces the whole # site, so they share a concurrency group and never run at the same time. deploy-pages: name: Deploy to Cloudflare Pages needs: build if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest concurrency: group: plg-pages-deploy cancel-in-progress: false steps: - name: Checkout uses: actions/checkout@v4 - name: Download staged APK uses: actions/download-artifact@v4 with: name: plg-prod-staged path: staged - name: Assemble site env: PLG_SKIP_OTHER: ${{ inputs.first_deploy && '1' || '' }} run: .github/scripts/stage-pages-site.sh prod "${{ needs.build.outputs.version }}" "staged/ProLibertateGames-${{ needs.build.outputs.version }}.apk" - name: Deploy env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} run: | set -euo pipefail # Creates the project on first run; fails harmlessly if it exists. npx --yes wrangler@3 pages project create plg --production-branch main || true # --branch main makes this the production deployment, which is what # plg.wallacenet.ca serves, whichever branch the workflow ran on. npx --yes wrangler@3 pages deploy pages-out --project-name plg --branch main --commit-dirty=true