Skip to content

Commit 427b3f2

Browse files
committed
feat: add test actions
1 parent be52207 commit 427b3f2

3 files changed

Lines changed: 192 additions & 0 deletions

File tree

test/check/action.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: "Test Check Labels"
2+
description: "Fails if label-needed is present but label-done is not."
3+
4+
inputs:
5+
label-needed:
6+
description: 'Label indicating the PR needs testing'
7+
required: false
8+
default: 'test-needed'
9+
label-done:
10+
description: 'Label indicating the PR has been tested'
11+
required: false
12+
default: 'test-done'
13+
test-name:
14+
description: 'Name of the test type used in comments (e.g. Robot)'
15+
required: false
16+
default: 'Test'
17+
token:
18+
description: 'GitHub token or PAT used to post comments (defaults to github.token)'
19+
required: false
20+
default: ''
21+
22+
runs:
23+
using: "composite"
24+
steps:
25+
- name: Check test labels
26+
uses: actions/github-script@v7
27+
with:
28+
github-token: ${{ inputs.token || github.token }}
29+
script: |
30+
const labelNeeded = '${{ inputs.label-needed }}';
31+
const labelDone = '${{ inputs.label-done }}';
32+
const testName = '${{ inputs.test-name }}';
33+
const { number: pr, head: { sha } } = context.payload.pull_request;
34+
const repo = context.repo;
35+
36+
const postComment = async (body) => {
37+
try {
38+
await github.rest.issues.createComment({ ...repo, issue_number: pr, body });
39+
} catch (err) {
40+
core.warning(`Could not post comment: ${err.message}`);
41+
}
42+
};
43+
44+
const { data: labels } = await github.rest.issues.listLabelsOnIssue({ ...repo, issue_number: pr });
45+
const has = new Set(labels.map(l => l.name));
46+
47+
if (!has.has(labelNeeded)) {
48+
core.info(`\`${labelNeeded}\` not present. No ${testName} testing required.`);
49+
return;
50+
}
51+
52+
if (has.has(labelDone)) {
53+
core.info(`\`${labelDone}\` present. ${testName} testing confirmed.`);
54+
return;
55+
}
56+
57+
const shaLine = sha ? `\n\n**Commit:** \`${sha}\`` : '';
58+
await postComment(
59+
`### ❌ ${testName} Testing Required\n\n` +
60+
`\`${labelNeeded}\` is present but \`${labelDone}\` has not been added. This PR cannot be merged until ${testName} testing is complete.${shaLine}\n\n` +
61+
`> [!IMPORTANT]\n> Add \`${labelDone}\` once ${testName} testing is complete.`
62+
);
63+
core.setFailed(`\`${labelNeeded}\` is present but \`${labelDone}\` has not been added. ${testName} testing must be completed before merging.`);

