mirror of
https://github.com/tiennm99/loto.git
synced 2026-10-12 14:15:05 +00:00
188 lines
5.8 KiB
YAML
188 lines
5.8 KiB
YAML
# 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
|