-
Notifications
You must be signed in to change notification settings - Fork 29
Support caching bevy_lint
in its Github Action
#530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
bf3652f
to
b328396
Compare
b328396
to
af02286
Compare
The cache is only saved in the post-run step, meaning the job must end before a cache is saved. The easiest way to get around this is to split each test into a separate job.
@@ -8,10 +8,25 @@ on: | |||
paths: | |||
- bevy_lint/action.yml | |||
- rust-toolchain.toml | |||
- .github/workflows/linter-action.yml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While unrelated, this lets us test linter-action.yml
in CI on PRs when linter-action.yml
is modified.
- name: Run `bevy_lint` on `bevy_lint` | ||
run: bevy_lint --package bevy_lint --locked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chose not to run this for all of the other cache jobs in order to speed up the workflow runtime. Instead, the other jobs just run bevy_lint --version
.
Let me know if you think I should change this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If set to `true`, this action will cache the built `bevy_lint` executable and reuse it on | ||
subsequent runs, which can speed up the runtime. This defaults to `false`. | ||
required: false | ||
default: 'false' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is a string and not a boolean. Action inputs are converted to strings, making these two steps equivalent:
- uses: TheBevyFlock/bevy_cli/bevy_lint@main
with:
cache: true
- uses: TheBevyFlock/bevy_cli/bevy_lint@main
with:
cache: 'true'
This is important when checking if the input is true or false, as non-empty strings are truthy:
if: ${{ true }} # true
if: ${{ 'true' }} # true
if: ${{ false }} # false
if: ${{ '' }} # false
if: ${{ 'false' }} # true! :O
This is why I do a lot of ${{ inputs.cache == 'true' }}
instead of just ${{ inputs.cache }}
.
description: | | ||
A string indicating whether an existing cached `bevy_lint` was used. This will be 'true' if a | ||
cache was used and '' (an empty string) if a cache was not. If caching is disabled, this will | ||
always be an empty string. | ||
# Technically `cache-hit` could be 'false' if a fallback key was used instead of the primary | ||
# key, but we don't use fallback keys, so that shouldn't happen. | ||
value: ${{ steps.cache.outputs.cache-hit || steps.restore-cache.outputs.cache-hit }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I would much rather this be 'true'
or 'false'
for if the cache was hit, actions/cache
uses 'true'
and ''
. I'd rather follow precedence here than make things confusing and different.
id: cache-key | ||
if: ${{ inputs.cache == 'true' }} | ||
shell: bash | ||
run: echo "key=bevy_lint-${RUNNER_OS}-${ACTION_REF}" >> "${GITHUB_OUTPUT}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This key makes it so caches for different operating systems and linter versions won't be shared. For example, Windows and MacOS will have separate caches, and bevy_lint
v0.3.0 and bevy_lint
main
will have separate caches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool, and nicely documented and tested :)
If set to `true`, this action will cache the built `bevy_lint` executable and reuse it on | ||
subsequent runs, which can speed up the runtime. This defaults to `false`. | ||
required: false | ||
default: 'false' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious, if the speedup is so big, why don't we enable caching by default?
I would expect most users wanting to have it enabled.
`bevy_lint` provides an action to conveniently install the linter in CI: | ||
> **Important** | ||
> | ||
> The action is only available for versions v0.3.0 and onward. v0.2.0 and v0.1.0 will not work, however you may emulate it by manually running the [installation commands](install.md) in your workflow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the long term (and in a separate PR) we should define some sort of shortcut or component to indicate version compatibility in the book, something like "since v0.3.0".
This would also be useful for the CLI!
This PR adds support for caching the compiled
bevy_lint
andbevy_lint_driver
binaries in the Github Action. This can significantly speed up the time it takes to install the linter in CI.Usage
Check out the rendered documentation! The biggest notes are:
main
branch to reduce quota usageYou can also check whether there was a cache hit, but that's mostly useful for internal testing.
Performance
The CI run for
aa51a8e
show the performance benefits. The "Cache miss" jobs are when the linter is built from scratch, while the "Cache hit" jobs are when the linter is downloaded from the cache. The times are summarized below:Essentially, caching doubles the speed at which
bevy_lint
can be installed. This is awesome!Testing
I overhauled our
linter-action.yml
CI check to test caching. It now tests:save-cache-if: 'false'
save-cache-if: 'true'
Because these tests depend on the global CI cache, I restricted the concurrency of this workflow so only one instance of it can run at a time. This may result in slower CI times when several PRs are merged at the same time or several PRs modify
bevy_lint/action.yml
, but in practice I don't think that will be an issue.