This should substantially reduce network flakes, since most builds will no longer need to download external dependencies. Because these caches actually get pretty expensive (~300 MB just from 1 openjdk dependency), we've taken some precautions: 1) The caches only get updated on push events (i.e. post-submit jobs) 2) Only a single job will push a new cache for any os/branch/commit combination. This will be whichever job finishes its bazel run first, and *also* has updates for the cache. Over time, the cache should expand to the full set of transitive dependencies as the quicker jobs stop pushing updates. 3) A clear_caches workflow has been introduced to reset the caches in case they grow too large. This will run monthly for now, but can also be run manually. PiperOrigin-RevId: 508133044pull/11856/head
parent
99e83d07fe
commit
0ed65fd08f
7 changed files with 125 additions and 7 deletions
@ -0,0 +1,41 @@ |
||||
name: Restore Repository Cache |
||||
description: Restore the Bazel repository cache from our github action cache |
||||
inputs: |
||||
bazel-cache: |
||||
required: true |
||||
description: A unique path for the Bazel cache. |
||||
type: string |
||||
|
||||
# By design, these actions will restore the latest cache for this branch/os, |
||||
# and only save a new version if something has changed. Initially this will |
||||
# cause a lot of churn, since each test has a slightly different set of |
||||
# repositories to download. Over time though, since we don't upload no-op |
||||
# changes, this should converge to a stable set of 3 caches per branch. Every |
||||
# run will update the current cache with a new test's repositories, until there |
||||
# are no unique ones left. |
||||
# |
||||
# This saves asymptotic space, since each one of these can get up to ~500 MB |
||||
# and Github prunes the cache after 10 GB. |
||||
runs: |
||||
using: 'composite' |
||||
steps: |
||||
- name: Setup Bazel repository cache variables |
||||
shell: bash |
||||
run: | |
||||
REPOSITORY_CACHE_BASE=repository-cache-${{ github.base_ref || github.ref_name }}-${{ runner.os }} |
||||
echo "REPOSITORY_CACHE_BASE=$REPOSITORY_CACHE_BASE" >> $GITHUB_ENV |
||||
echo "REPOSITORY_CACHE_NAME=$REPOSITORY_CACHE_BASE-${{ inputs.bazel-cache}}-${{ github.sha }}" >> $GITHUB_ENV |
||||
echo "REPOSITORY_CACHE_PATH=.repository-cache" >> $GITHUB_ENV |
||||
|
||||
- name: Restore Bazel repository cache |
||||
id: restore-cache |
||||
uses: actions/cache/restore@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4 |
||||
with: |
||||
path: ${{ github.workspace }}/${{ env.REPOSITORY_CACHE_PATH }} |
||||
key: ${{ env.REPOSITORY_CACHE_NAME }} |
||||
restore-keys: ${{ env.REPOSITORY_CACHE_BASE }} |
||||
|
||||
- name: Initialize BAZEL environment variable |
||||
if: ${{ steps.restore-cache.cache-hit }} |
||||
shell: bash |
||||
run: echo "REPOSITORY_CACHE_HASH=${{ hashFiles(format('{0}/**', env.REPOSITORY_CACHE_PATH)) }}" >> $GITHUB_ENV |
@ -0,0 +1,19 @@ |
||||
name: Restore Repository Cache |
||||
description: Restore the Bazel repository cache from our github action cache |
||||
|
||||
# Note: this action will only work if repository-cache-restore has already |
||||
# been called. All bazel actions should specify the repository_cache parameter |
||||
# using REPOSITORY_CACHE_PATH. |
||||
# |
||||
# We intentionally upload to REPOSITORY_CACHE_BASE to prevent a flood of new |
||||
# caches on any change. Only 1 job per os in each test run will be allowed to |
||||
# update the cache because they're all trying to write to the same location. |
||||
runs: |
||||
using: 'composite' |
||||
steps: |
||||
- name: Save modified Bazel repository cache |
||||
if: ${{ env.REPOSITORY_CACHE_HASH != hashFiles(format('{0}/**', env.REPOSITORY_CACHE_PATH)) }} |
||||
uses: actions/cache/save@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4 |
||||
with: |
||||
path: ${{ github.workspace }}/${{ env.REPOSITORY_CACHE_PATH }} |
||||
key: ${{ env.REPOSITORY_CACHE_BASE }}-${{ github.sha }} |
@ -0,0 +1,29 @@ |
||||
name: Clear expensive caches to prevent unbounded growth |
||||
|
||||
on: |
||||
schedule: |
||||
# Run every 1st of the month at 10 AM UTC (2 AM PDT) |
||||
- cron: 0 10 1 * * |
||||
|
||||
# manual |
||||
workflow_dispatch: |
||||
|
||||
jobs: |
||||
bazel-repository-cache: |
||||
strategy: |
||||
fail-fast: false # Don't cancel all jobs if one fails. |
||||
matrix: |
||||
os: [ubuntu-latest, macos-latest, windows-latest] |
||||
name: Clear Bazel repository cache ${{ runner.os }} |
||||
runs-on: ${{ matrix.os }} |
||||
steps: |
||||
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4 |
||||
with: |
||||
path: ${{ github.workspace }}/${{ steps.output.outputs.repository-cache }} |
||||
key: repository-cache-${{ github.ref_name }}-${{ runner.os }}-reset-${{ github.sha }} |
||||
|
||||
- name: Create an empty cache with a single file |
||||
run: | |
||||
rm -rf .repository-cache |
||||
mkdir -p .repository-cache' |
||||
touch .repository-cache/reset_file |
Loading…
Reference in new issue