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
14
.github/workflows/pr-automation.yml
vendored
14
.github/workflows/pr-automation.yml
vendored
|
|
@ -34,16 +34,16 @@ jobs:
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
- name: Get tags
|
||||||
|
uses: actions/github-script@v7
|
||||||
id: getTags
|
id: getTags
|
||||||
env:
|
env:
|
||||||
PR_BODY: ${{ github.event.pull_request.body }}
|
NODE_PATH: "${{ github.workspace }}/.github/workflows/scripts"
|
||||||
run: |
|
with:
|
||||||
REGEX='/ok-to-test tags="([^"]*)"';
|
script: |
|
||||||
if [[ $PR_BODY =~ $REGEX ]]; then
|
const testTagParser = require("test-tag-parser.js")
|
||||||
echo "tags=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT
|
core.setOutput("tags", testTagParser.parseTags({core, context}))
|
||||||
fi
|
|
||||||
|
|
||||||
# Parses the retrieved /ok-to-test slash command to retrieve tags
|
# Parses the retrieved /ok-to-test slash command to retrieve tags
|
||||||
- name: Parse tags
|
- name: Parse tags
|
||||||
|
|
|
||||||
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