Rollup merge of #48405 - kennytm:autotoolstate-follow-up, r=Mark-Simulacrum
Auto-toolstate management follow-up. Tracking comment: https://github.com/rust-lang/rust/issues/45861#issuecomment-367302777 * Fixed rust-lang-nursery/rust-toolstate#1, a proper link to the PR will be included. * Fixed rust-lang-nursery/rust-toolstate#2, a comment will be posted to the PR if the toolstate changed * Toolstate regression will be rejected at the last week of the 6-week cycle (currently entirely date-based). * Implemented https://internals.rust-lang.org/t/the-current-submodule-setup-is-not-tenable/6593, moved doc tests of Nomicon, Reference, Rust-by-Example and The Book to the "tools" job and thus allowed to fail like other external tools.
This commit is contained in:
@@ -188,7 +188,7 @@ matrix:
|
|||||||
script:
|
script:
|
||||||
MESSAGE_FILE=$(mktemp -t msg.XXXXXX);
|
MESSAGE_FILE=$(mktemp -t msg.XXXXXX);
|
||||||
. src/ci/docker/x86_64-gnu-tools/repo.sh;
|
. src/ci/docker/x86_64-gnu-tools/repo.sh;
|
||||||
commit_toolstate_change "$MESSAGE_FILE" "$TRAVIS_BUILD_DIR/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "$MESSAGE_FILE"
|
commit_toolstate_change "$MESSAGE_FILE" "$TRAVIS_BUILD_DIR/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "$MESSAGE_FILE" "$TOOLSTATE_REPO_ACCESS_TOKEN";
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ pub struct ShouldRun<'a> {
|
|||||||
paths: BTreeSet<PathSet>,
|
paths: BTreeSet<PathSet>,
|
||||||
|
|
||||||
// If this is a default rule, this is an additional constraint placed on
|
// If this is a default rule, this is an additional constraint placed on
|
||||||
// it's run. Generally something like compiler docs being enabled.
|
// its run. Generally something like compiler docs being enabled.
|
||||||
is_really_default: bool,
|
is_really_default: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +326,9 @@ impl<'a> Builder<'a> {
|
|||||||
test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty,
|
test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty,
|
||||||
test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::RunMake,
|
test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::RunMake,
|
||||||
test::Crate, test::CrateLibrustc, test::Rustdoc, test::Linkcheck, test::Cargotest,
|
test::Crate, test::CrateLibrustc, test::Rustdoc, test::Linkcheck, test::Cargotest,
|
||||||
test::Cargo, test::Rls, test::Docs, test::ErrorIndex, test::Distcheck,
|
test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck,
|
||||||
|
test::Nomicon, test::Reference, test::RustdocBook, test::RustByExample,
|
||||||
|
test::TheBook, test::UnstableBook,
|
||||||
test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme),
|
test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme),
|
||||||
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
|
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
|
||||||
Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
|
Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
|
||||||
|
|||||||
@@ -629,6 +629,8 @@ impl Step for CodegenBackend {
|
|||||||
.arg(build.src.join("src/librustc_trans/Cargo.toml"));
|
.arg(build.src.join("src/librustc_trans/Cargo.toml"));
|
||||||
rustc_cargo_env(build, &mut cargo);
|
rustc_cargo_env(build, &mut cargo);
|
||||||
|
|
||||||
|
let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage));
|
||||||
|
|
||||||
match &*self.backend {
|
match &*self.backend {
|
||||||
"llvm" | "emscripten" => {
|
"llvm" | "emscripten" => {
|
||||||
// Build LLVM for our target. This will implicitly build the
|
// Build LLVM for our target. This will implicitly build the
|
||||||
@@ -642,7 +644,6 @@ impl Step for CodegenBackend {
|
|||||||
features.push_str(" emscripten");
|
features.push_str(" emscripten");
|
||||||
}
|
}
|
||||||
|
|
||||||
let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage));
|
|
||||||
println!("Building stage{} codegen artifacts ({} -> {}, {})",
|
println!("Building stage{} codegen artifacts ({} -> {}, {})",
|
||||||
compiler.stage, &compiler.host, target, self.backend);
|
compiler.stage, &compiler.host, target, self.backend);
|
||||||
|
|
||||||
|
|||||||
@@ -78,15 +78,17 @@ fn try_run(build: &Build, cmd: &mut Command) -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_run_quiet(build: &Build, cmd: &mut Command) {
|
fn try_run_quiet(build: &Build, cmd: &mut Command) -> bool {
|
||||||
if !build.fail_fast {
|
if !build.fail_fast {
|
||||||
if !build.try_run_quiet(cmd) {
|
if !build.try_run_quiet(cmd) {
|
||||||
let mut failures = build.delayed_failures.borrow_mut();
|
let mut failures = build.delayed_failures.borrow_mut();
|
||||||
failures.push(format!("{:?}", cmd));
|
failures.push(format!("{:?}", cmd));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
build.run_quiet(cmd);
|
build.run_quiet(cmd);
|
||||||
}
|
}
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
@@ -994,23 +996,19 @@ impl Step for Compiletest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Docs {
|
struct DocTest {
|
||||||
compiler: Compiler,
|
compiler: Compiler,
|
||||||
|
path: &'static str,
|
||||||
|
name: &'static str,
|
||||||
|
is_ext_doc: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Step for Docs {
|
impl Step for DocTest {
|
||||||
type Output = ();
|
type Output = ();
|
||||||
const DEFAULT: bool = true;
|
|
||||||
const ONLY_HOSTS: bool = true;
|
const ONLY_HOSTS: bool = true;
|
||||||
|
|
||||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||||
run.path("src/doc")
|
run.never()
|
||||||
}
|
|
||||||
|
|
||||||
fn make_run(run: RunConfig) {
|
|
||||||
run.builder.ensure(Docs {
|
|
||||||
compiler: run.builder.compiler(run.builder.top_stage, run.host),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run `rustdoc --test` for all documentation in `src/doc`.
|
/// Run `rustdoc --test` for all documentation in `src/doc`.
|
||||||
@@ -1026,9 +1024,9 @@ impl Step for Docs {
|
|||||||
|
|
||||||
// Do a breadth-first traversal of the `src/doc` directory and just run
|
// Do a breadth-first traversal of the `src/doc` directory and just run
|
||||||
// tests for all files that end in `*.md`
|
// tests for all files that end in `*.md`
|
||||||
let mut stack = vec![build.src.join("src/doc")];
|
let mut stack = vec![build.src.join(self.path)];
|
||||||
let _time = util::timeit();
|
let _time = util::timeit();
|
||||||
let _folder = build.fold_output(|| "test_docs");
|
let _folder = build.fold_output(|| format!("test_{}", self.name));
|
||||||
|
|
||||||
while let Some(p) = stack.pop() {
|
while let Some(p) = stack.pop() {
|
||||||
if p.is_dir() {
|
if p.is_dir() {
|
||||||
@@ -1046,11 +1044,64 @@ impl Step for Docs {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
markdown_test(builder, compiler, &p);
|
let test_result = markdown_test(builder, compiler, &p);
|
||||||
|
if self.is_ext_doc {
|
||||||
|
let toolstate = if test_result {
|
||||||
|
ToolState::TestPass
|
||||||
|
} else {
|
||||||
|
ToolState::TestFail
|
||||||
|
};
|
||||||
|
build.save_toolstate(self.name, toolstate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! test_book {
|
||||||
|
($($name:ident, $path:expr, $book_name:expr, default=$default:expr;)+) => {
|
||||||
|
$(
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct $name {
|
||||||
|
compiler: Compiler,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Step for $name {
|
||||||
|
type Output = ();
|
||||||
|
const DEFAULT: bool = $default;
|
||||||
|
const ONLY_HOSTS: bool = true;
|
||||||
|
|
||||||
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||||
|
run.path($path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_run(run: RunConfig) {
|
||||||
|
run.builder.ensure($name {
|
||||||
|
compiler: run.builder.compiler(run.builder.top_stage, run.host),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(self, builder: &Builder) {
|
||||||
|
builder.ensure(DocTest {
|
||||||
|
compiler: self.compiler,
|
||||||
|
path: $path,
|
||||||
|
name: $book_name,
|
||||||
|
is_ext_doc: !$default,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_book!(
|
||||||
|
Nomicon, "src/doc/nomicon", "nomicon", default=false;
|
||||||
|
Reference, "src/doc/reference", "reference", default=false;
|
||||||
|
RustdocBook, "src/doc/rustdoc", "rustdoc", default=true;
|
||||||
|
RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false;
|
||||||
|
TheBook, "src/doc/book", "book", default=false;
|
||||||
|
UnstableBook, "src/doc/unstable-book", "unstable-book", default=true;
|
||||||
|
);
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct ErrorIndex {
|
pub struct ErrorIndex {
|
||||||
compiler: Compiler,
|
compiler: Compiler,
|
||||||
@@ -1101,13 +1152,13 @@ impl Step for ErrorIndex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) {
|
fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) -> bool {
|
||||||
let build = builder.build;
|
let build = builder.build;
|
||||||
let mut file = t!(File::open(markdown));
|
let mut file = t!(File::open(markdown));
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
t!(file.read_to_string(&mut contents));
|
t!(file.read_to_string(&mut contents));
|
||||||
if !contents.contains("```") {
|
if !contents.contains("```") {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("doc tests for: {}", markdown.display());
|
println!("doc tests for: {}", markdown.display());
|
||||||
@@ -1121,9 +1172,9 @@ fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) {
|
|||||||
cmd.arg("--test-args").arg(test_args);
|
cmd.arg("--test-args").arg(test_args);
|
||||||
|
|
||||||
if build.config.quiet_tests {
|
if build.config.quiet_tests {
|
||||||
try_run_quiet(build, &mut cmd);
|
try_run_quiet(build, &mut cmd)
|
||||||
} else {
|
} else {
|
||||||
try_run(build, &mut cmd);
|
try_run(build, &mut cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
COPY scripts/sccache.sh /scripts/
|
COPY scripts/sccache.sh /scripts/
|
||||||
RUN sh /scripts/sccache.sh
|
RUN sh /scripts/sccache.sh
|
||||||
|
|
||||||
|
COPY x86_64-gnu-tools/checkregression.py /tmp/
|
||||||
COPY x86_64-gnu-tools/checktools.sh /tmp/
|
COPY x86_64-gnu-tools/checktools.sh /tmp/
|
||||||
COPY x86_64-gnu-tools/repo.sh /tmp/
|
COPY x86_64-gnu-tools/repo.sh /tmp/
|
||||||
|
|
||||||
|
|||||||
40
src/ci/docker/x86_64-gnu-tools/checkregression.py
Executable file
40
src/ci/docker/x86_64-gnu-tools/checkregression.py
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
os_name = sys.argv[1]
|
||||||
|
toolstate_file = sys.argv[2]
|
||||||
|
current_state = sys.argv[3]
|
||||||
|
|
||||||
|
with open(toolstate_file, 'r') as f:
|
||||||
|
toolstate = json.load(f)
|
||||||
|
with open(current_state, 'r') as f:
|
||||||
|
current = json.load(f)
|
||||||
|
|
||||||
|
regressed = False
|
||||||
|
for cur in current:
|
||||||
|
tool = cur['tool']
|
||||||
|
state = cur[os_name]
|
||||||
|
new_state = toolstate.get(tool, '')
|
||||||
|
if new_state < state:
|
||||||
|
print(
|
||||||
|
'Error: The state of "{}" has regressed from "{}" to "{}"'
|
||||||
|
.format(tool, state, new_state)
|
||||||
|
)
|
||||||
|
regressed = True
|
||||||
|
|
||||||
|
if regressed:
|
||||||
|
sys.exit(1)
|
||||||
@@ -17,11 +17,18 @@ TOOLSTATE_FILE="$(realpath $2)"
|
|||||||
OS="$3"
|
OS="$3"
|
||||||
COMMIT="$(git rev-parse HEAD)"
|
COMMIT="$(git rev-parse HEAD)"
|
||||||
CHANGED_FILES="$(git diff --name-status HEAD HEAD^)"
|
CHANGED_FILES="$(git diff --name-status HEAD HEAD^)"
|
||||||
|
SIX_WEEK_CYCLE="$(( ($(date +%s) / 604800 - 3) % 6 ))"
|
||||||
|
# ^ 1970 Jan 1st is a Thursday, and our release dates are also on Thursdays,
|
||||||
|
# thus we could divide by 604800 (7 days in seconds) directly.
|
||||||
|
|
||||||
touch "$TOOLSTATE_FILE"
|
touch "$TOOLSTATE_FILE"
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
python2.7 "$X_PY" test --no-fail-fast \
|
python2.7 "$X_PY" test --no-fail-fast \
|
||||||
|
src/doc/book \
|
||||||
|
src/doc/nomicon \
|
||||||
|
src/doc/reference \
|
||||||
|
src/doc/rust-by-example \
|
||||||
src/tools/rls \
|
src/tools/rls \
|
||||||
src/tools/rustfmt \
|
src/tools/rustfmt \
|
||||||
src/tools/miri \
|
src/tools/miri \
|
||||||
@@ -29,27 +36,38 @@ python2.7 "$X_PY" test --no-fail-fast \
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
cat "$TOOLSTATE_FILE"
|
cat "$TOOLSTATE_FILE"
|
||||||
|
echo
|
||||||
|
|
||||||
# If this PR is intended to update one of these tools, do not let the build pass
|
verify_status() {
|
||||||
# when they do not test-pass.
|
echo "Verifying status of $1..."
|
||||||
for TOOL in rls rustfmt clippy; do
|
if echo "$CHANGED_FILES" | grep -q "^M[[:blank:]]$2$"; then
|
||||||
echo "Verifying status of $TOOL..."
|
echo "This PR updated '$2', verifying if status is 'test-pass'..."
|
||||||
if echo "$CHANGED_FILES" | grep -q "^M[[:blank:]]src/tools/$TOOL$"; then
|
if grep -vq '"'"$1"'":"test-pass"' "$TOOLSTATE_FILE"; then
|
||||||
echo "This PR updated 'src/tools/$TOOL', verifying if status is 'test-pass'..."
|
|
||||||
if grep -vq '"'"$TOOL"'[^"]*":"test-pass"' "$TOOLSTATE_FILE"; then
|
|
||||||
echo
|
echo
|
||||||
echo "⚠️ We detected that this PR updated '$TOOL', but its tests failed."
|
echo "⚠️ We detected that this PR updated '$1', but its tests failed."
|
||||||
echo
|
echo
|
||||||
echo "If you do intend to update '$TOOL', please check the error messages above and"
|
echo "If you do intend to update '$1', please check the error messages above and"
|
||||||
echo "commit another update."
|
echo "commit another update."
|
||||||
echo
|
echo
|
||||||
echo "If you do NOT intend to update '$TOOL', please ensure you did not accidentally"
|
echo "If you do NOT intend to update '$1', please ensure you did not accidentally"
|
||||||
echo "change the submodule at 'src/tools/$TOOL'. You may ask your reviewer for the"
|
echo "change the submodule at '$2'. You may ask your reviewer for the"
|
||||||
echo "proper steps."
|
echo "proper steps."
|
||||||
exit 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
}
|
||||||
|
|
||||||
|
# If this PR is intended to update one of these tools, do not let the build pass
|
||||||
|
# when they do not test-pass.
|
||||||
|
|
||||||
|
verify_status book src/doc/book
|
||||||
|
verify_status nomicon src/doc/nomicon
|
||||||
|
verify_status reference src/doc/reference
|
||||||
|
verify_status rust-by-example src/doc/rust-by-example
|
||||||
|
verify_status rls src/tool/rls
|
||||||
|
verify_status rustfmt src/tool/rustfmt
|
||||||
|
verify_status clippy-driver src/tool/clippy
|
||||||
|
#verify_status miri src/tool/miri
|
||||||
|
|
||||||
if [ "$RUST_RELEASE_CHANNEL" = nightly -a -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then
|
if [ "$RUST_RELEASE_CHANNEL" = nightly -a -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then
|
||||||
. "$(dirname $0)/repo.sh"
|
. "$(dirname $0)/repo.sh"
|
||||||
@@ -59,6 +77,11 @@ if [ "$RUST_RELEASE_CHANNEL" = nightly -a -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_s
|
|||||||
sed -i "1 a\\
|
sed -i "1 a\\
|
||||||
$COMMIT\t$(cat "$TOOLSTATE_FILE")
|
$COMMIT\t$(cat "$TOOLSTATE_FILE")
|
||||||
" "history/$OS.tsv"
|
" "history/$OS.tsv"
|
||||||
|
# if we are at the last week in the 6-week release cycle, reject any kind of regression.
|
||||||
|
if [ $SIX_WEEK_CYCLE -eq 5 ]; then
|
||||||
|
python2.7 "$(dirname $0)/checkregression.py" \
|
||||||
|
"$OS" "$TOOLSTATE_FILE" "rust-toolstate/_data/latest.json"
|
||||||
|
fi
|
||||||
rm -f "$MESSAGE_FILE"
|
rm -f "$MESSAGE_FILE"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ import json
|
|||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
import collections
|
import collections
|
||||||
|
import textwrap
|
||||||
|
try:
|
||||||
|
import urllib2
|
||||||
|
except ImportError:
|
||||||
|
import urllib.request as urllib2
|
||||||
|
|
||||||
# List of people to ping when the status of a tool changed.
|
# List of people to ping when the status of a tool changed.
|
||||||
MAINTAINERS = {
|
MAINTAINERS = {
|
||||||
@@ -24,6 +29,10 @@ MAINTAINERS = {
|
|||||||
'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk',
|
'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk',
|
||||||
'rls': '@nrc',
|
'rls': '@nrc',
|
||||||
'rustfmt': '@nrc',
|
'rustfmt': '@nrc',
|
||||||
|
'book': '@carols10cents @steveklabnik',
|
||||||
|
'nomicon': '@frewsxcv @Gankro',
|
||||||
|
'reference': '@steveklabnik @Havvy @matthewjasper @alercah',
|
||||||
|
'rust-by-example': '@steveklabnik @marioidival @projektir',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +47,12 @@ def read_current_status(current_commit, path):
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def update_latest(current_commit, relevant_pr_number, current_datetime):
|
def update_latest(
|
||||||
|
current_commit,
|
||||||
|
relevant_pr_number,
|
||||||
|
relevant_pr_url,
|
||||||
|
current_datetime
|
||||||
|
):
|
||||||
'''Updates `_data/latest.json` to match build result of the given commit.
|
'''Updates `_data/latest.json` to match build result of the given commit.
|
||||||
'''
|
'''
|
||||||
with open('_data/latest.json', 'rb+') as f:
|
with open('_data/latest.json', 'rb+') as f:
|
||||||
@@ -50,8 +64,13 @@ def update_latest(current_commit, relevant_pr_number, current_datetime):
|
|||||||
}
|
}
|
||||||
|
|
||||||
slug = 'rust-lang/rust'
|
slug = 'rust-lang/rust'
|
||||||
message = '📣 Toolstate changed by {}!\n\nTested on commit {}@{}.\n\n' \
|
message = textwrap.dedent('''\
|
||||||
.format(relevant_pr_number, slug, current_commit)
|
📣 Toolstate changed by {}!
|
||||||
|
|
||||||
|
Tested on commit {}@{}.
|
||||||
|
Direct link to PR: <{}>
|
||||||
|
|
||||||
|
''').format(relevant_pr_number, slug, current_commit, relevant_pr_url)
|
||||||
anything_changed = False
|
anything_changed = False
|
||||||
for status in latest:
|
for status in latest:
|
||||||
tool = status['tool']
|
tool = status['tool']
|
||||||
@@ -68,7 +87,7 @@ def update_latest(current_commit, relevant_pr_number, current_datetime):
|
|||||||
elif new < old:
|
elif new < old:
|
||||||
changed = True
|
changed = True
|
||||||
message += '💔 {} on {}: {} → {} (cc {}).\n' \
|
message += '💔 {} on {}: {} → {} (cc {}).\n' \
|
||||||
.format(tool, os, old, new, MAINTAINERS[tool])
|
.format(tool, os, old, new, MAINTAINERS.get(tool))
|
||||||
|
|
||||||
if changed:
|
if changed:
|
||||||
status['commit'] = current_commit
|
status['commit'] = current_commit
|
||||||
@@ -89,17 +108,41 @@ if __name__ == '__main__':
|
|||||||
cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
|
cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
cur_commit_msg = sys.argv[2]
|
cur_commit_msg = sys.argv[2]
|
||||||
save_message_to_path = sys.argv[3]
|
save_message_to_path = sys.argv[3]
|
||||||
|
github_token = sys.argv[4]
|
||||||
|
|
||||||
relevant_pr_match = re.search('#[0-9]+', cur_commit_msg)
|
relevant_pr_match = re.search('#([0-9]+)', cur_commit_msg)
|
||||||
if relevant_pr_match:
|
if relevant_pr_match:
|
||||||
relevant_pr_number = 'rust-lang/rust' + relevant_pr_match.group(0)
|
number = relevant_pr_match.group(1)
|
||||||
|
relevant_pr_number = 'rust-lang/rust#' + number
|
||||||
|
relevant_pr_url = 'https://github.com/rust-lang/rust/pull/' + number
|
||||||
else:
|
else:
|
||||||
|
number = '-1'
|
||||||
relevant_pr_number = '<unknown PR>'
|
relevant_pr_number = '<unknown PR>'
|
||||||
|
relevant_pr_url = '<unknown>'
|
||||||
|
|
||||||
|
message = update_latest(
|
||||||
|
cur_commit,
|
||||||
|
relevant_pr_number,
|
||||||
|
relevant_pr_url,
|
||||||
|
cur_datetime
|
||||||
|
)
|
||||||
|
if not message:
|
||||||
|
print('<Nothing changed>')
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
message = update_latest(cur_commit, relevant_pr_number, cur_datetime)
|
|
||||||
if message:
|
|
||||||
print(message)
|
print(message)
|
||||||
with open(save_message_to_path, 'w') as f:
|
with open(save_message_to_path, 'w') as f:
|
||||||
f.write(message)
|
f.write(message)
|
||||||
else:
|
|
||||||
print('<Nothing changed>')
|
# Write the toolstate comment on the PR as well.
|
||||||
|
gh_url = 'https://api.github.com/repos/rust-lang/rust/issues/{}/comments' \
|
||||||
|
.format(number)
|
||||||
|
response = urllib2.urlopen(urllib2.Request(
|
||||||
|
gh_url,
|
||||||
|
json.dumps({'body': message}),
|
||||||
|
{
|
||||||
|
'Authorization': 'token ' + github_token,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
))
|
||||||
|
response.read()
|
||||||
|
|||||||
Reference in New Issue
Block a user