Skip to content

Commit f7b95e3

Browse files
committed
Auto merge of #12181 - weihanglo:which-channel-backport, r=ehuss
chore: detect the channel a PR wants to merge into ### What does this PR try to resolve? This detects which channel a pull request wants to merge into. It is hard because bors runs in a different repo. Bors knows nothing about branches or tag in this repo. It only see one base commit and a merge commit AFAIK. Basically the assumption and idea are 1. bors create a merge commit, so `HEAD~` should find the base branch. 2. Cargo maintains `rust-1.y.0` branch for each Rust minor version releases. Therefore, we can use the symbolic name of `origin/rust-1.x.0` to determine if it aims for stable, beta, or nightly channel. 3. After we know which channel it is targeted at, we can skip jobs that are likely to be broken.
2 parents 202eb1d + 40be718 commit f7b95e3

File tree

3 files changed

+165
-33
lines changed

3 files changed

+165
-33
lines changed

.github/workflows/main.yml

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@ env:
1616
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
1717

1818
jobs:
19+
# Determine which channel will be merged into.
20+
channel:
21+
runs-on: ubuntu-latest
22+
outputs:
23+
CHANNEL: ${{ steps.channel.outputs.CHANNEL }}
24+
env:
25+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
26+
steps:
27+
- uses: actions/checkout@v3
28+
with:
29+
fetch-depth: 0 # fetch all branches
30+
- id: channel
31+
run: ci/which-channel.sh
32+
1933
# Check Code style quickly by running `rustfmt` over all code
2034
rustfmt:
2135
runs-on: ubuntu-latest
@@ -63,8 +77,42 @@ jobs:
6377
- run: rustup update stable && rustup default stable
6478
- run: ci/validate-version-bump.sh
6579

80+
# Generate strategy matrix for different platforms and channels
81+
# (see ci/matrix.json)
82+
matrix:
83+
runs-on: ubuntu-latest
84+
needs:
85+
- channel
86+
outputs:
87+
matrix: ${{ steps.matrix.outputs.matrix }}
88+
steps:
89+
- uses: actions/checkout@v3
90+
- name: Generate strategy matrix
91+
id: matrix
92+
run: |
93+
CHANNEL=${{ needs.channel.outputs.CHANNEL }}
94+
95+
# This reads ci/matrix.json and then filters the environment we want to
96+
# build on, based on the channel this PR want to merge into.
97+
#
98+
# * For stable, we build only on stable toolchain.
99+
# * For beta, we build on stable and beta.
100+
# * For nightly, we build on stable, beta, and nightly.
101+
MATRIX=$(
102+
jq --arg C "$CHANNEL" 'map (. |
103+
if ($C == "beta") then select(.rust | startswith("nightly") | not)
104+
elif ($C == "stable") then select(.rust | startswith("stable"))
105+
else . end)' ci/matrix.json
106+
)
107+
echo "$MATRIX"
108+
109+
# Outputs as Job's outputs for other jobs to reuse.
110+
echo "MATRIX={\"include\":$(echo $MATRIX)}" >> "$GITHUB_OUTPUT"
111+
66112
test:
67113
runs-on: ${{ matrix.os }}
114+
needs:
115+
- matrix
68116
env:
69117
CARGO_PROFILE_DEV_DEBUG: 1
70118
CARGO_PROFILE_TEST_DEBUG: 1
@@ -73,36 +121,7 @@ jobs:
73121
# Deny warnings on CI to avoid warnings getting into the codebase.
74122
RUSTFLAGS: -D warnings
75123
strategy:
76-
matrix:
77-
include:
78-
- name: Linux x86_64 stable
79-
os: ubuntu-latest
80-
rust: stable
81-
other: i686-unknown-linux-gnu
82-
- name: Linux x86_64 beta
83-
os: ubuntu-latest
84-
rust: beta
85-
other: i686-unknown-linux-gnu
86-
- name: Linux x86_64 nightly
87-
os: ubuntu-latest
88-
rust: nightly
89-
other: i686-unknown-linux-gnu
90-
- name: macOS x86_64 stable
91-
os: macos-latest
92-
rust: stable
93-
other: x86_64-apple-ios
94-
- name: macOS x86_64 nightly
95-
os: macos-latest
96-
rust: nightly
97-
other: x86_64-apple-ios
98-
- name: Windows x86_64 MSVC stable
99-
os: windows-latest
100-
rust: stable-msvc
101-
other: i686-pc-windows-msvc
102-
- name: Windows x86_64 gnu nightly # runs out of space while trying to link the test suite
103-
os: windows-latest
104-
rust: nightly-gnu
105-
other: i686-pc-windows-gnu
124+
matrix: ${{ fromJSON(needs.matrix.outputs.MATRIX) }}
106125
name: Tests ${{ matrix.name }}
107126
steps:
108127
- uses: actions/checkout@v3
@@ -180,6 +199,9 @@ jobs:
180199

