|
14 | 14 | types: [ labeled, opened, synchronize, reopened ] |
15 | 15 |
|
16 | 16 | jobs: |
17 | | - # Warm LFS cache once, generate a stable .lfs-assets-id with LF endings, and save it as an artifact |
18 | | - WarmLfs: |
| 17 | + # Warm up LFS cache once, on a single runner, and compute a stable cache key |
| 18 | + WarmLFS: |
19 | 19 | runs-on: ubuntu-latest |
20 | | - steps: |
21 | | - - name: Git Config |
22 | | - shell: bash |
23 | | - run: | |
24 | | - git config --global core.autocrlf false |
25 | | - git config --global core.longpaths true |
26 | 20 |
|
27 | | - - name: Git Checkout |
28 | | - uses: actions/checkout@v4 |
| 21 | + # Expose the computed cache key so matrix jobs can use it |
| 22 | + outputs: |
| 23 | + lfs_key: ${{ steps.compute-key.outputs.lfs_key }} |
| 24 | + |
| 25 | + steps: |
| 26 | + # Checkout repo with full history and submodules so we can see all LFS files |
| 27 | + - uses: actions/checkout@v4 |
29 | 28 | with: |
30 | 29 | fetch-depth: 0 |
31 | 30 | submodules: recursive |
32 | 31 |
|
33 | | - # Generate the LFS id list once and normalise to LF so hashFiles() matches across OS |
34 | | - - name: Git Create LFS FileList |
| 32 | + # Create a deterministic list of LFS object IDs: |
| 33 | + # - `git lfs ls-files -l` lists all tracked LFS objects with their SHA-256 |
| 34 | + # - `awk '{print $1}'` extracts just the SHA field |
| 35 | + # - `sort` sorts in byte order (hex hashes sort the same everywhere) |
| 36 | + # This ensures the file content is identical regardless of OS or locale |
| 37 | + - name: Git Create LFS id list |
35 | 38 | shell: bash |
36 | | - run: git lfs ls-files -l | cut -d' ' -f1 | sort | tr -d '\r' > .lfs-assets-id |
| 39 | + run: git lfs ls-files -l | awk '{print $1}' | sort > .lfs-assets-id |
37 | 40 |
|
| 41 | + # Compute a stable cache key by hashing the list file itself. |
| 42 | + # This guarantees the same key across all OSes and all matrix jobs. |
| 43 | + - name: Git Compute LFS cache key |
| 44 | + id: compute-key |
| 45 | + shell: bash |
| 46 | + run: | |
| 47 | + # sha256sum outputs "<hash> <filename>" |
| 48 | + KEY_HASH=$(sha256sum .lfs-assets-id | awk '{print $1}') |
| 49 | + echo "lfs_key=lfs-${KEY_HASH}-v1" >> "$GITHUB_OUTPUT" |
| 50 | +
|
| 51 | + # Restore or populate the cache for .git/lfs using the computed key |
38 | 52 | - name: Git Setup LFS Cache |
39 | 53 | uses: actions/cache@v4 |
40 | | - id: lfs-cache |
41 | 54 | with: |
42 | 55 | path: .git/lfs |
43 | | - key: lfs-${{ hashFiles('.lfs-assets-id') }}-v1 |
| 56 | + key: ${{ steps.compute-key.outputs.lfs_key }} |
44 | 57 |
|
| 58 | + # Ensure all LFS files for this commit are present locally |
45 | 59 | - name: Git Pull LFS |
46 | 60 | shell: bash |
47 | 61 | run: git lfs pull |
48 | 62 |
|
49 | 63 | Build: |
50 | | - needs: WarmLfs # Ensure the cache and id file exist before starting the matrix |
| 64 | + needs: WarmLFS # Ensure the cache and id file exist before starting the matrix |
51 | 65 | strategy: |
52 | 66 | matrix: |
53 | 67 | isARM: |
@@ -124,10 +138,12 @@ jobs: |
124 | 138 | fetch-depth: 0 |
125 | 139 | submodules: recursive |
126 | 140 |
|
127 | | - # Each job restores the now-primed cache, and pulls only if needed |
128 | | - - name: Git Create LFS FileList |
129 | | - shell: bash |
130 | | - run: git lfs ls-files -l | cut -d' ' -f1 | sort | tr -d '\r' > .lfs-assets-id |
| 141 | + # Use the *exact same key* computed in WarmLFS to restore the warmed cache. |
| 142 | + # This avoids regenerating the key per-OS and ensures all matrix jobs hit the same cache. |
| 143 | + - uses: actions/cache@v4 |
| 144 | + with: |
| 145 | + path: .git/lfs |
| 146 | + key: ${{ needs.WarmLFS.outputs.lfs_key }} |
131 | 147 |
|
132 | 148 | - name: Git Setup LFS Cache |
133 | 149 | uses: actions/cache@v4 |
|
0 commit comments