# One pipeline for both subprojects, because they ship from the same commit. # # The web app is built twice and only twice — once per base path — and every # consumer downloads an artifact instead of rebuilding: # # build (root, base "") -> deploy-firebase, preview-firebase # build (gh, base /loto) -> deploy-pages # # The Android app is native Kotlin/Compose and builds independently of the # web bundle (it mounts web/static/audio straight from the checkout). # Tags are handled by android-release.yml, which builds standalone. name: ci # Actions' parser rejects YAML anchors, so the two path lists are duplicated # by necessity — keep them identical. on: pull_request: paths: - 'web/**' - 'android/**' - '.github/actions/**' - '.github/workflows/ci.yml' push: branches: [main] paths: - 'web/**' - 'android/**' - '.github/actions/**' - '.github/workflows/ci.yml' workflow_dispatch: permissions: contents: read concurrency: group: ci-${{ github.ref }} # Superseded PRs are safe to kill; a main run may be mid-deploy. cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: ./.github/actions/setup-web - run: npm run lint working-directory: web - run: npm run check working-directory: web - run: npm test working-directory: web build: # Nothing is built, shipped or signed unless the suite is green. needs: test runs-on: ubuntu-latest strategy: matrix: include: # Firebase and the APK serve from a domain root. - profile: root script: build artifact: web-build buildProfile: '' # GitHub Pages serves under /loto. - profile: gh script: 'build:gh' artifact: web-build-gh buildProfile: gh name: build (${{ matrix.profile }}) steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: ./.github/actions/setup-web - run: npm run ${{ matrix.script }} working-directory: web # Fails the build if the SW registration wiring or the audio precache # base-path prefixing regresses — see scripts/verify-pwa-build.mjs. - run: npm run verify:pwa working-directory: web env: BUILD_PROFILE: ${{ matrix.buildProfile }} - uses: actions/upload-artifact@v7 with: name: ${{ matrix.artifact }} path: web/build # Hand-off within this run only; releases keep their own copies. retention-days: 1 deploy-pages: if: github.event_name != 'pull_request' needs: build runs-on: ubuntu-latest permissions: contents: read pages: write id-token: write # Guards the shared Pages environment against runs of other workflows. concurrency: group: github-pages cancel-in-progress: true environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - uses: actions/download-artifact@v7 with: name: web-build-gh path: build - uses: actions/configure-pages@v6 - uses: actions/upload-pages-artifact@v5 with: path: build - id: deployment uses: actions/deploy-pages@v5 deploy-firebase: if: github.event_name != 'pull_request' needs: build runs-on: ubuntu-latest concurrency: group: firebase-hosting-live cancel-in-progress: false steps: # entryPoint below reads web/firebase.json and web/.firebaserc. - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/download-artifact@v7 with: name: web-build # firebase.json declares `public: "build"`, relative to entryPoint. path: web/build - uses: FirebaseExtended/action-hosting-deploy@500ac625ca2dd40cbd15f7659af953801858032a # v0 with: repoToken: ${{ secrets.GITHUB_TOKEN }} firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_LOOTOO }} channelId: live projectId: lootoo entryPoint: web preview-firebase: # Forks cannot read the service account, so skip rather than fail. if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository needs: build runs-on: ubuntu-latest permissions: checks: write contents: read pull-requests: write steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/download-artifact@v7 with: name: web-build path: web/build - uses: FirebaseExtended/action-hosting-deploy@500ac625ca2dd40cbd15f7659af953801858032a # v0 with: repoToken: ${{ secrets.GITHUB_TOKEN }} firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_LOOTOO }} projectId: lootoo entryPoint: web android-debug: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: ./.github/actions/setup-android # assembleRelease runs R8 with no secrets needed (unsigned without # LOTO_KEYSTORE_PATH) so a missing keep rule fails CI, not the tag. - name: Lint, test and assemble debug + release APKs run: ./gradlew :app:lint :app:test :app:assembleDebug :app:assembleRelease working-directory: android - uses: actions/upload-artifact@v7 with: name: app-debug.apk path: android/app/build/outputs/apk/debug/*.apk archive: false retention-days: 7