Files
pebrel/.github/actions/rust-cache/action.yml
T
kuddev e33465943a ci(macos): run release checks beside the complete native tests
Separate the independent macOS release metadata checks from native test jobs while retaining both architectures and the full release gate. Preserve Git dependency checkouts in the shared Cargo cache and compile tests before checking the product graph.
2026-09-15 09:51:18 +08:00

124 lines
5.9 KiB
YAML

name: Cargo downloads and compiled targets
description: Share downloads across jobs without duplicating them in every target cache
inputs:
key:
description: Compiled workload (core, product, release or legacy)
required: true
target:
description: Compiled profile directories to retain, relative to the repository
required: true
legacy-key:
description: Previous combined cache key, restored only during migration
default: ""
extra-key:
description: Additional inputs for native build tools stored with this target
default: ""
outputs:
cache-key:
description: Key to use when saving compiled targets
value: ${{ steps.identity.outputs.key }}
cache-hit:
description: Whether the compiled target cache matched exactly
value: ${{ steps.target.outputs.cache-hit }}
runs:
using: composite
steps:
- name: Identify compiler and build environment
id: identity
shell: bash
env:
CACHE_OS: ${{ runner.os }}
CACHE_ARCH: ${{ runner.arch }}
CACHE_WORKLOAD: ${{ inputs.key }}
CACHE_REVISION: ${{ github.sha }}
CACHE_MANIFESTS: ${{ hashFiles('Cargo.lock', '**/Cargo.toml', 'rust-toolchain.toml', '**/.cargo/config.toml', '.github/ci-profile.toml') }}${{ inputs.extra-key }}
run: |
python - <<'PY'
import hashlib
import json
import os
from pathlib import Path
import subprocess
facts = {"rustc": subprocess.check_output(["rustc", "-vV"], text=True)}
prefixes = ("CARGO_PROFILE_", "CFLAGS", "CXXFLAGS", "RUSTFLAGS")
names = {"CARGO_BUILD_TARGET", "CARGO_ENCODED_RUSTFLAGS", "RUSTC_WRAPPER",
"CC", "CXX", "ImageOS", "MACOSX_DEPLOYMENT_TARGET", "SDKROOT", "DEVELOPER_DIR"}
normalize = str.upper if os.name == "nt" else str
names = {normalize(name) for name in names}
facts["environment"] = {normalize(key): value for key, value in os.environ.items()
if normalize(key) in names or normalize(key).startswith(prefixes)}
if os.environ["CACHE_OS"] == "macOS":
facts["sdk"] = subprocess.check_output(["xcrun", "--sdk", "macosx", "--show-sdk-version"], text=True)
fingerprint = hashlib.sha256(json.dumps(facts, sort_keys=True).encode()).hexdigest()[:16]
prefix = "cargo-targets-v1-" + "-".join(os.environ[name] for name in
("CACHE_OS", "CACHE_ARCH", "CACHE_WORKLOAD"))
prefix += "-" + fingerprint + "-"
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
# Immutable caches need a new entry after a source change, including
# when the prior revision failed before it compiled every profile.
output.write("key=" + prefix + os.environ["CACHE_MANIFESTS"] + "-" + os.environ["CACHE_REVISION"] + "\n")
output.write("manifest-key=" + prefix + os.environ["CACHE_MANIFESTS"] + "\n")
output.write("restore-key=" + prefix + "\n")
# Recover the preceding Windows cache, which omitted ImageOS because
# Python uppercases environment names there. Cargo revalidates it.
if os.name == "nt":
facts["environment"].pop("IMAGEOS", None)
previous = hashlib.sha256(json.dumps(facts, sort_keys=True).encode()).hexdigest()[:16]
output.write("migration-key=" + prefix.replace(fingerprint, previous) + "\n")
output.write("cargo-home=" + (os.environ.get("CARGO_HOME") or str(Path.home() / ".cargo")) + "\n")
PY
- name: Restore shared Cargo downloads
id: downloads
uses: actions/cache/restore@v4
with:
# Preserve Git source checkouts with their mtimes. Recreating them from
# git/db can make timestamp-based dependency fingerprints dirty even
# after compiled targets were restored. Registry crates remain immutable
# archives: Cargo can recreate their extracted sources without this risk.
path: |
${{ steps.identity.outputs.cargo-home }}/registry/index
${{ steps.identity.outputs.cargo-home }}/registry/cache
${{ steps.identity.outputs.cargo-home }}/git/db
${{ steps.identity.outputs.cargo-home }}/git/checkouts
key: cargo-downloads-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }}
restore-keys: cargo-downloads-v2-${{ runner.os }}-${{ runner.arch }}-
- name: Restore compiled targets
id: target
uses: actions/cache/restore@v4
with:
path: ${{ inputs.target }}
key: ${{ steps.identity.outputs.key }}
restore-keys: |
${{ steps.identity.outputs.manifest-key }}
${{ steps.identity.outputs.restore-key }}
${{ steps.identity.outputs.migration-key }}
- name: Recover an existing combined cache during migration
if: steps.target.outputs.cache-matched-key == '' && inputs.legacy-key != ''
uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ inputs.legacy-key }}
workspaces: . -> target
cache-bin: false
cache-on-failure: true
save-if: false
- name: Populate complete downloads before sharing the cache
if: steps.downloads.outputs.cache-hit != 'true'
shell: bash
run: |
host_target="$(rustc -vV | sed -n 's/^host: //p')"
test -n "$host_target"
cargo fetch --locked --target "$host_target"
- name: Save complete shared Cargo downloads
if: steps.downloads.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
${{ steps.identity.outputs.cargo-home }}/registry/index
${{ steps.identity.outputs.cargo-home }}/registry/cache
${{ steps.identity.outputs.cargo-home }}/git/db
${{ steps.identity.outputs.cargo-home }}/git/checkouts
key: ${{ steps.downloads.outputs.cache-primary-key }}