Skip to content

Commit 0ed65fd

Browse files
mkruskal-googlecopybara-github
authored andcommitted
Enable github caching of Bazel's repository cache.
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: 508133044
1 parent 99e83d0 commit 0ed65fd

File tree

7 files changed

+125
-7
lines changed

7 files changed

+125
-7
lines changed

.github/actions/bazel-docker/action.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ runs:
4545
credentials-file: /workspace/$(basename ${{ steps.auth.outputs.credentials-file }})
4646
bazel-cache: ${{ inputs.bazel-cache }}
4747

48+
- name: Hook up repository Cache
49+
shell: bash
50+
run: echo "BAZEL_FLAGS=$BAZEL_FLAGS --repository_cache='/workspace/${{ env.REPOSITORY_CACHE_PATH }}'" >> $GITHUB_ENV
51+
4852
- name: Validate inputs
4953
if: ${{ (inputs.bash && inputs.bazel) || (!inputs.bash && !inputs.bazel) }}
5054
shell: bash
@@ -63,4 +67,9 @@ runs:
6367
if: ${{ !inputs.bash }}
6468
with:
6569
image: ${{ inputs.image }}
66-
command: ${{ inputs.bazel }} ${{ steps.bazel.outputs.bazel-flags }}
70+
command: ${{ inputs.bazel }} ${{ env.BAZEL_FLAGS }}
71+
72+
- name: Save Bazel repository cache
73+
# Only allow repository cache updates during post-submits.
74+
if: ${{ github.event_name == 'push' }}
75+
uses: ./.github/actions/internal/repository-cache-save

.github/actions/bazel/action.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,23 @@ runs:
6363
run: echo "BAZELISK_PATH=$LOCALAPPDATA\bazelisk" >> $GITHUB_ENV
6464

6565
- name: Cache Bazelisk
66+
if: ${{ github.event_name == 'push' }}
6667
uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
6768
with:
6869
path: ${{ env.BAZELISK_PATH }}
6970
key: bazel-${{ runner.os }}-${{ inputs.version }}
7071

72+
- name: Restore Bazelisk
73+
if: ${{ github.event_name != 'push' }}
74+
uses: actions/cache/restore@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
75+
with:
76+
path: ${{ env.BAZELISK_PATH }}
77+
key: bazel-${{ runner.os }}-${{ inputs.version }}
78+
79+
- name: Hook up repository Cache
80+
shell: bash
81+
run: echo "BAZEL_FLAGS=$BAZEL_FLAGS --repository_cache=$(pwd)/${{ env.REPOSITORY_CACHE_PATH }}" >> $GITHUB_ENV
82+
7183
- name: Validate inputs
7284
if: ${{ (inputs.bash && inputs.bazel) || (!inputs.bash && !inputs.bazel) }}
7385
shell: bash
@@ -90,5 +102,10 @@ runs:
90102
if: ${{ !inputs.bash }}
91103
run: >-
92104
bazelisk ${{ steps.bazel.outputs.bazel-startup-flags }}
93-
${{ inputs.bazel }} ${{ steps.bazel.outputs.bazel-flags }}
105+
${{ inputs.bazel }} $BAZEL_FLAGS
94106
shell: bash
107+
108+
- name: Save Bazel repository cache
109+
# Only allow repository cache updates during post-submits.
110+
if: ${{ github.event_name == 'push' }}
111+
uses: ./.github/actions/internal/repository-cache-save

.github/actions/ccache/action.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,15 @@ runs:
2525
with:
2626
path: .ccache
2727
# Always push to a cache key unique to this commit.
28-
key: ${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref, github.sha) }}
28+
key: ${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref_name, github.sha) }}
2929
# Select a cache to restore from with the follow order of preference:
3030
# 1) The exact same commit we're running over
3131
# 2) The latest cache from the current ref branch
3232
# 3) The latest push to the base ref of a pull request
3333
restore-keys: |
34-
${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref, github.sha) }}
35-
${{ format('ccache-{0}-{1}', inputs.cache-prefix, github.ref) }}
34+
${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref_name, github.sha) }}
35+
${{ format('ccache-{0}-{1}', inputs.cache-prefix, github.ref_name) }}
3636
${{ format('ccache-{0}-{1}', inputs.cache-prefix, github.base_ref) }}
37-
${{ format('ccache-{0}-refs/heads/{1}', inputs.cache-prefix, github.ref) }}
38-
${{ format('ccache-{0}-refs/heads/{1}', inputs.cache-prefix, github.base_ref) }}
3937
4038
- name: Configure ccache environment variables
4139
shell: bash

