Rollup merge of #64451 - RalfJung:miri-manifest, r=pietroalbini
when Miri tests are not passing, do not add Miri component This makes build-manifest query the toolstate repo at https://github.com/rust-lang-nursery/rust-toolstate to figure out if the tests of the Miri component are passing. If they are not, we remove the component from the manifest, to avoid shipping a broken Miri. I tested this locally by running build-manifest and making sure that it correctly detects the toolstate of 02785dabad07d19b8c76a7f86763801d5d3497ff as broken. r? @pietroalbini Cc @kennytm @alexcrichton Fixes https://github.com/rust-lang/rust/issues/60301
This commit is contained in:
commit
7975973e2b
@ -201,7 +201,9 @@ dependencies = [
|
|||||||
name = "build-manifest"
|
name = "build-manifest"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2000,6 +2000,8 @@ impl Step for HashSign {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(self, builder: &Builder<'_>) {
|
fn run(self, builder: &Builder<'_>) {
|
||||||
|
// This gets called by `promote-release`
|
||||||
|
// (https://github.com/rust-lang/rust-central-station/tree/master/promote-release).
|
||||||
let mut cmd = builder.tool_cmd(Tool::BuildManifest);
|
let mut cmd = builder.tool_cmd(Tool::BuildManifest);
|
||||||
if builder.config.dry_run {
|
if builder.config.dry_run {
|
||||||
return;
|
return;
|
||||||
@ -2010,10 +2012,14 @@ impl Step for HashSign {
|
|||||||
let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
|
let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
|
||||||
panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
|
panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
|
||||||
});
|
});
|
||||||
let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
|
let pass = if env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err() {
|
||||||
panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
|
let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
|
||||||
});
|
panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
|
||||||
let pass = t!(fs::read_to_string(&file));
|
});
|
||||||
|
t!(fs::read_to_string(&file))
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
|
||||||
let today = output(Command::new("date").arg("+%Y-%m-%d"));
|
let today = output(Command::new("date").arg("+%Y-%m-%d"));
|
||||||
|
|
||||||
|
@ -7,3 +7,5 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
reqwest = "0.9"
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
|
//! Build a dist manifest, hash and sign everything.
|
||||||
|
//! This gets called by `promote-release`
|
||||||
|
//! (https://github.com/rust-lang/rust-central-station/tree/master/promote-release)
|
||||||
|
//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
|
||||||
|
//! by rustbuild (in `src/bootstrap/dist.rs`).
|
||||||
|
|
||||||
use toml;
|
use toml;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write, BufRead, BufReader};
|
||||||
use std::path::{PathBuf, Path};
|
use std::path::{PathBuf, Path};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
static HOSTS: &[&str] = &[
|
static HOSTS: &[&str] = &[
|
||||||
"aarch64-unknown-linux-gnu",
|
"aarch64-unknown-linux-gnu",
|
||||||
@ -146,6 +153,9 @@ static MINGW: &[&str] = &[
|
|||||||
"x86_64-pc-windows-gnu",
|
"x86_64-pc-windows-gnu",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
static TOOLSTATE: &str =
|
||||||
|
"https://raw.githubusercontent.com/rust-lang-nursery/rust-toolstate/master/history/linux.tsv";
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
struct Manifest {
|
struct Manifest {
|
||||||
@ -270,6 +280,7 @@ fn main() {
|
|||||||
// Do not ask for a passphrase while manually testing
|
// Do not ask for a passphrase while manually testing
|
||||||
let mut passphrase = String::new();
|
let mut passphrase = String::new();
|
||||||
if should_sign {
|
if should_sign {
|
||||||
|
// `x.py` passes the passphrase via stdin.
|
||||||
t!(io::stdin().read_to_string(&mut passphrase));
|
t!(io::stdin().read_to_string(&mut passphrase));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,6 +364,7 @@ impl Builder {
|
|||||||
self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
|
self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
|
||||||
self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
|
self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
|
||||||
|
|
||||||
|
self.check_toolstate();
|
||||||
self.digest_and_sign();
|
self.digest_and_sign();
|
||||||
let manifest = self.build_manifest();
|
let manifest = self.build_manifest();
|
||||||
self.write_channel_files(&self.rust_release, &manifest);
|
self.write_channel_files(&self.rust_release, &manifest);
|
||||||
@ -362,6 +374,37 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If a tool does not pass its tests, don't ship it.
|
||||||
|
/// Right now, we do this only for Miri.
|
||||||
|
fn check_toolstate(&mut self) {
|
||||||
|
// Get the toolstate for this rust revision.
|
||||||
|
let rev = self.rust_git_commit_hash.as_ref().expect("failed to determine rust git hash");
|
||||||
|
let toolstates = reqwest::get(TOOLSTATE).expect("failed to get toolstates");
|
||||||
|
let toolstates = BufReader::new(toolstates);
|
||||||
|
let toolstate = toolstates.lines()
|
||||||
|
.find_map(|line| {
|
||||||
|
let line = line.expect("failed to read toolstate lines");
|
||||||
|
let mut pieces = line.splitn(2, '\t');
|
||||||
|
let commit = pieces.next().expect("malformed toolstate line");
|
||||||
|
if commit != rev {
|
||||||
|
// Not the right commit.
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// Return the 2nd piece, the JSON.
|
||||||
|
Some(pieces.next().expect("malformed toolstate line").to_owned())
|
||||||
|
})
|
||||||
|
.expect("failed to find toolstate for rust commit");
|
||||||
|
let toolstate: HashMap<String, String> =
|
||||||
|
serde_json::from_str(&toolstate).expect("toolstate is malformed JSON");
|
||||||
|
// Mark some tools as missing based on toolstate.
|
||||||
|
if toolstate.get("miri").map(|s| &*s as &str) != Some("test-pass") {
|
||||||
|
println!("Miri tests are not passing, removing component");
|
||||||
|
self.miri_version = None;
|
||||||
|
self.miri_git_commit_hash = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
|
||||||
fn digest_and_sign(&mut self) {
|
fn digest_and_sign(&mut self) {
|
||||||
for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
|
for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
|
||||||
let filename = file.file_name().unwrap().to_str().unwrap();
|
let filename = file.file_name().unwrap().to_str().unwrap();
|
||||||
@ -532,19 +575,20 @@ impl Builder {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|version| (version, true))
|
.map(|version| (version, true))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default(); // `is_present` defaults to `false` here.
|
||||||
|
|
||||||
// miri needs to build std with xargo, which doesn't allow stable/beta:
|
// Miri is nightly-only; never ship it for other trains.
|
||||||
// <https://github.com/japaric/xargo/pull/204#issuecomment-374888868>
|
|
||||||
if pkgname == "miri-preview" && self.rust_release != "nightly" {
|
if pkgname == "miri-preview" && self.rust_release != "nightly" {
|
||||||
is_present = false; // ignore it
|
is_present = false; // Pretend the component is entirely missing.
|
||||||
}
|
}
|
||||||
|
|
||||||
let targets = targets.iter().map(|name| {
|
let targets = targets.iter().map(|name| {
|
||||||
if is_present {
|
if is_present {
|
||||||
|
// The component generally exists, but it might still be missing for this target.
|
||||||
let filename = self.filename(pkgname, name);
|
let filename = self.filename(pkgname, name);
|
||||||
let digest = match self.digests.remove(&filename) {
|
let digest = match self.digests.remove(&filename) {
|
||||||
Some(digest) => digest,
|
Some(digest) => digest,
|
||||||
|
// This component does not exist for this target -- skip it.
|
||||||
None => return (name.to_string(), Target::unavailable()),
|
None => return (name.to_string(), Target::unavailable()),
|
||||||
};
|
};
|
||||||
let xz_filename = filename.replace(".tar.gz", ".tar.xz");
|
let xz_filename = filename.replace(".tar.gz", ".tar.xz");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user