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: # 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: temurin 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" version="v${series}.${{ github.run_number }}" 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 - name: Create GitHub release env: GH_TOKEN: ${{ github.token }} run: | set -euo pipefail gh release create "${{ steps.stage.outputs.version }}" \ "${{ steps.stage.outputs.apk }}" \ "ProLibertateGames.apk" \ --repo "${{ github.repository }}" \ --target "${{ github.sha }}" \ --title "ProLibertateGames ${{ steps.stage.outputs.version }}" \ --notes "Automated release built from \`${{ github.sha }}\` on push to \`main\`. Download **${{ steps.stage.outputs.apk }}** below and install it on an Android device (you may need to allow *Install unknown apps*). This is a debug-signed build. Both files below are the same build. \`ProLibertateGames.apk\` is a copy under a fixed name, so this link always fetches the newest release and can be bookmarked or shared: https://github.com/${{ github.repository }}/releases/latest/download/ProLibertateGames.apk" # Publishes the build to https://plg.wallacenet.ca (Cloudflare Pages). Runs # alongside the GitHub release above for one deployment so already-installed # apps, which still read GitHub, can fetch the updater that reads Cloudflare. # # 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 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