Skip to content

Cache test binaries#45

Draft
dmacvicar wants to merge 2 commits intomainfrom
optimize/cache-test-binaries
Draft

Cache test binaries#45
dmacvicar wants to merge 2 commits intomainfrom
optimize/cache-test-binaries

Conversation

@dmacvicar
Copy link
Contributor

@dmacvicar dmacvicar commented Mar 17, 2026

This PR explores an idea to go beyond the Go setup action caching and do caching per test binary.

While a test binary can take up to 17m to build, with the Go action cache this goes down to something between 30s to 2m depending on the test. This is not much, but if we test 100+ services, this scales quickly to 30+ minutes per run.

This approach caches the service binary, and brings it down to ~5s to restore the binary cache. The cache is done on top of the go-action layer, so it cascades on miss/hit of that cache.

The key is composed of:

  • go version (unfortunately can't take it from go action output, as it runs before)
  • submodule hash
  • patches applied to the provider

I'd love to get feedback if the complexity is worth the gain.

@github-actions
Copy link

github-actions bot commented Mar 17, 2026

Terraform Test Results

2 tests   1 ✅  35s ⏱️
1 suites  0 💤
1 files    1 ❌

For more details on these failures, see this check.

Results for commit 40b9f76.

♻️ This comment has been updated with latest results.

@dmacvicar dmacvicar changed the title Optimize/cache test binaries Cache test binaries Mar 18, 2026
Skip Go setup, patching, and binary compilation when the cache
hits. Also cache the Go vendor directory keyed on go.sum. Caches
are saved immediately after build using explicit save/restore so
they persist even when tests fail.
@dmacvicar dmacvicar force-pushed the optimize/cache-test-binaries branch from 9edbfd7 to caa1566 Compare March 18, 2026 08:59
Read the Go version from go.mod before the cache restore step so
it is available for the key. This ensures binaries are rebuilt
when the Go version changes.
Copy link
Member

@alexrashed alexrashed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea to implement more aggressive caching!
I guess for me the biggest question is how often the cache is going to be invalidated / how often we will have a cache hit. If we are going to update the submodule hash every week, and only run the action once a week, there is no need to introduce these caches. However, if there are multiple runs on the same terraform test codebase, this looks very promising! 🤩

key: test-bin-go${{ steps.submodule-info.outputs.go-version }}-${{ steps.submodule-info.outputs.sha }}-${{ hashFiles('terraform_pytest/patches/**') }}-${{ matrix.service_partition.service }}

- uses: actions/setup-go@v6
if: steps.cache-binary.outputs.cache-hit != 'true'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: The setup-go action takes ~10 seconds to run (at least in this run). Would it maybe make sense to avoid the complexity of determining the go version manually, and just run the go setup always?

Comment on lines +56 to +61
- name: Restore test binary cache
id: cache-binary
uses: actions/cache/restore@v4
with:
path: test-bin/${{ matrix.service_partition.service }}.test
key: test-bin-go${{ steps.submodule-info.outputs.go-version }}-${{ steps.submodule-info.outputs.sha }}-${{ hashFiles('terraform_pytest/patches/**') }}-${{ matrix.service_partition.service }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: I am not sure, but is it really necessary to explicitly run restore and save? Usually you only use actions/cache and the action itself runs the restore directly and registers a post-step. Is this because the cache should be stored even if the workflow run fails?

Comment on lines +56 to +61
- name: Restore test binary cache
id: cache-binary
uses: actions/cache/restore@v4
with:
path: test-bin/${{ matrix.service_partition.service }}.test
key: test-bin-go${{ steps.submodule-info.outputs.go-version }}-${{ steps.submodule-info.outputs.sha }}-${{ hashFiles('terraform_pytest/patches/**') }}-${{ matrix.service_partition.service }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: There are 3 different caches with different cache keys, each using the keys in the restore and save actions. I think that might be the weakest point here in terms of complexity. It will be very easy in the future to break the caching because the keys are manipulated or diverge. Would it maybe make sense to have one step clearly defining these keys in variables that are then being used for the steps (maybe with additional context why the keys are composed the way they are)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants