diff options
| author | The Miri Cronjob Bot <miri@cron.bot> | 2025-03-16 05:12:15 +0000 |
|---|---|---|
| committer | The Miri Cronjob Bot <miri@cron.bot> | 2025-03-16 05:12:15 +0000 |
| commit | 17ae00d1228ced4eb5a19fa4371b080da87b6b2a (patch) | |
| tree | 001d780c6d9145424e81b3488d472beb488fa237 /src/ci | |
| parent | 642634c39b00a4630e461b431cce0fc38a640b66 (diff) | |
| parent | 5434242af764d1525bd6ddf6e53ee5567042e381 (diff) | |
| download | rust-17ae00d1228ced4eb5a19fa4371b080da87b6b2a.tar.gz rust-17ae00d1228ced4eb5a19fa4371b080da87b6b2a.zip | |
Merge from rustc
Diffstat (limited to 'src/ci')
| -rw-r--r-- | src/ci/citool/src/merge_report.rs | 215 | ||||
| -rw-r--r-- | src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile | 1 | ||||
| -rw-r--r-- | src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 4 | ||||
| -rwxr-xr-x | src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh | 26 | ||||
| -rw-r--r-- | src/ci/docker/host-x86_64/mingw-check/Dockerfile | 2 | ||||
| -rw-r--r-- | src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile | 1 | ||||
| -rwxr-xr-x | src/ci/docker/run.sh | 1 | ||||
| -rw-r--r-- | src/ci/docker/scripts/sccache.sh | 4 | ||||
| -rwxr-xr-x | src/ci/run.sh | 15 | ||||
| -rwxr-xr-x | src/ci/scripts/install-sccache.sh | 6 |
10 files changed, 158 insertions, 117 deletions
diff --git a/src/ci/citool/src/merge_report.rs b/src/ci/citool/src/merge_report.rs index 17e42d49286..62daa2e6853 100644 --- a/src/ci/citool/src/merge_report.rs +++ b/src/ci/citool/src/merge_report.rs @@ -1,8 +1,8 @@ -use std::cmp::Reverse; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; +use std::path::PathBuf; use anyhow::Context; -use build_helper::metrics::{JsonRoot, TestOutcome}; +use build_helper::metrics::{JsonRoot, TestOutcome, TestSuiteMetadata}; use crate::jobs::JobDatabase; use crate::metrics::get_test_suites; @@ -13,8 +13,10 @@ type JobName = String; /// Computes a post merge CI analysis report between the `parent` and `current` commits. pub fn post_merge_report(job_db: JobDatabase, parent: Sha, current: Sha) -> anyhow::Result<()> { let jobs = download_all_metrics(&job_db, &parent, ¤t)?; - let diffs = aggregate_test_diffs(&jobs)?; - report_test_changes(diffs); + let aggregated_test_diffs = aggregate_test_diffs(&jobs)?; + + println!("Comparing {parent} (base) -> {current} (this PR)\n"); + report_test_diffs(aggregated_test_diffs); Ok(()) } @@ -54,7 +56,16 @@ Maybe it was newly added?"#, Ok(jobs) } +/// Downloads job metrics of the given job for the given commit. +/// Caches the result on the local disk. fn download_job_metrics(job_name: &str, sha: &str) -> anyhow::Result<JsonRoot> { + let cache_path = PathBuf::from(".citool-cache").join(sha).join(job_name).join("metrics.json"); + if let Some(cache_entry) = + std::fs::read_to_string(&cache_path).ok().and_then(|data| serde_json::from_str(&data).ok()) + { + return Ok(cache_entry); + } + let url = get_metrics_url(job_name, sha); let mut response = ureq::get(&url).call()?; if !response.status().is_success() { @@ -68,6 +79,13 @@ fn download_job_metrics(job_name: &str, sha: &str) -> anyhow::Result<JsonRoot> { .body_mut() .read_json() .with_context(|| anyhow::anyhow!("cannot deserialize metrics from {url}"))?; + + // Ignore errors if cache cannot be created + if std::fs::create_dir_all(cache_path.parent().unwrap()).is_ok() { + if let Ok(serialized) = serde_json::to_string(&data) { + let _ = std::fs::write(&cache_path, &serialized); + } + } Ok(data) } @@ -76,81 +94,80 @@ fn get_metrics_url(job_name: &str, sha: &str) -> String { format!("https://ci-artifacts.rust-lang.org/rustc-builds{suffix}/{sha}/metrics-{job_name}.json") } +/// Represents a difference in the outcome of tests between a base and a current commit. +/// Maps test diffs to jobs that contained them. +#[derive(Debug)] +struct AggregatedTestDiffs { + diffs: HashMap<TestDiff, Vec<JobName>>, +} + fn aggregate_test_diffs( jobs: &HashMap<JobName, JobMetrics>, -) -> anyhow::Result<Vec<AggregatedTestDiffs>> { - let mut job_diffs = vec![]; +) -> anyhow::Result<AggregatedTestDiffs> { + let mut diffs: HashMap<TestDiff, Vec<JobName>> = HashMap::new(); // Aggregate test suites for (name, metrics) in jobs { if let Some(parent) = &metrics.parent { let tests_parent = aggregate_tests(parent); let tests_current = aggregate_tests(&metrics.current); - let test_diffs = calculate_test_diffs(tests_parent, tests_current); - if !test_diffs.is_empty() { - job_diffs.push((name.clone(), test_diffs)); + for diff in calculate_test_diffs(tests_parent, tests_current) { + diffs.entry(diff).or_default().push(name.to_string()); } } } - // Aggregate jobs with the same diff, as often the same diff will appear in many jobs - let job_diffs: HashMap<Vec<(Test, TestOutcomeDiff)>, Vec<String>> = - job_diffs.into_iter().fold(HashMap::new(), |mut acc, (job, diffs)| { - acc.entry(diffs).or_default().push(job); - acc - }); + Ok(AggregatedTestDiffs { diffs }) +} - Ok(job_diffs - .into_iter() - .map(|(test_diffs, jobs)| AggregatedTestDiffs { jobs, test_diffs }) - .collect()) +#[derive(Eq, PartialEq, Hash, Debug)] +enum TestOutcomeDiff { + ChangeOutcome { before: TestOutcome, after: TestOutcome }, + Missing { before: TestOutcome }, + Added(TestOutcome), } -fn calculate_test_diffs( - reference: TestSuiteData, - current: TestSuiteData, -) -> Vec<(Test, TestOutcomeDiff)> { - let mut diffs = vec![]; +#[derive(Eq, PartialEq, Hash, Debug)] +struct TestDiff { + test: Test, + diff: TestOutcomeDiff, +} + +fn calculate_test_diffs(parent: TestSuiteData, current: TestSuiteData) -> HashSet<TestDiff> { + let mut diffs = HashSet::new(); for (test, outcome) in ¤t.tests { - match reference.tests.get(test) { + match parent.tests.get(test) { Some(before) => { if before != outcome { - diffs.push(( - test.clone(), - TestOutcomeDiff::ChangeOutcome { + diffs.insert(TestDiff { + test: test.clone(), + diff: TestOutcomeDiff::ChangeOutcome { before: before.clone(), after: outcome.clone(), }, - )); + }); } } - None => diffs.push((test.clone(), TestOutcomeDiff::Added(outcome.clone()))), + None => { + diffs.insert(TestDiff { + test: test.clone(), + diff: TestOutcomeDiff::Added(outcome.clone()), + }); + } } } - for (test, outcome) in &reference.tests { + for (test, outcome) in &parent.tests { if !current.tests.contains_key(test) { - diffs.push((test.clone(), TestOutcomeDiff::Missing { before: outcome.clone() })); + diffs.insert(TestDiff { + test: test.clone(), + diff: TestOutcomeDiff::Missing { before: outcome.clone() }, + }); } } diffs } -/// Represents a difference in the outcome of tests between a base and a current commit. -#[derive(Debug)] -struct AggregatedTestDiffs { - /// All jobs that had the exact same test diffs. - jobs: Vec<String>, - test_diffs: Vec<(Test, TestOutcomeDiff)>, -} - -#[derive(Eq, PartialEq, Hash, Debug)] -enum TestOutcomeDiff { - ChangeOutcome { before: TestOutcome, after: TestOutcome }, - Missing { before: TestOutcome }, - Added(TestOutcome), -} - /// Aggregates test suite executions from all bootstrap invocations in a given CI job. #[derive(Default)] struct TestSuiteData { @@ -160,6 +177,7 @@ struct TestSuiteData { #[derive(Hash, PartialEq, Eq, Debug, Clone)] struct Test { name: String, + is_doctest: bool, } /// Extracts all tests from the passed metrics and map them to their outcomes. @@ -168,7 +186,10 @@ fn aggregate_tests(metrics: &JsonRoot) -> TestSuiteData { let test_suites = get_test_suites(&metrics); for suite in test_suites { for test in &suite.tests { - let test_entry = Test { name: normalize_test_name(&test.name) }; + // Poor man's detection of doctests based on the "(line XYZ)" suffix + let is_doctest = matches!(suite.metadata, TestSuiteMetadata::CargoPackage { .. }) + && test.name.contains("(line"); + let test_entry = Test { name: normalize_test_name(&test.name), is_doctest }; tests.insert(test_entry, test.outcome.clone()); } } @@ -181,16 +202,13 @@ fn normalize_test_name(name: &str) -> String { } /// Prints test changes in Markdown format to stdout. -fn report_test_changes(mut diffs: Vec<AggregatedTestDiffs>) { +fn report_test_diffs(diff: AggregatedTestDiffs) { println!("## Test differences"); - if diffs.is_empty() { + if diff.diffs.is_empty() { println!("No test diffs found"); return; } - // Sort diffs in decreasing order by diff count - diffs.sort_by_key(|entry| Reverse(entry.test_diffs.len())); - fn format_outcome(outcome: &TestOutcome) -> String { match outcome { TestOutcome::Passed => "pass".to_string(), @@ -219,36 +237,79 @@ fn report_test_changes(mut diffs: Vec<AggregatedTestDiffs>) { } } - let max_diff_count = 10; - let max_job_count = 5; - let max_test_count = 10; - - for diff in diffs.iter().take(max_diff_count) { - let mut jobs = diff.jobs.clone(); - jobs.sort(); - - let jobs = jobs.iter().take(max_job_count).map(|j| format!("`{j}`")).collect::<Vec<_>>(); + fn format_job_group(group: u64) -> String { + format!("**J{group}**") + } - let extra_jobs = diff.jobs.len().saturating_sub(max_job_count); - let suffix = if extra_jobs > 0 { - format!(" (and {extra_jobs} {})", pluralize("other", extra_jobs)) - } else { - String::new() + // It would be quite noisy to repeat the jobs that contained the test changes after/next to + // every test diff. At the same time, grouping the test diffs by + // [unique set of jobs that contained them] also doesn't work well, because the test diffs + // would have to be duplicated several times. + // Instead, we create a set of unique job groups, and then print a job group after each test. + // We then print the job groups at the end, as a sort of index. + let mut grouped_diffs: Vec<(&TestDiff, u64)> = vec![]; + let mut job_list_to_group: HashMap<&[JobName], u64> = HashMap::new(); + let mut job_index: Vec<&[JobName]> = vec![]; + + let original_diff_count = diff.diffs.len(); + let diffs = diff + .diffs + .into_iter() + .filter(|(diff, _)| !diff.test.is_doctest) + .map(|(diff, mut jobs)| { + jobs.sort(); + (diff, jobs) + }) + .collect::<Vec<_>>(); + let doctest_count = original_diff_count.saturating_sub(diffs.len()); + + let max_diff_count = 100; + for (diff, jobs) in diffs.iter().take(max_diff_count) { + let jobs = &*jobs; + let job_group = match job_list_to_group.get(jobs.as_slice()) { + Some(id) => *id, + None => { + let id = job_index.len() as u64; + job_index.push(jobs); + job_list_to_group.insert(jobs, id); + id + } }; - println!("- {}{suffix}", jobs.join(",")); + grouped_diffs.push((diff, job_group)); + } - let extra_tests = diff.test_diffs.len().saturating_sub(max_test_count); - for (test, outcome_diff) in diff.test_diffs.iter().take(max_test_count) { - println!(" - {}: {}", test.name, format_diff(&outcome_diff)); - } - if extra_tests > 0 { - println!(" - (and {extra_tests} additional {})", pluralize("tests", extra_tests)); - } + // Sort diffs by job group and test name + grouped_diffs.sort_by(|(d1, g1), (d2, g2)| g1.cmp(&g2).then(d1.test.name.cmp(&d2.test.name))); + + for (diff, job_group) in grouped_diffs { + println!( + "- `{}`: {} ({})", + diff.test.name, + format_diff(&diff.diff), + format_job_group(job_group) + ); } let extra_diffs = diffs.len().saturating_sub(max_diff_count); if extra_diffs > 0 { - println!("\n(and {extra_diffs} additional {})", pluralize("diff", extra_diffs)); + println!("\n(and {extra_diffs} additional {})", pluralize("test diff", extra_diffs)); + } + + if doctest_count > 0 { + println!( + "\nAdditionally, {doctest_count} doctest {} were found. These are ignored, as they are noisy.", + pluralize("diff", doctest_count) + ); + } + + // Now print the job group index + println!("\n**Job group index**\n"); + for (group, jobs) in job_index.into_iter().enumerate() { + println!( + "- {}: {}", + format_job_group(group as u64), + jobs.iter().map(|j| format!("`{j}`")).collect::<Vec<_>>().join(", ") + ); } } diff --git a/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile index eb39861d8c7..cf030f6830e 100644 --- a/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile +++ b/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile @@ -30,7 +30,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUSTBUILD_FORCE_CLANG_BASED_TESTS 1 -ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 # llvm.use-linker conflicts with downloading CI LLVM ENV NO_DOWNLOAD_CI_LLVM 1 diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index f54ecef1e30..ae5bf8946dd 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -101,7 +101,9 @@ ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \ ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ --host $HOSTS --target $HOSTS \ --include-default-paths \ - build-manifest bootstrap gcc + build-manifest bootstrap && \ + # Use GCC for building GCC, as it seems to behave badly when built with Clang + CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang # This is the only builder which will create source tarballs diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh index 4a42f5da29f..ad21836253b 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh @@ -41,8 +41,6 @@ cd netbsd mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot -# URL=https://ci-mirrors.rust-lang.org/rustc - # Hashes come from https://cdn.netbsd.org/pub/NetBSD/security/hashes/NetBSD-9.0_hashes.asc SRC_SHA=2c791ae009a6929c6fc893ec5df7e62910ee8207e0b2159d6937309c03efe175b6ae1e445829a13d041b6851334ad35c521f2fa03c97675d4a05f1fafe58ede0 GNUSRC_SHA=3710085a73feecf6a843415271ec794c90146b03f6bbd30f07c9e0c79febf8995d557e40194f1e05db655e4f5ef2fae97563f8456fceaae65d4ea98857a83b1c @@ -51,22 +49,16 @@ SYSSRC_SHA=60b9ddf4cc6402256473e2e1eefeabd9001aa4e205208715ecc6d6fc3f5b400e46994 BASE_SHA=b5926b107cebf40c3c19b4f6cd039b610987dd7f819e7cdde3bd1e5230a856906e7930b15ab242d52ced9f0bda01d574be59488b8dbb95fa5df2987d0a70995f COMP_SHA=38ea54f30d5fc2afea87e5096f06873e00182789e8ad9cec0cb3e9f7c538c1aa4779e63fd401a36ba02676158e83fa5c95e8e87898db59c1914fb206aecd82d2 -# FIXME: the archive URL is being used temporarily while the CDN is down. -# We should serve this from our own CDN -# SOURCE_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/source/sets -SOURCE_URL=http://archive.netbsd.org/pub/NetBSD-archive/NetBSD-9.0/source/sets -download src.tgz "$SOURCE_URL/src.tgz" "$SRC_SHA" tar xzf src.tgz -download gnusrc.tgz "$SOURCE_URL/gnusrc.tgz" "$GNUSRC_SHA" tar xzf gnusrc.tgz -download sharesrc.tgz "$SOURCE_URL/sharesrc.tgz" "$SHARESRC_SHA" tar xzf sharesrc.tgz -download syssrc.tgz "$SOURCE_URL/syssrc.tgz" "$SYSSRC_SHA" tar xzf syssrc.tgz - -# FIXME: the archive URL is being used temporarily while the CDN is down. -# We should serve this from our own CDN -# BINARY_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/amd64/binary/sets -BINARY_URL=http://archive.netbsd.org/pub/NetBSD-archive/NetBSD-9.0/amd64/binary/sets -download base.tar.xz "$BINARY_URL/base.tar.xz" "$BASE_SHA" \ +SOURCE_URL=https://ci-mirrors.rust-lang.org/rustc/2025-03-14-netbsd-9.0-src +download src.tgz "$SOURCE_URL-src.tgz" "$SRC_SHA" tar xzf src.tgz +download gnusrc.tgz "$SOURCE_URL-gnusrc.tgz" "$GNUSRC_SHA" tar xzf gnusrc.tgz +download sharesrc.tgz "$SOURCE_URL-sharesrc.tgz" "$SHARESRC_SHA" tar xzf sharesrc.tgz +download syssrc.tgz "$SOURCE_URL-syssrc.tgz" "$SYSSRC_SHA" tar xzf syssrc.tgz + +BINARY_URL=https://ci-mirrors.rust-lang.org/rustc/2025-03-14-netbsd-9.0-amd64-binary +download base.tar.xz "$BINARY_URL-base.tar.xz" "$BASE_SHA" \ tar xJf base.tar.xz -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib -download comp.tar.xz "$BINARY_URL/comp.tar.xz" "$COMP_SHA" \ +download comp.tar.xz "$BINARY_URL-comp.tar.xz" "$COMP_SHA" \ tar xJf comp.tar.xz -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib cd usr/src diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 9234c6dc921..b32fa6c8e4e 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -41,8 +41,6 @@ COPY host-x86_64/mingw-check/check-default-config-profiles.sh /scripts/ COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/ -ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 - # Check library crates on all tier 1 targets. # We disable optimized compiler built-ins because that requires a C toolchain for the target. # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile index 292dbfd20a5..b97568b0819 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile @@ -30,7 +30,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUSTBUILD_FORCE_CLANG_BASED_TESTS 1 -ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 # llvm.use-linker conflicts with downloading CI LLVM ENV NO_DOWNLOAD_CI_LLVM 1 diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 6658b83efc8..2805bb1118d 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -361,6 +361,7 @@ docker \ --env TOOLSTATE_PUBLISH \ --env RUST_CI_OVERRIDE_RELEASE_CHANNEL \ --env CI_JOB_NAME="${CI_JOB_NAME-$IMAGE}" \ + --env CI_JOB_DOC_URL="${CI_JOB_DOC_URL}" \ --env BASE_COMMIT="$BASE_COMMIT" \ --env DIST_TRY_BUILD \ --env PR_CI_JOB \ diff --git a/src/ci/docker/scripts/sccache.sh b/src/ci/docker/scripts/sccache.sh index f66671c64d2..dba617d8bc8 100644 --- a/src/ci/docker/scripts/sccache.sh +++ b/src/ci/docker/scripts/sccache.sh @@ -6,10 +6,10 @@ set -ex case "$(uname -m)" in x86_64) - url="https://ci-mirrors.rust-lang.org/rustc/2025-01-07-sccache-v0.9.1-x86_64-unknown-linux-musl" + url="https://ci-mirrors.rust-lang.org/rustc/2025-02-24-sccache-v0.10.0-x86_64-unknown-linux-musl" ;; aarch64) - url="https://ci-mirrors.rust-lang.org/rustc/2025-01-07-sccache-v0.9.1-aarch64-unknown-linux-musl" + url="https://ci-mirrors.rust-lang.org/rustc/2025-02-24-sccache-v0.10.0-aarch64-unknown-linux-musl" ;; *) echo "unsupported architecture: $(uname -m)" diff --git a/src/ci/run.sh b/src/ci/run.sh index 823404ea632..63e79c737d6 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -260,19 +260,6 @@ else do_make "$RUST_CHECK_TARGET" fi -if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then - rm -f config.toml - $SRC/configure --set change-id=99999999 - - # Save the build metrics before we wipe the directory - mv build/metrics.json . - rm -rf build - mkdir build - mv metrics.json build - - CARGO_INCREMENTAL=0 ../x check -fi - echo "::group::sccache stats" -sccache --show-stats || true +sccache --show-adv-stats || true echo "::endgroup::" diff --git a/src/ci/scripts/install-sccache.sh b/src/ci/scripts/install-sccache.sh index e143152f330..b055e76a805 100755 --- a/src/ci/scripts/install-sccache.sh +++ b/src/ci/scripts/install-sccache.sh @@ -8,11 +8,13 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" if isMacOS; then - curl -fo /usr/local/bin/sccache "${MIRRORS_BASE}/2021-08-25-sccache-v0.2.15-x86_64-apple-darwin" + curl -fo /usr/local/bin/sccache \ + "${MIRRORS_BASE}/2025-02-24-sccache-v0.10.0-x86_64-apple-darwin" chmod +x /usr/local/bin/sccache elif isWindows; then mkdir -p sccache - curl -fo sccache/sccache.exe "${MIRRORS_BASE}/2018-04-26-sccache-x86_64-pc-windows-msvc" + curl -fo sccache/sccache.exe \ + "${MIRRORS_BASE}/2025-02-24-sccache-v0.10.0-x86_64-pc-windows-msvc.exe" ciCommandAddPath "$(pwd)/sccache" fi |
