|
| 1 | +# Shared Flutter toolchain setup for the analyze_and_test jobs. Both jobs pay |
| 2 | +# this prefix (checks needs generated code for analyze/tests; integration needs |
| 3 | +# it to build the app), so it lives here to keep the two copies from drifting. |
| 4 | +# |
| 5 | +# Cache notes: keys derive from lockfiles, so they self-invalidate when deps |
| 6 | +# change. When both parallel jobs miss the same key (lockfile just changed), |
| 7 | +# both build and both try to save — the first save wins, the second logs a |
| 8 | +# benign "cache already exists" warning. No restore-keys on the pub cache on |
| 9 | +# purpose: it holds the bull_sdk git clone, and a fuzzy fallback can restore a |
| 10 | +# checkout from an OLDER lock whose pinned commit differs; pub then resolves |
| 11 | +# against that stale clone and `pub get --enforce-lockfile` fails wanting to |
| 12 | +# drop deps. The exact key already pins the commit via pubspec.lock. |
| 13 | +name: Flutter setup |
| 14 | +description: FVM + pub caches, FVM install, deps, build_runner, translations |
| 15 | + |
| 16 | +inputs: |
| 17 | + cargo-cache: |
| 18 | + description: Also restore the Cargo cache (only the integration job compiles the FRB native crates) |
| 19 | + required: false |
| 20 | + default: 'false' |
| 21 | + |
| 22 | +runs: |
| 23 | + using: composite |
| 24 | + steps: |
| 25 | + # runner.arch is in the FVM key because the SDK is native binaries — an |
| 26 | + # x64 SDK restored on an arm64 runner is broken. pub/cargo caches hold |
| 27 | + # sources only (arch-independent), so they keep os-only keys and stay |
| 28 | + # shared across arches. |
| 29 | + - name: Cache Flutter SDK (FVM) |
| 30 | + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 |
| 31 | + with: |
| 32 | + path: ~/fvm/versions |
| 33 | + key: fvm-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.fvmrc') }} |
| 34 | + |
| 35 | + - name: Cache pub (hosted + git deps) |
| 36 | + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 |
| 37 | + with: |
| 38 | + path: ~/.pub-cache |
| 39 | + key: pub-${{ runner.os }}-${{ hashFiles('pubspec.lock') }} |
| 40 | + |
| 41 | + - name: Cache Cargo (FRB native crates) |
| 42 | + if: ${{ inputs.cargo-cache == 'true' }} |
| 43 | + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 |
| 44 | + with: |
| 45 | + path: | |
| 46 | + ~/.cargo/registry |
| 47 | + ~/.cargo/git |
| 48 | + key: cargo-${{ runner.os }}-${{ hashFiles('pubspec.lock') }} |
| 49 | + restore-keys: cargo-${{ runner.os }}- |
| 50 | + |
| 51 | + - name: Install FVM |
| 52 | + shell: bash |
| 53 | + run: | |
| 54 | + case "$(uname -m)" in |
| 55 | + x86_64) fvm_arch=x64 ;; |
| 56 | + aarch64|arm64) fvm_arch=arm64 ;; |
| 57 | + *) echo "Unsupported FVM architecture: $(uname -m)" >&2; exit 1 ;; |
| 58 | + esac |
| 59 | + archive="$RUNNER_TEMP/fvm-4.1.2-linux-${fvm_arch}.tar.gz" |
| 60 | + curl --retry 5 --retry-all-errors -fL \ |
| 61 | + "https://github.com/conceptadev/fvm/releases/download/4.1.2/fvm-4.1.2-linux-${fvm_arch}.tar.gz" \ |
| 62 | + -o "$archive" |
| 63 | + mkdir -p "$HOME/fvm/bin" |
| 64 | + # Extract the whole tree, not just `fvm/fvm`: the two release archives |
| 65 | + # have different layouts. x64 ships a self-contained binary, arm64 a |
| 66 | + # launcher script that execs `src/dart` relative to its own directory — |
| 67 | + # unpacking the launcher alone yields `exec: .../src/dart: not found` |
| 68 | + # on every fvm invocation. |
| 69 | + tar -xzf "$archive" -C "$HOME/fvm/bin" --strip-components=1 |
| 70 | + chmod +x "$HOME/fvm/bin/fvm" |
| 71 | + if [ -f "$HOME/fvm/bin/src/dart" ]; then |
| 72 | + chmod +x "$HOME/fvm/bin/src/dart" |
| 73 | + fi |
| 74 | + # Prove the launcher actually runs before anything depends on it. |
| 75 | + "$HOME/fvm/bin/fvm" --version |
| 76 | + echo "$HOME/fvm/bin" >> $GITHUB_PATH |
| 77 | +
|
| 78 | + - name: Check Flutter version |
| 79 | + shell: bash |
| 80 | + run: make fvm-check |
| 81 | + |
| 82 | + - name: Get dependencies |
| 83 | + shell: bash |
| 84 | + run: make deps |
| 85 | + |
| 86 | + # build_runner's incremental cache — RESTORE ONLY. PR jobs never save (a sha-keyed save per push would blow the 10GB repo cache quota and evict the FVM/pub/cargo caches); only the cache-warmer workflow saves, on develop pushes, so all PRs restore develop's latest warm snapshot. |
| 87 | + # ALL gitignored generated source files are cached alongside .dart_tool/build so the restored state is self-consistent (outputs present + asset graph present); build_runner hashes inputs itself and regenerates what changed. |
| 88 | + # The suffix list MUST cover every gitignored to-source output: build_runner trusts .dart_tool/build and will NOT regenerate an output whose file is missing from disk (it reports "N skipped"), so a suffix left out here is silently absent after restore and breaks the build — that is how the missing assets.gen.dart (flutter_gen, *.gen.dart ≠ *.g.dart) incident happened. |
| 89 | + # *.gr.dart / *.config.dart match nothing today but are pre-listed to mirror the format-filter regex (makefile format-check), so adding auto_route/injectable later cannot reproduce the incident; *.steps.dart is deliberately NOT cached — drift schema snapshots are git-tracked, and restoring a tracked file would overwrite the checkout (same reason main.directories.g.dart is excluded below). |
| 90 | + # Arch is in the key defensively: the build cache holds kernel/asset hashes we don't want shared across arches. |
| 91 | + # The key embeds hashFiles of this action and the warmer workflow, so any edit to either file self-busts the cache instead of restoring a stale pre-edit snapshot — no manual version token to bump (this replaced the short-lived -v2- token). |
| 92 | + # Keep path + key in sync with the save step in cache-warmer.yml. |
| 93 | + - name: Restore build_runner cache |
| 94 | + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 |
| 95 | + with: |
| 96 | + path: | |
| 97 | + .dart_tool/build |
| 98 | + **/*.g.dart |
| 99 | + **/*.freezed.dart |
| 100 | + **/*.mocks.dart |
| 101 | + **/*.gen.dart |
| 102 | + **/*.gr.dart |
| 103 | + **/*.config.dart |
| 104 | + !packages/bull_ui_catalogue/lib/main.directories.g.dart |
| 105 | + key: buildrunner-${{ hashFiles('.github/actions/flutter-setup/action.yml', '.github/workflows/cache-warmer.yml') }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pubspec.lock') }}-${{ github.sha }} |
| 106 | + restore-keys: buildrunner-${{ hashFiles('.github/actions/flutter-setup/action.yml', '.github/workflows/cache-warmer.yml') }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pubspec.lock') }}- |
| 107 | + |
| 108 | + - name: Generate code (build_runner) |
| 109 | + shell: bash |
| 110 | + run: make build-runner |
| 111 | + |
| 112 | + - name: Generate translations |
| 113 | + shell: bash |
| 114 | + run: make translations |
| 115 | + |
| 116 | + - name: Disk telemetry (for trimming free-disk later) |
| 117 | + shell: bash |
| 118 | + run: df -h / |
0 commit comments