test/label/action.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: "Test Label"
2+
description: "When the label-done label is added, posts a comment confirming the test status."
3+
4+
inputs:
5+
label-needed:
6+
description: 'Label indicating the PR needs testing'
7+
required: false
8+
default: 'test-needed'
9+
label-done:
10+
description: 'Label indicating the PR has been tested'
11+
required: false
12+
default: 'test-done'
13+
test-name:
14+
description: 'Name of the test type used in comments (e.g. Robot)'
15+
required: false
16+
default: 'Test'
17+
token:
18+
description: 'GitHub token or PAT used to post comments (defaults to github.token)'
19+
required: false
20+
default: ''
21+
22+
runs:
23+
using: "composite"
24+
steps:
25+
- name: Comment on label added
26+
uses: actions/github-script@v7
27+
with:
28+
github-token: ${{ inputs.token || github.token }}
29+
script: |
30+
const labelDone = '${{ inputs.label-done }}';
31+
const labelNeeded = '${{ inputs.label-needed }}';
32+
const testName = '${{ inputs.test-name }}';
33+
const { number: pr, head: { sha } } = context.payload.pull_request;
34+
const repo = context.repo;
35+
36+
const postComment = async (body) => {
37+
try {
38+
await github.rest.issues.createComment({ ...repo, issue_number: pr, body });
39+
} catch (err) {
40+
core.warning(`Could not post comment: ${err.message}`);
41+
}
42+
};
43+
44+
const { data: labels } = await github.rest.issues.listLabelsOnIssue({ ...repo, issue_number: pr });
45+
const has = new Set(labels.map(l => l.name));
46+
const shaLine = sha ? `\n\n**Commit:** \`${sha}\`` : '';
47+
48+
if (!has.has(labelDone)) {
49+
if (has.has(labelNeeded)) {
50+
core.warning(`\`${labelDone}\` not found. \`${labelNeeded}\` is present but testing is not confirmed.`);
51+
await postComment(
52+
`### ⚠️ ${testName} Testing Incomplete\n\n` +
53+
`\`${labelNeeded}\` is present but \`${labelDone}\` has not been added yet.${shaLine}\n\n` +
54+
`> [!WARNING]\n> Add \`${labelDone}\` once ${testName} testing is complete.`
55+
);
56+
} else {
57+
core.info(`\`${labelDone}\` not present. Nothing to do.`);
58+
}
59+
return;
60+
}
61+
62+
core.info(`\`${labelDone}\` found. Posting confirmation comment.`);
63+
await postComment(
64+
`### ✅ ${testName} Complete\n\n` +
65+
`\`${labelDone}\` has been added. ${testName} testing has been confirmed for this PR.${shaLine}`
66+
);

test/unlabel/action.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: "Test Unlabel"
2+
description: "On new commits, removes the label-done label if present and posts a comment."
3+
4+
inputs:
5+
label-needed:
6+
description: 'Label indicating the PR needs testing'
7+
required: false
8+
default: 'test-needed'
9+
label-done:
10+
description: 'Label indicating the PR has been tested'
11+
required: false
12+
default: 'test-done'
13+
test-name:
14+
description: 'Name of the test type used in comments (e.g. Robot)'
15+
required: false
16+
default: 'Test'
17+
token:
18+
description: 'GitHub token or PAT used to remove labels and post comments (defaults to github.token)'
19+
required: false
20+
default: ''
21+
22+
runs:
23+
using: "composite"
24+
steps:
25+
- name: Remove label and comment
26+
uses: actions/github-script@v7
27+
with:
28+
github-token: ${{ inputs.token || github.token }}
29+
script: |
30+
const labelDone = '${{ inputs.label-done }}';
31+
const labelNeeded = '${{ inputs.label-needed }}';
32+
const testName = '${{ inputs.test-name }}';
33+
const { number: pr, head: { sha } } = context.payload.pull_request;
34+
const repo = context.repo;
35+
36+
const postComment = async (body) => {
37+
try {
38+
await github.rest.issues.createComment({ ...repo, issue_number: pr, body });
39+
} catch (err) {
40+
core.warning(`Could not post comment: ${err.message}`);
41+
}
42+
};
43+
44+
const { data: labels } = await github.rest.issues.listLabelsOnIssue({ ...repo, issue_number: pr });
45+
const has = new Set(labels.map(l => l.name));
46+
47+
if (!has.has(labelDone)) {
48+
core.info(`\`${labelDone}\` not present. Nothing to do.`);
49+
return;
50+
}
51+
52+
await github.rest.issues.removeLabel({ ...repo, issue_number: pr, name: labelDone });
53+
core.info(`\`${labelDone}\` removed.`);
54+
55+
const shaLine = sha ? `\n\n**Commit:** \`${sha}\`` : '';
56+
const warning = !has.has(labelNeeded)
57+
? `\n\n> [!WARNING]\n> \`${labelDone}\` was removed but \`${labelNeeded}\` was not present. This PR may not be queued for ${testName} testing.`
58+
: '';
59+
60+
await postComment(
61+
`### 🔄 ${testName} Label Removed\n\n` +
62+
`New commits were pushed. \`${labelDone}\` has been removed and ${testName} testing must be repeated.${shaLine}${warning}`
63+
);

0 commit comments

Comments
 (0)