Skip to content

Commit 519f92f

Browse files
committed
Upload the toolstate to the remote repository.
1 parent 0692b3d commit 519f92f

File tree

7 files changed

+230
-11
lines changed

7 files changed

+230
-11
lines changed

.travis.yml

+13
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,26 @@ matrix:
179179
- env: IMAGE=x86_64-gnu-incremental
180180
if: branch = auto
181181

182+
- stage: publish toolstate
183+
if: branch = master AND type = push
184+
before_install: []
185+
install: []
186+
cache: false
187+
sudo: false
188+
script:
189+
MESSAGE_FILE=$(mktemp -t msg.XXXXXX);
190+
. src/ci/docker/x86_64-gnu-tools/repo.sh;
191+
commit_toolstate_change "$MESSAGE_FILE" "$TRAVIS_BUILD_DIR/src/ci/docker/x86_64-gnu-tools/publish.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "$MESSAGE_FILE"
192+
182193
env:
183194
global:
184195
- SCCACHE_BUCKET=rust-lang-ci-sccache2
185196
- SCCACHE_REGION=us-west-1
186197
- AWS_ACCESS_KEY_ID=AKIAJAMV3QAMMA6AXHFQ
187198
# AWS_SECRET_ACCESS_KEY=...
188199
- secure: "j96XxTVOSUf4s4r4htIxn/fvIa5DWbMgLqWl7r8z2QfgUwscmkMXAwXuFNc7s7bGTpV/+CgDiMFFM6BAFLGKutytIF6oA02s9b+usQYnM0th7YQ2AIgm9GtMTJCJp4AoyfFmh8F2faUICBZlfVLUJ34udHEe35vOklix+0k4WDo="
200+
# TOOLSTATE_REPO_ACCESS_TOKEN=...
201+
- secure: "cFh8thThqEJLC98XKI5pfqflUzOlxsYPRW20AWRaYOOgYHPTiGWypTXiPbGSKaeAXTZoOA+DpQtEmefc0U6lt9dHc7a/MIaK6isFurjlnKYiLOeTruzyu1z7PWCeZ/jKXsU2RK/88DBtlNwfMdaMIeuKj14IVfpepPPL71ETbuk="
189202

190203
before_install:
191204
- zcat $HOME/docker/rust-ci.tar.gz | docker load || true

appveyor.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ environment:
55
AWS_SECRET_ACCESS_KEY:
66
secure: 7Y+JiquYedOAgnUU26uL0DPzrxmTtR+qIwG6rNKSuWDffqU3vVZxbGXim9QpTO80
77
SCCACHE_DIGEST: f808afabb4a4eb1d7112bcb3fa6be03b61e93412890c88e177c667eb37f46353d7ec294e559b16f9f4b5e894f2185fe7670a0df15fd064889ecbd80f0c34166c
8+
TOOLSTATE_REPO_ACCESS_TOKEN:
9+
secure: PTZiSxJMVUZ0VnMR5i13E4OagbXfglj7pcskDQiKufVrDm13mLoI0vDJAEM35+bY
810

911
# By default schannel checks revocation of certificates unlike some other SSL
1012
# backends, but we've historically had problems on CI where a revocation
@@ -27,8 +29,8 @@ environment:
2729

2830
# MSVC tools tests
2931
- MSYS_BITS: 64
30-
SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py toolstates.json
31-
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=toolstates.json --enable-test-miri
32+
SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows
33+
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri
3234

3335
# 32/64-bit MinGW builds.
3436
#

src/ci/docker/run.sh

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ exec docker \
9999
--env LOCAL_USER_ID=`id -u` \
100100
--env TRAVIS \
101101
--env TRAVIS_BRANCH \
102+
--env TOOLSTATE_REPO_ACCESS_TOKEN \
102103
--volume "$HOME/.cargo:/cargo" \
103104
--volume "$HOME/rustsrc:$HOME/rustsrc" \
104105
--init \

src/ci/docker/x86_64-gnu-tools/Dockerfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ COPY scripts/sccache.sh /scripts/
1818
RUN sh /scripts/sccache.sh
1919

2020
COPY x86_64-gnu-tools/checktools.sh /tmp/
21+
COPY x86_64-gnu-tools/repo.sh /tmp/
2122

2223
ENV RUST_CONFIGURE_ARGS \
2324
--build=x86_64-unknown-linux-gnu \
2425
--enable-test-miri \
2526
--save-toolstates=/tmp/toolstates.json
26-
ENV SCRIPT /tmp/checktools.sh ../x.py /tmp/toolstates.json
27+
ENV SCRIPT /tmp/checktools.sh ../x.py /tmp/toolstates.json linux

