Skip to content

Commit ce4a73f

Browse files
mockersfItsDoot
authored andcommitted
Make CI friendlier (bevyengine#7398)
# Objective - Make CI friendlier ## Solution - CI now says hello to new contributor - for some jobs with non obvious solutions to failures, give more context - example run should say which example failed - example doc should say the next action to do (add metadata or run the update script) - MSRV will say when it needs updating I'm not completely sure everything is working and will try to trigger failures in this PR
1 parent 98234dd commit ce4a73f

File tree

3 files changed

+257
-11
lines changed

3 files changed

+257
-11
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
name: CI - PR Comments
2+
3+
# This workflow has write permissions on the repo
4+
# It must not checkout a PR and run untrusted code
5+
6+
# Also requesting write permissions on PR to be able to comment
7+
permissions:
8+
pull-requests: 'write'
9+
10+
on:
11+
workflow_run:
12+
workflows: ["CI"]
13+
types:
14+
- completed
15+
16+
jobs:
17+
example-run:
18+
runs-on: ubuntu-latest
19+
if: >
20+
github.event.workflow_run.event == 'pull_request' &&
21+
github.event.workflow_run.conclusion == 'failure'
22+
steps:
23+
- name: 'Download artifact'
24+
id: find-artifact
25+
uses: actions/github-script@v6
26+
with:
27+
result-encoding: string
28+
script: |
29+
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
30+
owner: context.repo.owner,
31+
repo: context.repo.repo,
32+
run_id: ${{github.event.workflow_run.id }},
33+
});
34+
var matchArtifacts = artifacts.data.artifacts.filter((artifact) => {
35+
return artifact.name == "example-run"
36+
});
37+
if (matchArtifacts.length == 0) { return "false" }
38+
var matchArtifact = matchArtifacts[0];
39+
var download = await github.rest.actions.downloadArtifact({
40+
owner: context.repo.owner,
41+
repo: context.repo.repo,
42+
artifact_id: matchArtifact.id,
43+
archive_format: 'zip',
44+
});
45+
var fs = require('fs');
46+
fs.writeFileSync('${{github.workspace}}/example-run.zip', Buffer.from(download.data));
47+
return "true"
48+
- run: unzip example-run.zip
49+
if: ${{ steps.find-artifact.outputs.result == 'true' }}
50+
- name: 'Comment on PR'
51+
if: ${{ steps.find-artifact.outputs.result == 'true' }}
52+
uses: actions/github-script@v6
53+
with:
54+
github-token: ${{ secrets.GITHUB_TOKEN }}
55+
script: |
56+
var fs = require('fs');
57+
var issue_number = Number(fs.readFileSync('./NR'));
58+
var last_example_run = fs.readFileSync('./last_example_run');
59+
await github.rest.issues.createComment({
60+
owner: context.repo.owner,
61+
repo: context.repo.repo,
62+
issue_number: issue_number,
63+
body: 'Example ' + last_example_run + ' failed to run, please try running it locally and check the result.'
64+
});
65+
66+
missing-examples:
67+
runs-on: ubuntu-latest
68+
if: >
69+
github.event.workflow_run.event == 'pull_request' &&
70+
github.event.workflow_run.conclusion == 'failure'
71+
steps:
72+
- name: 'Download artifact'
73+
id: find-artifact
74+
uses: actions/github-script@v6
75+
with:
76+
result-encoding: string
77+
script: |
78+
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
79+
owner: context.repo.owner,
80+
repo: context.repo.repo,
81+
run_id: ${{github.event.workflow_run.id }},
82+
});
83+
var matchArtifacts = artifacts.data.artifacts.filter((artifact) => {
84+
return artifact.name == "missing-examples"
85+
});
86+
if (matchArtifacts.length == 0) { return "false" }
87+
var matchArtifact = matchArtifacts[0];
88+
var download = await github.rest.actions.downloadArtifact({
89+
owner: context.repo.owner,
90+
repo: context.repo.repo,
91+
artifact_id: matchArtifact.id,
92+
archive_format: 'zip',
93+
});
94+
var fs = require('fs');
95+
fs.writeFileSync('${{github.workspace}}/missing-examples.zip', Buffer.from(download.data));
96+
return "true"
97+
- run: unzip missing-examples.zip
98+
if: ${{ steps.find-artifact.outputs.result == 'true' }}
99+
- name: 'Comment on PR'
100+
if: ${{ steps.find-artifact.outputs.result == 'true' }}
101+
uses: actions/github-script@v6
102+
with:
103+
github-token: ${{ secrets.GITHUB_TOKEN }}
104+
script: |
105+
var fs = require('fs');
106+
var issue_number = Number(fs.readFileSync('./NR'));
107+
if (existsSync('./missing-metadata')) {
108+
await github.rest.issues.createComment({
109+
owner: context.repo.owner,
110+
repo: context.repo.repo,
111+
issue_number: issue_number,
112+
body: 'You added a new example but didn't add metadata for it. Please update the root Cargo.toml file.'
113+
});
114+
}
115+
if (existsSync('./missing-update')) {
116+
await github.rest.issues.createComment({
117+
owner: context.repo.owner,
118+
repo: context.repo.repo,
119+
issue_number: issue_number,
120+
body: 'You added a new example but didn't update the readme. Please run `cargo run -p build-example-pages -- update` to update it, and commit the file change.'
121+
});
122+
}
123+
124+
msrv:
125+
runs-on: ubuntu-latest
126+
if: >
127+
github.event.workflow_run.event == 'pull_request' &&
128+
github.event.workflow_run.conclusion == 'failure'
129+
steps:
130+
- name: 'Download artifact'
131+
id: find-artifact
132+
uses: actions/github-script@v6
133+
with:
134+
result-encoding: string
135+
script: |
136+
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
137+
owner: context.repo.owner,
138+
repo: context.repo.repo,
139+
run_id: ${{github.event.workflow_run.id }},
140+
});
141+
var matchArtifacts = artifacts.data.artifacts.filter((artifact) => {
142+
return artifact.name == "msrv"
143+
});
144+
if (matchArtifacts.length == 0) { return "false" }
145+
var matchArtifact = matchArtifacts[0];
146+
var download = await github.rest.actions.downloadArtifact({
147+
owner: context.repo.owner,
148+
repo: context.repo.repo,
149+
artifact_id: matchArtifact.id,
150+
archive_format: 'zip',
151+
});
152+
var fs = require('fs');
153+
fs.writeFileSync('${{github.workspace}}/msrv.zip', Buffer.from(download.data));
154+
return "true"
155+
- run: unzip msrv.zip
156+
if: ${{ steps.find-artifact.outputs.result == 'true' }}
157+
- name: 'Comment on PR'
158+
if: ${{ steps.find-artifact.outputs.result == 'true' }}
159+
uses: actions/github-script@v6
160+
with:
161+
github-token: ${{ secrets.GITHUB_TOKEN }}
162+
script: |
163+
var fs = require('fs');
164+
var issue_number = Number(fs.readFileSync('./NR'));
165+
await github.rest.issues.createComment({
166+
owner: context.repo.owner,
167+
repo: context.repo.repo,
168+
issue_number: issue_number,
169+
body: 'Your PR increases Bevy Minimum Supported Rust Version. Please update the `rust-version` field in the root Cargo.toml file.'
170+
});

