ci: preserve native caches and correct Windows token access

This commit is contained in:
kuddev committed 2026-09-14 21:30:45 +08:00
1 parent c5af789bc8
commit 1c77d21722
6 files changed
+56 -17

No files matched your search

+15 -6
View File
@@ -6,7 +6,7 @@ inputs:
description: Compiled workload (core, product, release or legacy)
required: true
target:
description: Compiled profile directory to retain, relative to the repository
description: Compiled profile directories to retain, relative to the repository
required: true
legacy-key:
description: Previous combined cache key, restored only during migration
@@ -45,8 +45,10 @@ runs:
prefixes = ("CARGO_PROFILE_", "CFLAGS", "CXXFLAGS", "RUSTFLAGS")
names = {"CARGO_BUILD_TARGET", "CARGO_ENCODED_RUSTFLAGS", "RUSTC_WRAPPER",
"CC", "CXX", "ImageOS", "MACOSX_DEPLOYMENT_TARGET", "SDKROOT", "DEVELOPER_DIR"}
facts["environment"] = {key: value for key, value in os.environ.items()
if key in names or key.startswith(prefixes)}
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]
@@ -56,7 +58,13 @@ runs:
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
output.write("key=" + prefix + os.environ["CACHE_MANIFESTS"] + "\n")
output.write("restore-key=" + prefix + "\n")
output.write("cargo-home=" + os.environ.get("CARGO_HOME", str(Path.home() / ".cargo")) + "\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
@@ -76,14 +84,15 @@ runs:
with:
path: ${{ inputs.target }}
key: ${{ steps.identity.outputs.key }}
restore-keys: ${{ steps.identity.outputs.restore-key }}
restore-keys: |
${{ 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
env-vars: MACOSX_DEPLOYMENT_TARGET
cache-bin: false
cache-on-failure: true
save-if: false
+12 -7
View File
@@ -73,7 +73,10 @@ jobs:
id: rust-cache
with:
key: native
target: target/ci
extra-key: -release-check-v2
target: |
target/ci
target/release
legacy-key: ${{ runner.os == 'Windows' && 'windows' || runner.os == 'Linux' && 'linux' || 'macos' }}
- name: Prepare pinned Windows console runtime
if: runner.os == 'Windows'
@@ -81,12 +84,6 @@ jobs:
run: ./scripts/prepare-windows-runtime.ps1 -Destination assets/windows/conhost
- name: Test complete workspace and native harness
run: python scripts/ci_native_tests.py
- name: Save compiled workload
if: ${{ always() && steps.rust-cache.outcome == 'success' && steps.rust-cache.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: target/ci
key: ${{ steps.rust-cache.outputs.cache-key }}
- name: Check source architecture
if: ${{ !cancelled() && runner.os == 'Linux' }}
run: python scripts/check_architecture.py
@@ -96,6 +93,14 @@ jobs:
- name: Check the release workspace
if: ${{ !cancelled() }}
run: cargo check --locked --workspace --release
- name: Save compiled workload
if: ${{ always() && steps.rust-cache.outcome == 'success' && steps.rust-cache.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: |
target/ci
target/release
key: ${{ steps.rust-cache.outputs.cache-key }}
- name: Upload native compilation timings
if: always()
uses: actions/upload-artifact@v4
+2 -1
View File
@@ -434,7 +434,8 @@ settings files.
platform still runs the complete Python helper and harness suites. Separate
test and release cache keys prevent concurrent jobs from replacing one another's
compiled workload. Dependency archives and Git objects are shared within each
platform; only the relevant compiled profile is saved per workload. A fallback
platform; each workload saves only the profiles it uses (native tests also keep
release-check metadata). A fallback
reads existing combined caches during migration. Cargo still validates source,
profile and feature fingerprints before reuse.
- **Scheduling:** Stable releases call the same complete four-platform native
@@ -1,4 +1,5 @@
import os
import sys
import unittest
from scripts.conformance.windows_standard_user import WindowsTokens, run_python
@@ -6,6 +7,18 @@ from scripts.conformance.windows_standard_user import WindowsTokens, run_python
@unittest.skipUnless(os.name == "nt", "requires native Windows process tokens")
class StandardUserLaunchTests(unittest.TestCase):
def test_restricted_token_can_launch_even_when_parent_is_already_ordinary(self):
api = WindowsTokens()
token, restricted = api.current_token(), None
try:
restricted = api.restrict(token)
self.assertFalse(api.elevated(restricted))
self.assertEqual(api.run(restricted, [sys.executable, "-c", "raise SystemExit(19)"]), 19)
finally:
if restricted:
api.kernel.CloseHandle(restricted)
api.kernel.CloseHandle(token)
def test_child_is_unelevated_and_preserves_arguments_and_failure_code(self):
script = """
import sys
+4 -2
View File
@@ -76,9 +76,11 @@ class WindowsTokens:
def current_token(self):
token = wt.HANDLE()
# QUERY | DUPLICATE | ASSIGN_PRIMARY, for a restricted copy of ourselves.
# QUERY | DUPLICATE | ASSIGN_PRIMARY | ADJUST_DEFAULT. The restricted
# handle inherits this access mask; lowering its integrity needs the last
# right. The original token is never modified.
self.require(self.security.OpenProcessToken(
self.kernel.GetCurrentProcess(), 0x000B, ctypes.byref(token)))
self.kernel.GetCurrentProcess(), 0x008B, ctypes.byref(token)))
return token
def elevated(self, token):
+10 -1
View File
@@ -32,7 +32,7 @@ class CacheIdentityTests(unittest.TestCase):
self.assertEqual(arguments, ["xcrun", "--sdk", "macosx", "--show-sdk-version"])
return sdk
with patch.dict(os.environ, environment), patch("subprocess.check_output", side_effect=command):
with patch.dict(os.environ, environment, clear=True), patch("subprocess.check_output", side_effect=command):
exec(compile(code, str(ACTION), "exec"), {})
return dict(line.split("=", 1) for line in output.read_text(encoding="utf-8").splitlines())
@@ -63,6 +63,15 @@ class CacheIdentityTests(unittest.TestCase):
after = self.identity(GITHUB_SHA="two", PREVIEW_ID="second")
self.assertEqual(before["key"], after["key"])
@unittest.skipUnless(os.name == "nt", "Windows cache migration")
def test_windows_migration_preserves_compiler_and_workload_boundaries(self):
before = self.identity()
after = self.identity(ImageOS="win22")
self.assertEqual(before["restore-key"], after["migration-key"])
for change in ({"compiler": "rustc 1.98.0"}, {"CACHE_WORKLOAD": "release"},
{"RUSTFLAGS": "-C opt-level=1"}):
self.assertNotEqual(after["migration-key"], self.identity(**change)["migration-key"])
if __name__ == "__main__":
unittest.main()