-
-
Notifications
You must be signed in to change notification settings - Fork 78
196 lines (171 loc) · 7.18 KB
/
add_new_rust_to_matrix.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# Automatically add Rust minor versions to our test matrix as they are released.
#
# Note: we use `stable` to refer to the most recent stable Rust release.
# This means that when a new Rust minor version is released, this job will add
# the *previous* (already-existing) minor version to the test matrix. The newly-released
# version is `stable` so it's automatically part of the test matrix.
---
name: Add next Rust minor to test matrix
on:
schedule:
# Rust releases are every 6 weeks, but cron doesn't seem to support 6-week intervals.
# Run weekly on Thursday afternoons: 5/6ths of the runs won't find a new release.
- cron: '37 18 * * THU'
workflow_dispatch:
# Needed so we can run it manually
permissions:
contents: read
defaults:
run:
shell: bash
env:
PR_TITLE: Add next Rust minor to test matrix
PR_MESSAGE: |
Automation to ensure we test on all supported Rust versions as new stable Rust versions are released.
The following is the output from `git diff`:
jobs:
update-ci-yml:
if: github.repository_owner == 'obi1kenobi'
name: update Rust version matrix
runs-on: ubuntu-latest
steps:
- name: checkout the source code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: download yq
env:
VERSION: "v4.43.1"
run: |
set -euxo pipefail
wget "https://github.com/mikefarah/yq/releases/download/${VERSION}/yq_linux_amd64" -O yq &&\
chmod +x ./yq
- name: check if the new Rust release is out
run: |
set -euxo pipefail
UPCOMING="$(yq '.jobs.rust-tests.strategy.matrix.toolchain as $versions |
[$versions[] | select(. != "beta" and . != "stable")] as $numerical_versions |
[$versions[] | select(. == "beta" or . == "stable")] as $non_numerical_versions |
(
[$numerical_versions[] | sub("\d+\.(\d+)(?:\.\d+)?", "${1}") | to_number]
| sort
| .[-1]
) as $max_named_minor |
"1.\($max_named_minor + 2).0"
' .github/workflows/ci.yml)"
# This line will fail if that release isn't out yet.
wget "https://github.com/rust-lang/rust/releases/tag/${UPCOMING}" --server-response -O /dev/null
- name: add next minor to test matrix
run: |
set -euxo pipefail
yq '.jobs.rust-tests.strategy.matrix.toolchain' .github/workflows/ci.yml -o json | \
python -m json.tool --compact | \
sed 's/,/, /g' \
>.current_versions
yq '.jobs.rust-tests.strategy.matrix.toolchain as $versions |
[$versions[] | select(. != "beta" and . != "stable")] as $numerical_versions |
[$versions[] | select(. == "beta" or . == "stable")] as $non_numerical_versions |
(
[$numerical_versions[] | sub("\d+\.(\d+)(?:\.\d+)?", "${1}") | to_number]
| sort
| .[-1]
) as $max_named_minor |
[$numerical_versions[], "1.\($max_named_minor + 1)", $non_numerical_versions[]] as $next_versions |
$next_versions
' .github/workflows/ci.yml -o json | \
python -m json.tool --compact | \
sed 's/,/, /g' \
>.next_versions
CURRENT="$(cat .current_versions | sed 's/^/\\/g' | sed 's/\]/\\]/g')"
NEXT="$(cat .next_versions)"
sed -i "s/$CURRENT/$NEXT/g" .github/workflows/ci.yml
- name: upload ci.yml artifact for use in PR
uses: actions/upload-artifact@v4
with:
name: ci.yml
path: .github/workflows/ci.yml
retention-days: 1
if-no-files-found: error
pr-ci-yml:
if: github.repository_owner == 'obi1kenobi'
name: open or amend PR
needs: update-ci-yml
runs-on: ubuntu-latest
env:
BRANCH_NAME: add_new_rust_to_matrix
permissions:
contents: write
pull-requests: write
steps:
- name: checkout the source code
uses: actions/checkout@v4
with:
# We have to use a Personal Access Token (PAT) here.
# We are going to open a PR with changes to workflows, which requires a special permission
# that normal GitHub Actions runs don't have.
token: ${{ secrets.RUST_UPDATER_GITHUB_TOKEN }}
persist-credentials: true
- name: download ci.yml from update job
uses: actions/download-artifact@v4
with:
name: ci.yml
path: .github/workflows/
- name: craft PR body and commit message
run: |
set -euo pipefail
DIFF="$(git diff)"
echo "${PR_MESSAGE}" > body.md
echo '```diff' >> body.md
echo "$DIFF" >> body.md
echo '```' >> body.md
- name: commit
run: |
set -euxo pipefail
git config user.name github-actions
git config user.email [email protected]
git switch --force-create "$BRANCH_NAME"
git add ./.github/workflows/ci.yml
DIFF="$(git diff --staged)"
if [[ "$DIFF" == "" ]]; then
echo >2 "./.github/workflows/ci.yml was not changed, bailing out and not making a PR"
exit 1
fi
git commit --no-verify --file=body.md
- name: push
run: |
set -euo pipefail
git push --no-verify --force --set-upstream origin "$BRANCH_NAME"
- name: edit existing open pull request
id: edit
# Don't fail job if we need to open new PR
continue-on-error: true
env:
# We have to use a Personal Access Token (PAT) here.
# PRs opened from a workflow using the standard `GITHUB_TOKEN` in GitHub Actions
# do not automatically trigger more workflows:
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow
GITHUB_TOKEN: ${{ secrets.RUST_UPDATER_GITHUB_TOKEN }}
run: |
set -euo pipefail
# Exit with error if PR is closed
STATE="$(gh pr view "$BRANCH_NAME" --repo "$GITHUB_REPOSITORY" --json state --jq '.state')"
if [[ "$STATE" != "OPEN" ]]; then
exit 1
fi
gh pr edit "$BRANCH_NAME" --title "${PR_TITLE}" --body-file body.md --repo "$GITHUB_REPOSITORY"
- name: open new pull request
# Only run if there wasn't an existing PR
if: steps.edit.outcome != 'success'
env:
# We have to use a Personal Access Token (PAT) here.
# PRs opened from a workflow using the standard `GITHUB_TOKEN` in GitHub Actions
# do not automatically trigger more workflows:
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow
GITHUB_TOKEN: ${{ secrets.RUST_UPDATER_GITHUB_TOKEN }}
run: |
set -euo pipefail
gh pr create --title "${PR_TITLE}" --body-file body.md --repo "$GITHUB_REPOSITORY"
- name: set PR to auto-merge
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh pr merge --squash --auto --delete-branch