@@ -20,39 +20,79 @@ jobs:
20
20
name : No important files changed
21
21
runs-on : ubuntu-22.04
22
22
steps :
23
- - name : Checkout code
24
- uses : actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
25
- with :
26
- repository : ${{ inputs.repository }}
27
- ref : ${{ inputs.ref }}
28
-
29
23
- name : Check if important files changed
30
24
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
32
+ .listFiles({ owner, repo, pull_number })
33
+ .then(async ({ data: files }) => {
34
+ const filenames = files
35
+ .filter((file) => file.status !== "added")
36
+ .map((file) => file.filename);
37
+ console.log(`Files in PR: ${filenames}`);
38
+
39
+ // Cache the parsed exercise config file's invalidator files
40
+ let exerciseInvalidatorFiles = {};
41
+
42
+ for (const filename of filenames) {
43
+ const match =
44
+ /^exercises\/(?<type>practice|concept)\/(?<slug>[^\/]+)\/(?<path>.+)$/i.exec(
45
+ filename
46
+ );
47
+ if (match?.groups === undefined) {
48
+ console.log(`${filename}: skipped (can't invalidate test results)`);
49
+ return false;
50
+ }
51
+
52
+ const { type, slug, path } = match.groups;
53
+ const configFile = `exercises/${type}/${slug}/.meta/config.json`;
54
+
55
+ const parseInvalidatorFiles = (path) => {
56
+ return github.rest.repos
57
+ .getContent({ owner, repo, path })
58
+ .then(({ data: { content } }) =>
59
+ JSON.parse(Buffer.from(content, "base64").toString())
60
+ )
61
+ .then((config) => {
62
+ const files = config.files;
63
+ if (files === undefined) {
64
+ return [];
65
+ }
33
66
34
- git remote set-branches origin main
35
- git fetch --depth 1 origin main
67
+ return [].concat(
68
+ files["invalidator"] || [],
69
+ files["test"] || [],
70
+ files["editor"] || []
71
+ );
72
+ })
73
+ .catch((err) => []);
74
+ };
36
75
37
- git diff --diff-filter=M --name-only origin/main
76
+ exerciseInvalidatorFiles[slug] ||= await parseInvalidatorFiles(
77
+ configFile
78
+ );
79
+ const invalidatesTests = exerciseInvalidatorFiles[slug].includes(path);
38
80
39
- for changed_file in $(git diff --diff-filter=M --name-only origin/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"
81
+ if (invalidatesTests) {
82
+ console.log(`${filename}: invalidates test results`);
83
+ } else {
84
+ console.log(`${filename}: does not invalidate test results`);
85
+ }
44
86
45
- if ! [ -f "${config_json_file}" ]; then
46
- # cannot determine if important files changed without .meta/config.json
47
- continue
48
- fi
87
+ return invalidatesTests;
88
+ }
49
89
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
90
+ return false;
91
+ })
92
+ .catch((err) => false);
53
93
54
94
- name : Suggest to add [no important files changed]
55
- if : steps.check.outputs.important_files_changed == 'true'
95
+ if : steps.check.outputs.result == 'true'
56
96
uses : actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
57
97
with :
58
98
script : |
0 commit comments