@@ -20,39 +20,67 @@ jobs:
2020 name : No important files changed
2121 runs-on : ubuntu-22.04
2222 steps :
23- - name : Checkout code
24- uses : actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
25- with :
26- repository : ${{ inputs.repository }}
27- ref : ${{ inputs.ref }}
28-
2923 - name : Check if important files changed
3024 id : check
31- run : |
32- set -exo pipefail
25+ uses : actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
26+ with :
27+ script : |
28+ const { owner, repo } = context.repo;
29+ const pull_number = context.issue.number
30+
31+ return github.rest.pulls.listFiles({ owner, repo, pull_number })
32+ .then(async ({ data: files }) => {
33+ const filenames = files.map(file => file.filename);
34+ console.log(`Files in PR: ${filenames}`);
35+
36+ // Cache the parsed exercise config file's invalidator files
37+ let exerciseInvalidatorFiles = {};
38+
39+ return filenames.some(async (filename) => {
40+ const match = /^exercises\/(?<type>practice|concept)\/(?<slug>[^\/]+)\/(?<path>.+)$/i.exec(filename);
41+ if (match?.groups === undefined) {
42+ console.log(`${filename}: skipped (can't invalidate test results)`);
43+ return false;
44+ }
45+
46+ const { type, slug, path } = match.groups;
47+ const configFile = `exercises/${type}/${slug}/.meta/config.json`;
3348
34- git remote add upstream "https://github.com/${GITHUB_REPOSITORY}.git"
35- git fetch --depth 1 upstream main
49+ const parseInvalidatorFiles = (path) => {
50+ return github.rest.repos
51+ .getContent({ owner, repo, path })
52+ .then(({ data: { content } }) => JSON.parse(Buffer.from(content, "base64").toString()))
53+ .then((config) => {
54+ const files = config.files;
55+ if (files === undefined) {
56+ return [];
57+ }
3658
37- git diff --diff-filter=M --name-only upstream/main
59+ return [].concat(
60+ files["invalidator"] || [],
61+ files["test"] || [],
62+ files["editor"] || []
63+ );
64+ })
65+ .catch((err) => []);
66+ };
3867
39- for changed_file in $(git diff --diff-filter=M --name-only upstream/main); do
40- slug="$(echo "${changed_file}" | sed --regexp-extended 's#exercises/[^/]+/([^/]+)/.*#\1#' )"
41- path_before_slug="$(echo "${changed_file}" | sed --regexp-extended "s#(.*)/${slug}/.*#\\1#" )"
42- path_after_slug="$( echo "${changed_file}" | sed --regexp-extended "s#.*/${slug}/(.*)#\\1#" )"
43- config_json_file="${path_before_slug}/${slug}/.meta/config.json"
68+ exerciseInvalidatorFiles[slug] ||= await parseInvalidatorFiles(configFile);
69+ const invalidatesTests = exerciseInvalidatorFiles[slug].includes(path)
4470
45- if ! [ -f "${config_json_file}" ]; then
46- # cannot determine if important files changed without .meta/config.json
47- continue
48- fi
71+ if (invalidatesTests) {
72+ console.log(`${filename}: invalidates test results`);
73+ } else {
74+ console.log(`${filename}: does not invalidate test results`);
75+ }
4976
50- changed=$(jq --arg path "${path_after_slug}" '[.files.test, .files.invalidator, .files.editor] | flatten | index($path) != null' "${config_json_file}")
51- echo "important_files_changed=${changed}" >> "$GITHUB_OUTPUT"
52- done
77+ return invalidatesTests;
78+ });
79+ })
80+ .catch((err) => false);
5381
5482 - name : Suggest to add [no important files changed]
55- if : steps.check.outputs.important_files_changed == 'true'
83+ if : steps.check.outputs.result == 'true'
5684 uses : actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
5785 with :
5886 script : |
0 commit comments