Refresh usage data #11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Refresh usage data | |
| # Pulls GA4 (and the db-viz-hex query-log Sheet), commits the accumulated CSVs, | |
| # then builds and deploys — all in ONE workflow, deliberately. | |
| # | |
| # A push made with GITHUB_TOKEN does not trigger other workflows, so a | |
| # "commit here, let pages.yml deploy" split silently never deploys. (That is | |
| # exactly what happens today in CalCOFI/db-viz-station's refresh.yml, whose | |
| # data commits only reach the site when a human pushes afterwards.) | |
| # | |
| # GitHub drops most scheduled runs on public repos, so the cron below is a | |
| # fallback: the real daily trigger is a GCP Cloud Scheduler job POSTing | |
| # {"event_type":"analytics"} to this repo's dispatches API, mirroring | |
| # calcofi-uptime-dispatch. See OPERATIONS.md. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| backfill: | |
| description: "Pull everything GA4 still retains, not just the last 35 days" | |
| type: boolean | |
| default: false | |
| schedule: | |
| # Deliberately NOT the scheduler's 11:17 — when both fire in the same | |
| # minute the second run's `git push` races the first and goes red for no | |
| # reason. This is the fallback for a dead dispatcher, so it wants a | |
| # different time of day, not the same one. | |
| - cron: "47 23 * * *" # 15:47 PT | |
| repository_dispatch: | |
| types: [analytics] | |
| permissions: | |
| contents: write | |
| pages: write | |
| id-token: write | |
| concurrency: | |
| group: pages | |
| cancel-in-progress: false | |
| jobs: | |
| refresh: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: scripts/requirements.txt | |
| - run: pip install -r scripts/requirements.txt | |
| - name: Pull GA4 + Sheet, rebuild site data | |
| env: | |
| GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} | |
| USAGE_SHEET_ID: ${{ secrets.USAGE_SHEET_ID }} | |
| run: | | |
| python3 scripts/refresh.py ${{ inputs.backfill && '--backfill' || '' }} | |
| # always(): a partially-successful pull (one property misconfigured) still | |
| # produced real data for the other — keep it, and let the red run be what | |
| # signals that something needs fixing | |
| - name: Commit if changed | |
| if: always() | |
| run: | | |
| git config user.name "calcofi-bot" | |
| git config user.email "bot@calcofi.io" | |
| git add static/data data content/products | |
| if git diff --cached --quiet; then | |
| echo "no usage changes" | |
| else | |
| # NO [skip ci]: the build job below is what publishes this commit | |
| git commit -m "data: refresh usage from GA4" | |
| # rebase before pushing: a human commit (or a second refresh run) | |
| # landing mid-job otherwise rejects this push and loses the pull | |
| git pull --rebase --autostash origin "${GITHUB_REF_NAME}" || true | |
| git push | |
| fi | |
| build: | |
| needs: refresh | |
| # publish whatever landed, even if one property failed — see above | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.ref }} # pick up the commit the refresh job just pushed | |
| fetch-depth: 0 | |
| - run: git pull --ff-only || true | |
| - uses: peaceiris/actions-hugo@v3 | |
| with: | |
| hugo-version: "0.163.3" | |
| extended: true | |
| - uses: actions/configure-pages@v5 | |
| - run: hugo --gc --minify | |
| - uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: ./public | |
| deploy: | |
| needs: build | |
| # `needs: build` is NOT enough: a job's implicit condition is success(), | |
| # which evaluates over every ANCESTOR — so a failed `refresh` skipped this | |
| # deploy even though `build` succeeded, and the freshly-committed data sat | |
| # in the repo unpublished. Publish whatever built; the red run is the signal. | |
| if: always() && needs.build.result == 'success' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| steps: | |
| - id: deployment | |
| uses: actions/deploy-pages@v4 |