.github/actions/internal/bazel-setup/action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,8 @@ runs:
6666
run: |
6767
echo "bazel-flags=$BAZEL_FLAGS" >> $GITHUB_OUTPUT
6868
echo "bazel-startup-flags=$BAZEL_STARTUP_FLAGS" >> $GITHUB_OUTPUT
69+
70+
- name: Restore Bazel repository cache
71+
uses: ./.github/actions/internal/repository-cache-restore
72+
with:
73+
bazel-cache: ${{ inputs.bazel-cache }}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Restore Repository Cache
2+
description: Restore the Bazel repository cache from our github action cache
3+
inputs:
4+
bazel-cache:
5+
required: true
6+
description: A unique path for the Bazel cache.
7+
type: string
8+
9+
# By design, these actions will restore the latest cache for this branch/os,
10+
# and only save a new version if something has changed. Initially this will
11+
# cause a lot of churn, since each test has a slightly different set of
12+
# repositories to download. Over time though, since we don't upload no-op
13+
# changes, this should converge to a stable set of 3 caches per branch. Every
14+
# run will update the current cache with a new test's repositories, until there
15+
# are no unique ones left.
16+
#
17+
# This saves asymptotic space, since each one of these can get up to ~500 MB
18+
# and Github prunes the cache after 10 GB.
19+
runs:
20+
using: 'composite'
21+
steps:
22+
- name: Setup Bazel repository cache variables
23+
shell: bash
24+
run: |
25+
REPOSITORY_CACHE_BASE=repository-cache-${{ github.base_ref || github.ref_name }}-${{ runner.os }}
26+
echo "REPOSITORY_CACHE_BASE=$REPOSITORY_CACHE_BASE" >> $GITHUB_ENV
27+
echo "REPOSITORY_CACHE_NAME=$REPOSITORY_CACHE_BASE-${{ inputs.bazel-cache}}-${{ github.sha }}" >> $GITHUB_ENV
28+
echo "REPOSITORY_CACHE_PATH=.repository-cache" >> $GITHUB_ENV
29+
30+
- name: Restore Bazel repository cache
31+
id: restore-cache
32+
uses: actions/cache/restore@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
33+
with:
34+
path: ${{ github.workspace }}/${{ env.REPOSITORY_CACHE_PATH }}
35+
key: ${{ env.REPOSITORY_CACHE_NAME }}
36+
restore-keys: ${{ env.REPOSITORY_CACHE_BASE }}
37+
38+
- name: Initialize BAZEL environment variable
39+
if: ${{ steps.restore-cache.cache-hit }}
40+
shell: bash
41+
run: echo "REPOSITORY_CACHE_HASH=${{ hashFiles(format('{0}/**', env.REPOSITORY_CACHE_PATH)) }}" >> $GITHUB_ENV
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Restore Repository Cache
2+
description: Restore the Bazel repository cache from our github action cache
3+
4+
# Note: this action will only work if repository-cache-restore has already
5+
# been called. All bazel actions should specify the repository_cache parameter
6+
# using REPOSITORY_CACHE_PATH.
7+
#
8+
# We intentionally upload to REPOSITORY_CACHE_BASE to prevent a flood of new
9+
# caches on any change. Only 1 job per os in each test run will be allowed to
10+
# update the cache because they're all trying to write to the same location.
11+
runs:
12+
using: 'composite'
13+
steps:
14+
- name: Save modified Bazel repository cache
15+
if: ${{ env.REPOSITORY_CACHE_HASH != hashFiles(format('{0}/**', env.REPOSITORY_CACHE_PATH)) }}
16+
uses: actions/cache/save@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
17+
with:
18+
path: ${{ github.workspace }}/${{ env.REPOSITORY_CACHE_PATH }}
19+
key: ${{ env.REPOSITORY_CACHE_BASE }}-${{ github.sha }}

.github/workflows/clear_caches.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Clear expensive caches to prevent unbounded growth
2+
3+
on:
4+
schedule:
5+
# Run every 1st of the month at 10 AM UTC (2 AM PDT)
6+
- cron: 0 10 1 * *
7+
8+
# manual
9+
workflow_dispatch:
10+
11+
jobs:
12+
bazel-repository-cache:
13+
strategy:
14+
fail-fast: false # Don't cancel all jobs if one fails.
15+
matrix:
16+
os: [ubuntu-latest, macos-latest, windows-latest]
17+
name: Clear Bazel repository cache ${{ runner.os }}
18+
runs-on: ${{ matrix.os }}
19+
steps:
20+
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
21+
with:
22+
path: ${{ github.workspace }}/${{ steps.output.outputs.repository-cache }}
23+
key: repository-cache-${{ github.ref_name }}-${{ runner.os }}-reset-${{ github.sha }}
24+
25+
- name: Create an empty cache with a single file
26+
run: |
27+
rm -rf .repository-cache
28+
mkdir -p .repository-cache'
29+
touch .repository-cache/reset_file

0 commit comments

Comments
 (0)