Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions bootstrap.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,15 @@
#
#rust.parallel-frontend-threads = 1

# Baseline commit SHA for comparing semver breakages in the Rust standard library.
# The in-tree stdlib API will be evaluated for semver breakages against this commit.
# Used for the `./x test std-semver-check` command.
# If unset, the first upstream parent commit will be used.
#
# The SHA must point to a merge commit merged into the mainline rust-lang/rust `main` branch,
# because bootstrap will attempt to download the JSON docs data for this commit from its CI.
#rust.stdlib-semver-baseline = "<commit-sha>"

# =============================================================================
# Distribution options
#
Expand Down
72 changes: 56 additions & 16 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4617,7 +4617,7 @@ impl CommandLineStep for RemoteTestClientTests {
}

fn check_if_cargo_semver_checks_is_installed(builder: &Builder<'_>) -> bool {
command("cargo")
command(&builder.initial_cargo)
.allow_failure()
.arg("semver-checks")
.arg("--version")
Expand All @@ -4630,6 +4630,9 @@ fn check_if_cargo_semver_checks_is_installed(builder: &Builder<'_>) -> bool {
/// Run cargo-semver-checks on the standard library and compare its API
/// versus a previous baseline, using rustdoc JSON data.
///
/// The baseline commit can be configured using `rust.stdlib-semver-baseline`.
/// If unset, the first upstream parent commit will be used.
///
/// Fails if a semver-breaking change is detected.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StdSemverCheck {
Expand All @@ -4651,19 +4654,22 @@ impl CommandLineStep for StdSemverCheck {
panic!("cargo-semver-checks was not found, please install it");
}

let baseline_commit = match get_closest_upstream_commit(
Some(&run.builder.config.src),
&run.builder.config.git_config(),
run.builder.config.ci_env,
) {
Ok(Some(commit)) => commit,
Ok(None) => {
panic!("No baseline parent commit found for std-semver-check");
}
Err(error) => {
panic!("Cannot get baseline parent commit for std-semver-check: {error:?}");
}
};
let baseline_commit =
run.builder.config.stdlib_semver_baseline.clone().unwrap_or_else(|| {
match get_closest_upstream_commit(
Some(&run.builder.config.src),
&run.builder.config.git_config(),
run.builder.config.ci_env,
) {
Ok(Some(commit)) => commit,
Ok(None) => {
panic!("No baseline parent commit found for std-semver-check");
}
Err(error) => {
panic!("Cannot get baseline parent commit for std-semver-check: {error:?}");
}
}
});

run.builder.ensure(Self {
build_compiler: run.builder.compiler_for_std(run.builder.top_stage),
Expand All @@ -4687,7 +4693,7 @@ impl CommandLineStep for StdSemverCheck {

for library in ["core", "alloc", "std"] {
println!("Checking semver compatibility of {library}");
let mut cmd = command("cargo");
let mut cmd = command(&builder.initial_cargo);
cmd.arg("semver-checks")
.arg("-Z")
.arg("unstable-options")
Expand All @@ -4698,7 +4704,41 @@ impl CommandLineStep for StdSemverCheck {
.arg(directory.join(format!("{library}.json")))
.arg("--baseline-rustdoc")
.arg(baseline_dir.join(format!("{library}.json")));
cmd.run(builder);

// We use run_capture to get the exit status
let res = cmd.allow_failure().run_capture(builder);
match res.status() {
Some(status) if status.success() => {
println!("{}\n{}", res.stdout(), res.stderr());
}
// 101 marks that csc was unable to parse the JSON data, but it did not fail with a
// semver breakage.
Some(status) if status.code() == Some(101) => {
eprintln!(
"cargo-semver-checks was unable to process {library} (this is not a fatal error)\n{}\n{}",
res.stderr(),
res.stdout()
);
}
Comment thread
jieyouxu marked this conversation as resolved.
// 100 marks semver breakage
Some(status) if status.code() == Some(100) => {
let error = format!(
"cargo-semver-checks found semver breakage in {library}\n{}\n{}",
res.stderr(),
res.stdout()
);
if builder.fail_fast {
eprintln!("{error}",);
exit!(1);
} else {
builder.config.exec_ctx().add_to_delay_failure(error);
}
}
_ => {
eprintln!("cargo-semver-checks failed.\n{}\n{}", res.stderr(), res.stdout());
exit!(1);
}
}
}
}
}
4 changes: 4 additions & 0 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ pub struct Config {
pub rustdoc_pgo: PgoConfig,
pub cargo_pgo: PgoConfig,

pub stdlib_semver_baseline: Option<String>,

pub llvm_libunwind_default: Option<LlvmLibunwind>,
pub enable_bolt_settings: bool,

Expand Down Expand Up @@ -610,6 +612,7 @@ impl Config {
std_features: rust_std_features,
break_on_ice: rust_break_on_ice,
rustflags: rust_rustflags,
stdlib_semver_baseline: rust_stdlib_semver_baseline,
} = toml_rust.unwrap_or_default();

let Llvm {
Expand Down Expand Up @@ -1594,6 +1597,7 @@ NOTE: Please add `--stage 2` to your command line, or if you're sure you want to
.or(rust_rustc_debug_assertions)
.unwrap_or(rust_debug == Some(true)),
stderr_is_tty: std::io::stderr().is_terminal(),
stdlib_semver_baseline: rust_stdlib_semver_baseline,
stdout_is_tty: std::io::stdout().is_terminal(),
submodules: build_submodules,
sysconfdir: install_sysconfdir.map(PathBuf::from),
Expand Down
2 changes: 2 additions & 0 deletions src/bootstrap/src/core/config/toml/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ define_config! {
std_features: Option<BTreeSet<String>> = "std-features",
break_on_ice: Option<bool> = "break-on-ice",
parallel_frontend_threads: Option<u32> = "parallel-frontend-threads",
stdlib_semver_baseline: Option<String> = "stdlib-semver-baseline",
}
}

Expand Down Expand Up @@ -384,6 +385,7 @@ pub fn check_incompatible_options_for_ci_rustc(
parallel_frontend_threads: _,
bootstrap_override_lld: _,
rustflags: _,
stdlib_semver_baseline: _,
} = ci_rust_config;

// There are two kinds of checks for CI rustc incompatible options:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM ubuntu:26.04

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
make \
ninja-build \
file \
curl \
ca-certificates \
python3 \
git \
cmake \
sudo \
gdb \
libssl-dev \
pkg-config \
xz-utils \
mingw-w64 \
zlib1g-dev \
libzstd-dev \
&& rm -rf /var/lib/apt/lists/*

COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

ENV RUST_CONFIGURE_ARGS="--build=x86_64-unknown-linux-gnu"

COPY /scripts/std-semver-check.sh /tmp/std-semver-check.sh
ENV SCRIPT="bash /tmp/std-semver-check.sh"
21 changes: 21 additions & 0 deletions src/ci/docker/scripts/std-semver-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

set -euo pipefail

BUILD_DIR=$(realpath ./build/x86_64-unknown-linux-gnu)

# Install the latest version of cargo-semver-checks, so that once the JSON doc format changes,
# we will eventually get a csc version that supports it
RUSTC="${BUILD_DIR}"/stage0/bin/rustc "${BUILD_DIR}"/stage0/bin/cargo install \
cargo-semver-checks --locked

# Provide path to cargo-semver-checks
export PATH=${PATH}:/cargo/bin

# Explicitly compute the baseline commit (the first git parent, which is the latest upstream main
# commit), so that it is shown in the commit log and so that the command can be easily reproduced
# locally.
PARENT=$(git rev-parse HEAD^1)

# Run the test
python3 ../x.py test std-semver-check --set rust.stdlib-semver-baseline=${PARENT}
3 changes: 3 additions & 0 deletions src/ci/github-actions/jobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,9 @@ auto:
- name: x86_64-gnu-miri
<<: *job-linux-4c

- name: x86_64-gnu-stdlib-semver-check
<<: *job-linux-4c
Comment thread
jieyouxu marked this conversation as resolved.
Comment thread
jieyouxu marked this conversation as resolved.
Comment thread
jieyouxu marked this conversation as resolved.

- name: optional-x86_64-gnu-autodiff
continue_on_error: true
doc_url: https://rustc-dev-guide.rust-lang.org/tests/autodiff-ci-job.html
Expand Down
Loading