src/ci/docker/x86_64-gnu-tools/checktools.sh

+15-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
set -eu
1414

1515
X_PY="$1"
16-
TOOLSTATE_FILE="$2"
16+
TOOLSTATE_FILE="$(realpath $2)"
17+
OS="$3"
18+
COMMIT="$(git rev-parse HEAD)"
1719

1820
touch "$TOOLSTATE_FILE"
1921

@@ -23,17 +25,22 @@ python2.7 "$X_PY" test --no-fail-fast \
2325
src/tools/rustfmt \
2426
src/tools/miri \
2527
src/tools/clippy
26-
TEST_RESULT=$?
2728
set -e
2829

29-
# FIXME: Upload this file to the repository.
3030
cat "$TOOLSTATE_FILE"
3131

32-
# FIXME: After we can properly inform dev-tool maintainers about failure,
33-
# comment out the `exit 0` below.
3432
if [ "$RUST_RELEASE_CHANNEL" = nightly ]; then
35-
# exit 0
36-
true
33+
. "$(dirname $0)/repo.sh"
34+
MESSAGE_FILE=$(mktemp -t msg.XXXXXX)
35+
echo "($OS CI update)" > "$MESSAGE_FILE"
36+
commit_toolstate_change "$MESSAGE_FILE" \
37+
sed -i "1 a\\
38+
$COMMIT\t$(cat "$TOOLSTATE_FILE")
39+
" "history/$OS.tsv"
40+
rm -f "$MESSAGE_FILE"
41+
exit 0
3742
fi
3843