.github/workflows/ci.yml

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ jobs:
142142

143143
markdownlint:
144144
runs-on: ubuntu-latest
145-
needs: check-examples-readme-update-needed
145+
needs: check-missing-examples-in-docs
146146
if: always()
147147
steps:
148148
- uses: actions/checkout@v3
@@ -156,8 +156,6 @@ jobs:
156156
VALIDATE_ALL_CODEBASE: false
157157
VALIDATE_MARKDOWN: true
158158
DEFAULT_BRANCH: main
159-
# Not needed here as only one Linter is used.
160-
#GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
161159

162160
run-examples:
163161
runs-on: ubuntu-latest
@@ -193,6 +191,7 @@ jobs:
193191
run: |
194192
for example in .github/example-run/*.ron; do
195193
example_name=`basename $example .ron`
194+
echo $example > last_example_run
196195
echo "running $example_name - "`date`
197196
time TRACE_CHROME=trace-$example_name.json CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --features "bevy_ci_testing,trace,trace_chrome"
198197
sleep 10
@@ -203,6 +202,17 @@ jobs:
203202
with:
204203
name: example-traces.zip
205204
path: traces.zip
205+
- name: Save PR number
206+
if: ${{ failure() && github.event_name == 'pull_request' }}
207+
run: |
208+
mkdir -p ./example-run
209+
echo ${{ github.event.number }} > ./example-run/NR
210+
mv last_example_run > ./example-run/
211+
- uses: actions/upload-artifact@v2
212+
if: ${{ failure() && github.event_name == 'pull_request' }}
213+
with:
214+
name: example-run
215+
path: example-run/
206216

207217
check-doc:
208218
runs-on: ubuntu-latest
@@ -239,19 +249,33 @@ jobs:
239249
runs-on: ubuntu-latest
240250
steps:
241251
- uses: actions/checkout@v3
242-
- run: cargo run -p build-example-pages -- check-missing
243-
244-
check-examples-readme-update-needed:
245-
needs: check-missing-examples-in-docs
246-
runs-on: ubuntu-latest
247-
steps:
248-
- uses: actions/checkout@v3
249-
- run: cargo run -p build-example-pages -- update
252+
- name: check for missing metadata
253+
id: missing-metadata
254+
run: cargo run -p build-example-pages -- check-missing
255+
- name: check for missing update
256+
id: missing-update
257+
run: cargo run -p build-example-pages -- update
250258
- name: Check for modified files
251259
run: |
252260
echo "if this step fails, run the following command and commit the changed file on your PR."
253261
echo " > cargo run -p build-example-pages -- update"
254262
git diff --quiet HEAD --
263+
- name: Save PR number
264+
if: ${{ failure() && github.event_name == 'pull_request' }}
265+
run: |
266+
mkdir -p ./missing-examples
267+
echo ${{ github.event.number }} > ./missing-examples/NR
268+
- name: log failed task - missing metadata
269+
if: ${{ failure() && github.event_name == 'pull_request' && steps.missing-metadata.conclusion == 'failure' }}
270+
run: touch ./missing-examples/missing-metadata
271+
- name: log failed task - missing update
272+
if: ${{ failure() && github.event_name == 'pull_request' && steps.missing-update.conclusion == 'failure' }}
273+
run: touch ./missing-examples/missing-update
274+
- uses: actions/upload-artifact@v2
275+
if: ${{ failure() && github.event_name == 'pull_request' }}
276+
with:
277+
name: missing-examples
278+
path: missing-examples/
255279

256280
check-unused-dependencies:
257281
runs-on: ubuntu-latest
@@ -301,3 +325,13 @@ jobs:
301325
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev
302326
- name: Run cargo check
303327
run: cargo check
328+
- name: Save PR number
329+
if: ${{ failure() && github.event_name == 'pull_request' }}
330+
run: |
331+
mkdir -p ./msrv
332+
echo ${{ github.event.number }} > ./msrv/NR
333+
- uses: actions/upload-artifact@v2
334+
if: ${{ failure() && github.event_name == 'pull_request' }}
335+
with:
336+
name: msrv
337+
path: msrv/

.github/workflows/welcome.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Welcome new contributors
2+
3+
# This workflow has write permissions on the repo
4+
# It must not checkout a PR and run untrusted code
5+
6+
on: pull_request_target
7+
8+
jobs:
9+
welcome:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/github-script@v6
13+
with:
14+
script: |
15+
// Get a list of all issues created by the PR opener
16+
// See: https://octokit.github.io/rest.js/#pagination
17+
const creator = context.payload.sender.login
18+
const opts = github.rest.issues.listForRepo.endpoint.merge({
19+
...context.issue,
20+
creator,
21+
state: 'all'
22+
})
23+
const issues = await github.paginate(opts)
24+
25+
for (const issue of issues) {
26+
if (issue.number === context.issue.number) {
27+
continue
28+
}
29+
30+
if (issue.pull_request) {
31+
return // Creator is already a contributor.
32+
}
33+
}
34+
35+
await github.rest.issues.createComment({
36+
issue_number: context.issue.number,
37+
owner: context.repo.owner,
38+
repo: context.repo.repo,
39+
body: `**Welcome**, new contributor!
40+
41+
Please make sure you're read our [contributing guide](CONTRIBUTING.md) and we look forward to reviewing your Pull request shortly ✨`
42+
})

0 commit comments

Comments
 (0)