ci: Add sloppy /test command (#33558)
Adds support for a `/test` command, without breaking the existing `/ok-to-test` habits. This is a _sloppy_ version of `/ok-to-test`. Turns out humans are sloppy. So let's embrace the human. 🤯 Example incantation: ``` /test sanity workflow ``` The sloppy parser at work:  Of course, if a PR body contains `/ok-to-test`, that takes precedence, and any `/test` is ignored. We're also moving the logic of parsing the tags to a separate Javascript file. It's still not in a form that's easily testable, perhaps, but I hope this is a start for us to get to a "unit-tested CI". ❤️ --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
parent
f47bd4051c
commit
cb973941d5
16
.github/workflows/pr-automation.yml
vendored
16
.github/workflows/pr-automation.yml
vendored
|
|
@ -34,16 +34,16 @@ jobs:
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Reads the PR description to retrieve /ok-to-test slash command
|
||||
# Reads the PR description to retrieve the /ok-to-test or, if that's absent, the /test command
|
||||
- name: Get tags
|
||||
uses: actions/github-script@v7
|
||||
id: getTags
|
||||
env:
|
||||
PR_BODY: ${{ github.event.pull_request.body }}
|
||||
run: |
|
||||
REGEX='/ok-to-test tags="([^"]*)"';
|
||||
if [[ $PR_BODY =~ $REGEX ]]; then
|
||||
echo "tags=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
NODE_PATH: "${{ github.workspace }}/.github/workflows/scripts"
|
||||
with:
|
||||
script: |
|
||||
const testTagParser = require("test-tag-parser.js")
|
||||
core.setOutput("tags", testTagParser.parseTags({core, context}))
|
||||
|
||||
# Parses the retrieved /ok-to-test slash command to retrieve tags
|
||||
- name: Parse tags
|
||||
|
|
@ -112,7 +112,7 @@ jobs:
|
|||
- name: Stop the workflow run if tags are incorrect
|
||||
if: steps.checkTags.outputs.outcome == 'failure'
|
||||
run: exit 1
|
||||
|
||||
|
||||
# In case of a run with all test cases, allocate a larger matrix
|
||||
- name: Check if @tag.All is present in tags
|
||||
id: checkAll
|
||||
|
|
|
|||
47
.github/workflows/scripts/test-tag-parser.js
vendored
Normal file
47
.github/workflows/scripts/test-tag-parser.js
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
function parseTags({core, context}) {
|
||||
const body = context.payload.pull_request.body;
|
||||
|
||||
// "/ok-to-test" matcher. Takes precedence over the "/test" matcher.
|
||||
const strictMatch = body.match(/\/ok-to-test tags="(.+?)"/)?.[1];
|
||||
if (strictMatch) {
|
||||
return strictMatch;
|
||||
}
|
||||
|
||||
// "/test" matcher.
|
||||
const allTags = require(process.env.GITHUB_WORKSPACE + "/app/client/cypress/tags.js").Tag;
|
||||
const config = body.match(/^\/test\s+(.*)$/m)?.[1] ?? "";
|
||||
const concreteTags = [];
|
||||
|
||||
for (const [rawTag] of config.matchAll(/\w+/g)) {
|
||||
console.log("Given: '" + rawTag + "'");
|
||||
|
||||
// See if there is exact case-insensitive match.
|
||||
const exactTagMatch = allTags.find(t => t.toLowerCase() === "@tag." + rawTag);
|
||||
if (exactTagMatch) {
|
||||
console.log("\tMatch found:", exactTagMatch);
|
||||
concreteTags.push(exactTagMatch);
|
||||
continue;
|
||||
}
|
||||
|
||||
// See if there is a singular/plural match (very rudimentary language skills).
|
||||
const countedMatch = allTags.find(t => t.toLowerCase().replace(/s$/, "") === "@tag." + rawTag.replace(/s$/, ""));
|
||||
if (countedMatch) {
|
||||
console.log("\tMatch found:", countedMatch);
|
||||
concreteTags.push(countedMatch);
|
||||
continue;
|
||||
}
|
||||
|
||||
// More smart matchers?
|
||||
|
||||
// No match, fail.
|
||||
core.setFailed("\tNo match found for tag:", rawTag);
|
||||
|
||||
// We still process the rest, so we report all invalid tags in the input in a single run.
|
||||
}
|
||||
|
||||
return concreteTags.join(", ");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseTags,
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user