From cbb56f6a618b95af6afd52b58e8383a722c69df3 Mon Sep 17 00:00:00 2001 From: Keith Williams Date: Sat, 10 Jan 2026 09:46:21 -0300 Subject: [PATCH] feat: implement git checkout caching to speed up CI workflows (#26636) * feat: implement git checkout caching to speed up CI workflows - Create cache-checkout action to save/restore git working directory - Update prepare job in pr.yml to cache checkout after dangerous-git-checkout - Update all downstream workflows to restore from cache instead of checkout - Pass commit-sha to all workflow calls for cache key consistency This reduces the number of full git checkouts from 20+ per workflow run to just 1, significantly improving CI performance especially for large repos. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor: use actions/cache/restore directly instead of custom action Remove sparse-checkout and use actions/cache/restore@v4 directly in all downstream workflows. This eliminates the need for any git fetch operation before restoring from cache, making the optimization more effective. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor: use github.event.pull_request.head.sha for cache key - Remove commit-sha input from all downstream workflows - Update cache-checkout action to use github.event.pull_request.head.sha directly - Remove commit-sha output from prepare job - Remove commit-sha from all workflow calls in pr.yml - Keep sparse-checkout of .github to access the cache-checkout action This eliminates the need to pass commit-sha around while still using a reusable action for the cache restore logic. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: update cache key to include branch name and add cache cleanup Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: use github.head_ref and github.sha for cache key Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: add prefix delete before saving cache to clear previous caches Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * perf: add sparse-checkout to exclude example-apps and mp4 files Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: restore get_sha step and commit-sha output that was accidentally removed Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: add trailing dash to cache key prefix to prevent accidental deletion of other branches' caches The prefix-based cache deletion was using 'git-checkout-{branch}' which would accidentally match and delete caches for branches with similar prefixes. For example, branch 'feature' would delete caches for 'feature-2', 'feature-new', etc. Adding a trailing '-' ensures exact branch matching: - 'git-checkout-feature-' matches 'git-checkout-feature-abc123' (intended) - 'git-checkout-feature-' does NOT match 'git-checkout-feature-2-def456' (correct) Fixes both the cache-checkout action and the PR close cleanup workflow. Co-Authored-By: unknown <> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .github/actions/cache-checkout/action.yml | 40 +++++++++++++++++++ .../actions/dangerous-git-checkout/action.yml | 5 +++ .github/workflows/api-v1-production-build.yml | 6 ++- .github/workflows/api-v2-production-build.yml | 6 ++- .github/workflows/api-v2-unit-tests.yml | 6 ++- .github/workflows/atoms-production-build.yml | 6 ++- .../check-api-v2-breaking-changes.yml | 6 ++- .github/workflows/check-types.yml | 6 ++- .github/workflows/companion-build.yml | 6 ++- .github/workflows/delete-blacksmith-cache.yml | 10 +++++ .github/workflows/docs-build.yml | 6 ++- .github/workflows/e2e-api-v2.yml | 6 ++- .github/workflows/e2e-app-store.yml | 6 ++- .github/workflows/e2e-embed-react.yml | 6 ++- .github/workflows/e2e-embed.yml | 6 ++- .github/workflows/e2e.yml | 6 ++- .github/workflows/integration-tests.yml | 6 ++- .github/workflows/lint.yml | 6 ++- .github/workflows/pr.yml | 4 ++ .../production-build-without-database.yml | 6 ++- .github/workflows/setup-db.yml | 6 ++- .github/workflows/unit-tests.yml | 6 ++- 22 files changed, 149 insertions(+), 18 deletions(-) create mode 100644 .github/actions/cache-checkout/action.yml diff --git a/.github/actions/cache-checkout/action.yml b/.github/actions/cache-checkout/action.yml new file mode 100644 index 0000000000..514d8e4c00 --- /dev/null +++ b/.github/actions/cache-checkout/action.yml @@ -0,0 +1,40 @@ +name: Cache Git Checkout +description: "Save or restore git checkout from cache to speed up CI workflows" +inputs: + mode: + description: "Mode of operation: 'save' to cache the checkout, 'restore' to restore from cache" + required: true + +runs: + using: "composite" + steps: + - name: Restore git checkout from cache + if: ${{ inputs.mode == 'restore' }} + uses: actions/cache/restore@v4 + id: cache-restore + with: + path: | + . + !.git + !node_modules + !**/node_modules + key: git-checkout-${{ github.head_ref || github.ref_name }}-${{ github.sha }} + fail-on-cache-miss: true + + - name: Delete previous git-checkout caches for this branch + if: ${{ inputs.mode == 'save' }} + uses: useblacksmith/cache-delete@v1 + with: + key: git-checkout-${{ github.head_ref || github.ref_name }}- + prefix: "true" + + - name: Save git checkout to cache + if: ${{ inputs.mode == 'save' }} + uses: actions/cache/save@v4 + with: + path: | + . + !.git + !node_modules + !**/node_modules + key: git-checkout-${{ github.head_ref || github.ref_name }}-${{ github.sha }} diff --git a/.github/actions/dangerous-git-checkout/action.yml b/.github/actions/dangerous-git-checkout/action.yml index c2dccc4e29..6a3dd50f87 100644 --- a/.github/actions/dangerous-git-checkout/action.yml +++ b/.github/actions/dangerous-git-checkout/action.yml @@ -8,3 +8,8 @@ runs: with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 2 + sparse-checkout-cone-mode: false + sparse-checkout: | + /* + !/example-apps/ + !**/*.mp4 diff --git a/.github/workflows/api-v1-production-build.yml b/.github/workflows/api-v1-production-build.yml index 26d08fa9e8..380340d37d 100644 --- a/.github/workflows/api-v1-production-build.yml +++ b/.github/workflows/api-v1-production-build.yml @@ -65,7 +65,11 @@ jobs: - 5432:5432 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - uses: ./.github/actions/cache-db - name: Cache API v1 production build diff --git a/.github/workflows/api-v2-production-build.yml b/.github/workflows/api-v2-production-build.yml index 177199661f..2d2e9cb472 100644 --- a/.github/workflows/api-v2-production-build.yml +++ b/.github/workflows/api-v2-production-build.yml @@ -35,7 +35,11 @@ jobs: - 5432:5432 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - name: Generate Prisma schemas working-directory: apps/api/v2 diff --git a/.github/workflows/api-v2-unit-tests.yml b/.github/workflows/api-v2-unit-tests.yml index 5c6fd7b69c..bc33f8b4a8 100644 --- a/.github/workflows/api-v2-unit-tests.yml +++ b/.github/workflows/api-v2-unit-tests.yml @@ -12,7 +12,11 @@ jobs: runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - run: yarn prisma generate - name: Run API v2 unit tests diff --git a/.github/workflows/atoms-production-build.yml b/.github/workflows/atoms-production-build.yml index b8fc029acc..ef6f9a4210 100644 --- a/.github/workflows/atoms-production-build.yml +++ b/.github/workflows/atoms-production-build.yml @@ -12,7 +12,11 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - name: Cache atoms production build uses: actions/cache@v4 diff --git a/.github/workflows/check-api-v2-breaking-changes.yml b/.github/workflows/check-api-v2-breaking-changes.yml index b41d3b719b..270f0bd08c 100644 --- a/.github/workflows/check-api-v2-breaking-changes.yml +++ b/.github/workflows/check-api-v2-breaking-changes.yml @@ -34,7 +34,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - name: Generate Swagger diff --git a/.github/workflows/check-types.yml b/.github/workflows/check-types.yml index f640b75d96..bd2da47672 100644 --- a/.github/workflows/check-types.yml +++ b/.github/workflows/check-types.yml @@ -12,7 +12,11 @@ jobs: runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - name: Show info run: node -e "console.log(require('v8').getHeapStatistics())" diff --git a/.github/workflows/companion-build.yml b/.github/workflows/companion-build.yml index 12985b43eb..58cd1be35d 100644 --- a/.github/workflows/companion-build.yml +++ b/.github/workflows/companion-build.yml @@ -17,7 +17,11 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - name: Setup Bun uses: oven-sh/setup-bun@v1 diff --git a/.github/workflows/delete-blacksmith-cache.yml b/.github/workflows/delete-blacksmith-cache.yml index 26addc991f..5a84df5f48 100644 --- a/.github/workflows/delete-blacksmith-cache.yml +++ b/.github/workflows/delete-blacksmith-cache.yml @@ -31,3 +31,13 @@ jobs: with: key: ${{ env.CACHE_NAME }}-${{ github.event.pull_request.head.ref }} prefix: "true" + + delete-git-checkout-cache-on-pr-close: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: blacksmith-2vcpu-ubuntu-2404 + steps: + - name: Delete git-checkout cache + uses: useblacksmith/cache-delete@v1 + with: + key: git-checkout-${{ github.event.pull_request.head.ref }}- + prefix: "true" diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index ccf44ed8a6..6e869ff753 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -12,7 +12,11 @@ jobs: runs-on: blacksmith-2vcpu-ubuntu-2404 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - name: Cache Docs build uses: actions/cache@v4 id: cache-docs-build diff --git a/.github/workflows/e2e-api-v2.yml b/.github/workflows/e2e-api-v2.yml index 267c6baf95..9656c4b473 100644 --- a/.github/workflows/e2e-api-v2.yml +++ b/.github/workflows/e2e-api-v2.yml @@ -74,7 +74,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - uses: ./.github/actions/cache-db - name: Build platform packages with Turbo diff --git a/.github/workflows/e2e-app-store.yml b/.github/workflows/e2e-app-store.yml index e3e1774c80..d7bede4762 100644 --- a/.github/workflows/e2e-app-store.yml +++ b/.github/workflows/e2e-app-store.yml @@ -81,7 +81,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - uses: ./.github/actions/yarn-playwright-install - run: yarn prisma generate diff --git a/.github/workflows/e2e-embed-react.yml b/.github/workflows/e2e-embed-react.yml index a58cac8484..5ece5472a7 100644 --- a/.github/workflows/e2e-embed-react.yml +++ b/.github/workflows/e2e-embed-react.yml @@ -73,7 +73,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - uses: ./.github/actions/yarn-playwright-install - run: yarn prisma generate diff --git a/.github/workflows/e2e-embed.yml b/.github/workflows/e2e-embed.yml index c3b9b5e3c6..eec3307fc3 100644 --- a/.github/workflows/e2e-embed.yml +++ b/.github/workflows/e2e-embed.yml @@ -81,7 +81,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - uses: ./.github/actions/yarn-playwright-install - run: yarn prisma generate diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 54a20cb066..8495fef823 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -82,7 +82,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - uses: ./.github/actions/yarn-playwright-install - run: yarn prisma generate diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 83605ea5cc..1ea8425853 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -79,7 +79,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - run: yarn prisma generate - uses: ./.github/actions/cache-db diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 76dd0d24a4..a141c1579f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,7 +10,11 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - name: Run Lint run: yarn lint diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 3a05287fdf..b99abd9df8 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -175,6 +175,10 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ./.github/actions/dangerous-git-checkout + - name: Cache git checkout + uses: ./.github/actions/cache-checkout + with: + mode: save - name: Generate DB cache key id: cache-db-key uses: ./.github/actions/cache-db-key diff --git a/.github/workflows/production-build-without-database.yml b/.github/workflows/production-build-without-database.yml index 78920c5fb6..512efe6ac7 100644 --- a/.github/workflows/production-build-without-database.yml +++ b/.github/workflows/production-build-without-database.yml @@ -43,7 +43,11 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - run: yarn prisma generate - name: Generate cache key diff --git a/.github/workflows/setup-db.yml b/.github/workflows/setup-db.yml index f0634a0c68..66e4ea042f 100644 --- a/.github/workflows/setup-db.yml +++ b/.github/workflows/setup-db.yml @@ -47,7 +47,11 @@ jobs: - 5432:5432 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install if: inputs.DB_CACHE_HIT != 'true' - run: yarn prisma generate diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index a922ec9698..532ddb77a8 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -12,7 +12,11 @@ jobs: runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/dangerous-git-checkout + with: + sparse-checkout: .github + - uses: ./.github/actions/cache-checkout + with: + mode: restore - uses: ./.github/actions/yarn-install - run: yarn prisma generate - run: yarn test -- --no-isolate