181200
build_std:
182201
runs-on: ubuntu-latest
202+
needs:
203+
- channel
204+
if: needs.channel.outputs.CHANNEL == 'master'
183205
steps:
184206
- uses: actions/checkout@v3
185207
- run: rustup update nightly && rustup default nightly
@@ -190,6 +212,8 @@ jobs:
190212
CARGO_RUN_BUILD_STD_TESTS: 1
191213
docs:
192214
runs-on: ubuntu-latest
215+
needs:
216+
- channel
193217
steps:
194218
- uses: actions/checkout@v3
195219
- run: rustup update nightly && rustup default nightly
@@ -211,22 +235,36 @@ jobs:
211235
- run: cd src/doc && mdbook build --dest-dir ../../target/doc
212236
- name: Run linkchecker.sh
213237
run: |
238+
BRANCH=${{ needs.channel.outputs.CHANNEL }}
214239
cd target
215-
curl -sSLO https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh
240+
curl -sSLO "https://raw.githubusercontent.com/rust-lang/rust/$BRANCH/src/tools/linkchecker/linkcheck.sh"
216241
sh linkcheck.sh --all --path ../src/doc cargo
217242
243+
# Jobs that may be skipped if they aren't going to merge into master (nightly).
244+
#
245+
# This is needed because GitHub Actions treats success() as false if a job is
246+
# skipped, and the bors success/failure jobs below need to ignore skipped jobs.
247+
z-nightly-jobs:
248+
needs:
249+
- channel
250+
- build_std
251+
if: "(needs.channel.outputs.CHANNEL != 'master' && !failure()) || success()"
252+
runs-on: ubuntu-latest
253+
steps:
254+
- run: exit 0
255+
218256
success:
219257
permissions:
220258
contents: none
221259
name: bors build finished
222260
needs:
223-
- build_std
224261
- docs
225262
- lockfile
226263
- resolver
227264
- rustfmt
228265
- test
229266
- test_gitoxide
267+
- z-nightly-jobs
230268
runs-on: ubuntu-latest
231269
if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto-cargo'"
232270
steps:
@@ -236,13 +274,13 @@ jobs:
236274
contents: none
237275
name: bors build finished
238276
needs:
239-
- build_std
240277
- docs
241278
- lockfile
242279
- resolver
243280
- rustfmt
244281
- test
245282
- test_gitoxide
283+
- z-nightly-jobs
246284
runs-on: ubuntu-latest
247285
if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto-cargo'"
248286
steps:

ci/matrix.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[
2+
{
3+
"name": "Linux x86_64 stable",
4+
"os": "ubuntu-latest",
5+
"rust": "stable",
6+
"other": "i686-unknown-linux-gnu"
7+
},
8+
{
9+
"name": "Linux x86_64 beta",
10+
"os": "ubuntu-latest",
11+
"rust": "beta",
12+
"other": "i686-unknown-linux-gnu"
13+
},
14+
{
15+
"name": "Linux x86_64 nightly",
16+
"os": "ubuntu-latest",
17+
"rust": "nightly",
18+
"other": "i686-unknown-linux-gnu"
19+
},
20+
{
21+
"name": "macOS x86_64 stable",
22+
"os": "macos-latest",
23+
"rust": "stable",
24+
"other": "x86_64-apple-ios"
25+
},
26+
{
27+
"name": "macOS x86_64 nightly",
28+
"os": "macos-latest",
29+
"rust": "nightly",
30+
"other": "x86_64-apple-ios"
31+
},
32+
{
33+
"name": "Windows x86_64 MSVC stable",
34+
"os": "windows-latest",
35+
"rust": "stable-msvc",
36+
"other": "i686-pc-windows-msvc"
37+
},
38+
{
39+
"name": "Windows x86_64 gnu nightly",
40+
"os": "windows-latest",
41+
"rust": "nightly-gnu",
42+
"other": "i686-pc-windows-gnu"
43+
}
44+
]

ci/which-channel.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/bash
2+
# This script outputs the channel where a CI workflow wants to merge into.
3+
#
4+
# Inputs:
5+
# BASE_SHA The commit SHA of the branch where the PR wants to merge into.
6+
#
7+
# GitHub Action Outputs:
8+
# CHANNEL Target channel where the PR wants to merge into.
9+
10+
set -euo pipefail
11+
12+
# When `BASE_SHA` is missing, we assume it is from bors merge commit,
13+
# so hope `HEAD~` to find the previous commit on master branch.
14+
base_sha=$(git rev-parse "${BASE_SHA:-HEAD~1}")
15+
16+
# Get symbolic names for the base_sha.
17+
# Assumption: Cargo branches are always in the format of `rust-1.*.0`,
18+
# otherwise `git name-rev` will return "undefined".
19+
ref=$(git name-rev --name-only --refs='origin/rust-1.*.0' $base_sha)
20+
21+
# Get the latest `rust-1.*.0` branch from remote origin.
22+
# Assumption: The latest branch is always beta branch.
23+
beta=$(
24+
git branch --remotes --list 'origin/rust-1.*.0' \
25+
| sort --version-sort \
26+
| tail -n1 \
27+
| tr -d "[:space:]"
28+
)
29+
30+
master=$(git rev-parse origin/master)
31+
32+
# Backport pull requests always target at a `rust-1.*.0` branch.
33+
if [[ "$ref" = "undefined" ]] || [[ "$base_sha" = "$master" ]]
34+
then
35+
# Should be nightly but for convenience in CI let's call it master.
36+
channel="master"
37+
elif [[ "$ref" = "$beta" ]]
38+
then
39+
channel="beta"
40+
else
41+
channel="stable"
42+
fi
43+
44+
echo "Base sha: $base_sha"
45+
echo "Git Ref: $ref"
46+
echo "master: $master"
47+
echo "beta: $beta"
48+
echo "Channel: $channel"
49+
50+
echo "CHANNEL=$channel" >> "$GITHUB_OUTPUT"

0 commit comments

Comments
 (0)