39-
exit $TEST_RESULT
44+
if grep -q 'Broken\|Compiling' "$TOOLSTATE_FILE"; then
45+
exit 4
46+
fi
+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
5+
# file at the top-level directory of this distribution and at
6+
# http://rust-lang.org/COPYRIGHT.
7+
#
8+
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
9+
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
10+
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
11+
# option. This file may not be copied, modified, or distributed
12+
# except according to those terms.
13+
14+
import sys
15+
import re
16+
import json
17+
import copy
18+
import datetime
19+
import collections
20+
21+
# List of people to ping when the status of a tool changed.
22+
MAINTAINERS = {
23+
'miri': '@oli-obk @RalfJung @eddyb',
24+
'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk',
25+
'rls': '@nrc',
26+
'rustfmt': '@nrc',
27+
}
28+
29+
30+
def read_current_status(current_commit, path):
31+
'''Reads build status of `current_commit` from content of `history/*.tsv`
32+
'''
33+
with open(path, 'rU') as f:
34+
for line in f:
35+
(commit, status) = line.split('\t', 1)
36+
if commit == current_commit:
37+
return json.loads(status)
38+
return {}
39+
40+
41+
def update_latest(current_commit, relevant_pr_number, current_datetime):
42+
'''Updates `_data/latest.json` to match build result of the given commit.
43+
'''
44+
with open('_data/latest.json', 'rb+') as f:
45+
latest = json.load(f, object_pairs_hook=collections.OrderedDict)
46+
47+
current_status = {
48+
os: read_current_status(current_commit, 'history/' + os + '.tsv')
49+
for os in ['windows', 'linux']
50+
}
51+
52+
slug = 'rust-lang/rust'
53+
message = '📣 Toolstate changed by {}!\n\nTested on commit {}@{}.\n\n' \
54+
.format(relevant_pr_number, slug, current_commit)
55+
anything_changed = False
56+
for status in latest:
57+
tool = status['tool']
58+
changed = False
59+
60+
for os, s in current_status.items():
61+
old = status[os]
62+
new = s.get(tool, old)
63+
status[os] = new
64+
if new > old:
65+
changed = True
66+
message += '🎉 {} on {}: {} → {}.\n' \
67+
.format(tool, os, old, new)
68+
elif new < old:
69+
changed = True
70+
message += '💔 {} on {}: {} → {} (cc {}).\n' \
71+
.format(tool, os, old, new, MAINTAINERS[tool])
72+
73+
if changed:
74+
status['commit'] = current_commit
75+
status['datetime'] = current_datetime
76+
anything_changed = True
77+
78+
if not anything_changed:
79+
return ''
80+
81+
f.seek(0)
82+
f.truncate(0)
83+
json.dump(latest, f, indent=4, separators=(',', ': '))
84+
return message
85+
86+
87+
if __name__ == '__main__':
88+
cur_commit = sys.argv[1]
89+
cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
90+
cur_commit_msg = sys.argv[2]
91+
save_message_to_path = sys.argv[3]
92+
93+
relevant_pr_match = re.search('#[0-9]+', cur_commit_msg)
94+
if relevant_pr_match:
95+
relevant_pr_number = 'rust-lang/rust' + relevant_pr_match.group(0)
96+
else:
97+
relevant_pr_number = '<unknown PR>'
98+
99+
message = update_latest(cur_commit, relevant_pr_number, cur_datetime)
100+
if message:
101+
print(message)
102+
with open(save_message_to_path, 'w') as f:
103+
f.write(message)
104+
else:
105+
print('<Nothing changed>')
+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/bin/sh
2+
3+
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
4+
# file at the top-level directory of this distribution and at
5+
# http://rust-lang.org/COPYRIGHT.
6+
#
7+
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8+
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9+
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10+
# option. This file may not be copied, modified, or distributed
11+
# except according to those terms.
12+
13+
# This file provides the function `commit_toolstate_change` for pushing a change
14+
# to the `rust-toolstate` repository.
15+
#
16+
# The function relies on a GitHub bot user, which should have a Personal access
17+
# token defined in the environment variable $TOOLSTATE_REPO_ACCESS_TOKEN. If for
18+
# some reason you need to change the token, please update `.travis.yml` and
19+
# `appveyor.yml`:
20+
#
21+
# 1. Generate a new Personal access token:
22+
#
23+
# * Login to the bot account, and go to Settings -> Developer settings ->
24+
# Personal access tokens
25+
# * Click "Generate new token"
26+
# * Enable the "public_repo" permission, then click "Generate token"
27+
# * Copy the generated token (should be a 40-digit hexadecimal number).
28+
# Save it somewhere secure, as the token would be gone once you leave
29+
# the page.
30+
#
31+
# 2. Encrypt the token for Travis CI
32+
#
33+
# * Install the `travis` tool locally (`gem install travis`).
34+
# * Encrypt the token:
35+
# ```
36+
# travis -r rust-lang/rust encrypt \
37+
# TOOLSTATE_REPO_ACCESS_TOKEN=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
38+
# ```
39+
# * Copy output to replace the existing one in `.travis.yml`.
40+
# * Details of this step can be found in
41+
# <https://docs.travis-ci.com/user/encryption-keys/>
42+
#
43+
# 3. Encrypt the token for AppVeyor
44+
#
45+
# * Login to AppVeyor using your main account, and login as the rust-lang
46+
# organization.
47+
# * Open the ["Encrypt data" tool](https://ci.appveyor.com/tools/encrypt)
48+
# * Paste the 40-digit token into the "Value to encrypt" box, then click
49+
# "Encrypt"
50+
# * Copy the output to replace the existing one in `appveyor.yml`.
51+
# * Details of this step can be found in
52+
# <https://www.appveyor.com/docs/how-to/git-push/>
53+
#
54+
# 4. Replace the email address below if the bot account identity is changed
55+
#
56+
# * See <https://help.github.com/articles/about-commit-email-addresses/>
57+
# if a private email by GitHub is wanted.
58+
59+
commit_toolstate_change() {
60+
OLDFLAGS="$-"
61+
set -eu
62+
63+
git config --global user.email '[email protected]'
64+
git config --global user.name 'Rust Toolstate Update'
65+
git config --global credential.helper store
66+
printf 'https://%s:[email protected]\n' "$TOOLSTATE_REPO_ACCESS_TOKEN" \
67+
> "$HOME/.git-credentials"
68+
git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git
69+
70+
cd rust-toolstate
71+
FAILURE=1
72+
MESSAGE_FILE="$1"
73+
shift
74+
for RETRY_COUNT in 1 2 3 4 5; do
75+
"$@"
76+
# `git commit` failing means nothing to commit.
77+
FAILURE=0
78+
git commit -a -F "$MESSAGE_FILE" || break
79+
# On failure randomly sleep for 0 to 3 seconds as a crude way to introduce jittering.
80+
git push origin master && break || sleep $(LC_ALL=C tr -cd 0-3 < /dev/urandom | head -c 1)
81+
FAILURE=1
82+
git fetch origin master
83+
git reset --hard origin/master
84+
done
85+
cd ..
86+
87+
set +eu
88+
set "-$OLDFLAGS"
89+
return $FAILURE
90+
}

0 commit comments

Comments
 (0)