Include the hash of the cross binary in the cache key

This protects against changes to the Docker images that `cross` uses.
This commit is contained in:
Dave Rolsky 2024-12-24 11:35:28 -06:00
parent a183497a0a
commit faf2f9fd0a
No known key found for this signature in database
4 changed files with 54 additions and 29 deletions

View File

@ -111,6 +111,10 @@ When running `cargo` on a Linux system, it will also include the output of runni
system libraries. If those library versions change across OS versions (e.g. Ubuntu 20.04 to 22.04),
then the cache will be broken for these cases.
When running `cross`, the hash of the `cross` binary will be included in the cache key. This is done
because the Docker images that `cross` uses can change when `cross` is updated. We want to make sure
that we do not re-use the cache across changes when these images change.
Finally, it will run `strip` to strip the binaries it builds if the `strip` parameter is true. This
is only possible for builds that are not done via `cross`. In addition, Windows builds for `aarch64`
cannot be stripped either.

View File

@ -140,7 +140,7 @@ runs:
fi
# This will get the inputs JSON from the `RUST_CACHE_PARAMETERS` env var. This avoids
# any string interpolation issues, since the inputs will contain quotes.
parse-rust-cache-parameters.py "${{ inputs.target }}" "${{ steps.set-build-command.outputs.build-command }}" "$OS_VERSION"
parse-and-set-rust-cache-parameters.py "${{ inputs.target }}" "${{ steps.set-build-command.outputs.build-command }}" "$OS_VERSION"
env:
RUST_CACHE_PARAMETERS: ${{ inputs.rust-cache-parameters }}
if: inputs.use-rust-cache == 'true'

View File

@ -0,0 +1,49 @@
#!/usr/bin/env python3
import json
import os
import sys
import hashlib
def main():
target = sys.argv[1]
build_command = sys.argv[2]
os_version = sys.argv[3]
parameters = json.loads(os.environ["RUST_CACHE_PARAMETERS"])
if "key" not in parameters:
parameters["key"] = target
else:
parameters["key"] += "-{}".format(target)
if build_command == "cargo":
# If we're running cargo, we need to add the OS version to the cache. Otherwise things that link
# against system packages, like openssl, can break when we use the same cache across different
# versions of the runner OS. For example, when going from Ubuntu 20.04 to 22.04, we move from
# OpenSSL 1.1.x to 3.x.
parameters["key"] += "-{}".format(os_version)
else:
# Otherwise we want to include the `cross` binary's hash. The Docker images that `cross`
# uses can change when the binary is updated. This protects us from using the same cache
# inside containers that have changed.
parameters["key"] += "-cross-binary-hash-{}".format(
get_file_hash(build_command)
)
file = os.environ["GITHUB_OUTPUT"]
with open(file, "w") as f:
for key, value in parameters.items():
f.write(f"{key}={value}")
def get_file_hash(build_command):
with open(build_command, "rb") as f:
file_hash = hashlib.sha256()
while chunk := f.read(65536):
file_hash.update(chunk)
return file_hash.hexdigest()
main()

View File

@ -1,28 +0,0 @@
#!/usr/bin/env python3
import json
import os
import sys
target = sys.argv[1]
build_command = sys.argv[2]
os_version = sys.argv[3]
parameters = json.loads(os.environ["RUST_CACHE_PARAMETERS"])
if "key" not in parameters:
parameters["key"] = target
else:
parameters["key"] = "{}-{}".format(parameters["key"], target)
# If we're running cargo, we need to add the OS version to the cache. Otherwise things that link
# against system packages, like openssl, can break when we use the same cache across different
# versions of the runner OS. For example, when going from Ubuntu 20.04 to 22.04, we move from
# OpenSSL 1.1.x to 3.x.
if build_command == "cargo":
parameters["key"] = "{}-{}".format(parameters["key"], os_version)
file = os.environ["GITHUB_OUTPUT"]
with open(file, "w") as f:
for key, value in parameters.items():
f.write(f"{key}={value}")