Setup repository cache that will persist in github cache
diff --git a/.github/actions/bazel-docker/action.yml b/.github/actions/bazel-docker/action.yml
index c429163..c3bc865 100644
--- a/.github/actions/bazel-docker/action.yml
+++ b/.github/actions/bazel-docker/action.yml
@@ -45,6 +45,10 @@
         credentials-file: /workspace/$(basename ${{ steps.auth.outputs.credentials-file }})
         bazel-cache: ${{ inputs.bazel-cache }}
 
+    - name: Hook up repository Cache
+      shell: bash
+      run: echo "BAZEL_FLAGS=$BAZEL_FLAGS --repository_cache='/workspace/${{ steps.bazel.outputs.repository-cache }}'" >> $GITHUB_ENV
+
     - name: Validate inputs
       if: ${{ (inputs.bash && inputs.bazel) || (!inputs.bash && !inputs.bazel) }}
       shell: bash
@@ -63,4 +67,14 @@
       if: ${{ !inputs.bash }}
       with:
         image: ${{ inputs.image }}
-        command: ${{ inputs.bazel }} ${{ steps.bazel.outputs.bazel-flags }}
+        command: ${{ inputs.bazel }} ${{ env.BAZEL_FLAGS }}
+
+    # Create a new cache for each push event.  This will be seeded by the
+    # latest cache on that branch, but can include any updates.
+    - name: Save Bazel repository cache
+      if: ${{ github.event_name == 'push' }}
+      uses: actions/cache/save@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
+      with:
+        path: ${{ github.workspace }}/${{ steps.output.outputs.repository-cache }}
+        key: bazel-repository-cache-${{ github.ref_name }}-${{ runner.os }}-${{ github.sha }}
+        #restore-keys: bazel-repository-cache-${{ github.ref_name }}-${{ runner.os }}
diff --git a/.github/actions/bazel/action.yml b/.github/actions/bazel/action.yml
index f23dd0a..7d01437 100644
--- a/.github/actions/bazel/action.yml
+++ b/.github/actions/bazel/action.yml
@@ -63,11 +63,23 @@
       run: echo "BAZELISK_PATH=$LOCALAPPDATA\bazelisk" >> $GITHUB_ENV
 
     - name: Cache Bazelisk
+      if: ${{ github.event_name == 'push' }}
       uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
       with:
         path: ${{ env.BAZELISK_PATH }}
         key: bazel-${{ runner.os }}-${{ inputs.version }}
 
+    - name: Restore Bazelisk
+      if: ${{ github.event_name != 'push' }}
+      uses: actions/cache/restore@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
+      with:
+        path: ${{ env.BAZELISK_PATH }}
+        key: bazel-${{ runner.os }}-${{ inputs.version }}
+
+    - name: Hook up repository Cache
+      shell: bash
+      run: echo "BAZEL_FLAGS=$BAZEL_FLAGS --repository_cache=$(pwd)/${{ steps.bazel.outputs.repository-cache }}" >> $GITHUB_ENV
+
     - name: Validate inputs
       if: ${{ (inputs.bash && inputs.bazel) || (!inputs.bash && !inputs.bazel) }}
       shell: bash
@@ -90,5 +102,15 @@
       if: ${{ !inputs.bash }}
       run: >-
         bazelisk ${{ steps.bazel.outputs.bazel-startup-flags }}
-        ${{ inputs.bazel }} ${{ steps.bazel.outputs.bazel-flags }}
+        ${{ inputs.bazel }} $BAZEL_FLAGS
       shell: bash
+
+    # Create a new cache for each push event.  This will be seeded by the
+    # latest cache on that branch, but can include any updates.
+    - name: Save Bazel repository cache
+      if: ${{ github.event_name == 'push' }}
+      uses: actions/cache/save@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
+      with:
+        path: ${{ github.workspace }}/${{ steps.output.outputs.repository-cache }}
+        key: bazel-repository-cache-${{ github.ref_name }}-${{ runner.os }}-${{ github.sha }}
+        #restore-keys: bazel-repository-cache-${{ github.ref_name }}-${{ runner.os }}
diff --git a/.github/actions/ccache/action.yml b/.github/actions/ccache/action.yml
index f5ceaf0..2a100cc 100644
--- a/.github/actions/ccache/action.yml
+++ b/.github/actions/ccache/action.yml
@@ -25,17 +25,15 @@
       with:
         path: .ccache
         # Always push to a cache key unique to this commit.
-        key: ${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref, github.sha) }}
+        key: ${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref_name, github.sha) }}
         # Select a cache to restore from with the follow order of preference:
         # 1) The exact same commit we're running over
         # 2) The latest cache from the current ref branch
         # 3) The latest push to the base ref of a pull request
         restore-keys: |
-          ${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref, github.sha) }}
-          ${{ format('ccache-{0}-{1}', inputs.cache-prefix, github.ref) }}
+          ${{ format('ccache-{0}-{1}-{2}', inputs.cache-prefix, github.ref_name, github.sha) }}
+          ${{ format('ccache-{0}-{1}', inputs.cache-prefix, github.ref_name) }}
           ${{ format('ccache-{0}-{1}', inputs.cache-prefix, github.base_ref) }}
-          ${{ format('ccache-{0}-refs/heads/{1}', inputs.cache-prefix, github.ref) }}
-          ${{ format('ccache-{0}-refs/heads/{1}', inputs.cache-prefix, github.base_ref) }}
 
     - name: Configure ccache environment variables
       shell: bash
diff --git a/.github/actions/internal/bazel-setup/action.yml b/.github/actions/internal/bazel-setup/action.yml
index eb0951f..6b3bb42 100644
--- a/.github/actions/internal/bazel-setup/action.yml
+++ b/.github/actions/internal/bazel-setup/action.yml
@@ -17,6 +17,9 @@
   bazel-startup-flags:
     description: Bazel startup flags that should be sent to all Bazel invocations
     value: ${{ steps.output.outputs.bazel-startup-flags }}
+  repository-cache:
+    description: The location of our cached Bazel repository cache.
+    value: ${{ steps.output.outputs.repository-cache }}
 
 runs:
   using: 'composite'
@@ -66,3 +69,10 @@
       run: |
         echo "bazel-flags=$BAZEL_FLAGS" >> $GITHUB_OUTPUT
         echo "bazel-startup-flags=$BAZEL_STARTUP_FLAGS" >> $GITHUB_OUTPUT
+        echo "repository-cache=.repository_cache" >> $GITHUB_OUTPUT
+
+    - name: Restore Bazel repository cache
+      uses: actions/cache/restore@627f0f41f6904a5b1efbaed9f96d9eb58e92e920 # v3.2.4
+      with:
+        path: ${{ github.workspace }}/${{ steps.output.outputs.repository-cache }}
+        key: bazel-repository-cache-${{ github.base_ref || github.ref_name }}-${{ runner.os }}
diff --git a/.github/workflows/clear_caches.yml b/.github/workflows/clear_caches.yml
new file mode 100644
index 0000000..f27e00a
--- /dev/null
+++ b/.github/workflows/clear_caches.yml
@@ -0,0 +1,27 @@
+name: Clear expensive caches to prevent unbound growth
+
+on:
+  schedule:
+    # Run every Sunday at 10 AM UTC (2 AM PDT)
+    - cron: 0 10 * * SUN
+
+  # 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: bazel-repository-cache-${{ github.ref_name }}-${{ runner.os }}-reset-${{ github.sha }}
+
+      - run: |
+        mkdir -p '${{ github.workspace }}/.repository_cache'
+        touch '${{ github.workspace }}/.repository_cache/reset_file'