-
Notifications
You must be signed in to change notification settings - Fork 7
/
action.yml
257 lines (230 loc) · 10.4 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
name: PR Differences Mutants
description: "Runs mutants corresponding to its given inputs and uploads the outcomes to artifacts"
branding:
icon: "users"
color: "gray-dark"
inputs:
shard:
description: "The number of the shard to run (`-1` if ran without shards)"
required: false
default: -1
package:
description: "The package to run mutants on. `stackslib`, `stacks-node` and `stacks-signer` are independent, all others are run as `small`."
required: true
runs:
using: "composite"
steps:
# Cleanup Runner
- name: Cleanup Runner
id: runner_cleanup
uses: stacks-network/actions/cleanup/disk@main
# Checkout the stacks-core code
- name: Checkout stacks-core repo
id: git_checkout_stacks_core
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0
- name: Relative diff
id: relative_diff
shell: bash
run: |
git diff $(git merge-base origin/${{ github.base_ref }} HEAD)..HEAD > git.diff
- name: Install cargo-mutants
id: install_cargo_mutants
shell: bash
run: |
cargo install --git https://github.com/ASuciuX/cargo-mutants --branch feat/variable-test-timeout cargo-mutants # v24.2.0 - with test timeout multiplier implementation
- uses: taiki-e/install-action@ac89944b5b150d78567ab6c02badfbe48b0b55aa # v2.20.16
name: Install cargo-nextest
id: install_cargo_nextest
with:
tool: nextest # Latest version
- name: Update git diff
id: update_git_diff
shell: bash
run: |
input_file="git.diff"
temp_file="temp_diff_file.diff"
# Check if the file exists and is not empty
if [ ! -s "$input_file" ]; then
echo "Diff file ($input_file) is missing or empty!"
exit 1
fi
# Remove all lines related to deleted files including the first 'diff --git' line
awk '
/^diff --git/ {
diff_line = $0
getline
if ($0 ~ /^deleted file mode/) {
in_deleted_file_block = 1
} else {
if (diff_line != "") {
print diff_line
diff_line = ""
}
in_deleted_file_block = 0
}
}
!in_deleted_file_block
' "$input_file" > "$temp_file" && mv "$temp_file" "$input_file"
# Remove 'diff --git' lines only when followed by 'similarity index', 'rename from', and 'rename to'
awk '
/^diff --git/ {
diff_line = $0
getline
if ($0 ~ /^similarity index/) {
getline
if ($0 ~ /^rename from/) {
getline
if ($0 ~ /^rename to/) {
next
}
}
}
print diff_line
}
{ print }
' "$input_file" > "$temp_file" && mv "$temp_file" "$input_file"
- name: Split diffs
id: split_diffs
shell: bash
run: |
# Check that the file exists before performing actions on it
if [ ! -s git.diff ]; then
echo "Diff file (git.diff) is missing or empty!"
exit 1
fi
# Make a file containing all the mutants for the differences in the PR and a folder to split them into big and small packages
cargo mutants --in-diff git.diff --list > all_mutants.txt
if [ $? -ne 0 ]; then
echo "Error retrieving the list of mutants!"
exit $?
fi
mkdir -p mutants_by_packages
# Check that the file exists before performing actions on it
if [ ! -s all_mutants.txt ]; then
echo "The file containing mutants (all_mutants.txt) is missing or empty!"
exit 1
fi
# Split the differences from git into packages: 'stackslib', 'stacks-node', 'stacks-signer' and small packages (all others) and put them into separate files
while IFS= read -r line; do
package=$(echo "$line" | cut -d'/' -f1)
case $package in
"stackslib")
echo "$line" >> "mutants_by_packages/stackslib.txt"
;;
"testnet")
echo "$line" >> "mutants_by_packages/stacks-node.txt"
;;
"stacks-signer")
echo "$line" >> "mutants_by_packages/stacks-signer.txt"
;;
*)
echo "$line" >> "mutants_by_packages/small-packages.txt"
;;
esac
done < all_mutants.txt
# Create regex patterns of the mutants to be ran for `cargo mutants` -F flag and output them to files to be used later
for package in mutants_by_packages/*; do
regex_pattern=""
while IFS= read -r line; do
escaped_line=$(echo "$line" | sed 's/[][()\.^$*+?{}|]/\\&/g')
regex_pattern+="($escaped_line)|"
done < "$package"
regex_pattern="${regex_pattern%|}"
case $package in
"mutants_by_packages/stackslib.txt")
echo "$regex_pattern" > mutants_by_packages/regex-stackslib.txt
;;
"mutants_by_packages/stacks-node.txt")
echo "$regex_pattern" > mutants_by_packages/regex-stacks-node.txt
;;
"mutants_by_packages/stacks-signer.txt")
echo "$regex_pattern" > mutants_by_packages/regex-stacks-signer.txt
;;
*)
echo "$regex_pattern" > mutants_by_packages/regex-small-packages.txt
;;
esac
done
exit 0
- name: Run mutants
id: run_mutants
shell: bash
run: |
# Disable immediate exit on error
set +e
# Check which type of mutants to run: big, small, with or without shards, then capture the exit code
if [[ ${{ inputs.shard }} == -1 ]]; then
if [[ ${{ inputs.package }} == stackslib ]]; then
if [[ -f mutants_by_packages/regex-stackslib.txt ]]; then
echo "Running mutants without shards on stackslib package"
cargo mutants --timeout-multiplier 1.5 --no-shuffle -vV -F "$(<mutants_by_packages/regex-stackslib.txt)" -E ": replace .{1,2} with .{1,2} in " --output ./ --test-tool=nextest -- --all-targets --test-threads 1
exit_code=$?
else
echo "File containing mutants doesn't exist!"
fi
elif [[ ${{ inputs.package }} == stacks-node ]]; then
if [[ -f mutants_by_packages/regex-stacks-node.txt ]]; then
echo "Running mutants without shards on stacks-node package"
cargo mutants --timeout-multiplier 1.5 --no-shuffle -vV -F "$(<mutants_by_packages/regex-stacks-node.txt)" -E ": replace .{1,2} with .{1,2} in " --output ./ --test-tool=nextest -- --all-targets --test-threads 1
exit_code=$?
else
echo "File containing mutants doesn't exist!"
fi
elif [[ ${{ inputs.package }} == stacks-signer ]]; then
if [[ -f mutants_by_packages/regex-stacks-signer.txt ]]; then
echo "Running mutants without shards on stacks-signer package"
cargo mutants --timeout-multiplier 1.5 --no-shuffle -vV -F "$(<mutants_by_packages/regex-stacks-signer.txt)" -E ": replace .{1,2} with .{1,2} in " --output ./ --test-tool=nextest -- --all-targets --test-threads 1
exit_code=$?
else
echo "File containing mutants doesn't exist!"
fi
else
if [[ -f mutants_by_packages/regex-small-packages.txt ]]; then
echo "Running mutants without shards on small packages"
cargo mutants --timeout-multiplier 1.5 --no-shuffle -vV -F "$(<mutants_by_packages/regex-small-packages.txt)" -E ": replace .{1,2} with .{1,2} in " --output ./ --test-tool=nextest -- --all-targets
exit_code=$?
else
echo "File containing mutants doesn't exist!"
fi
fi
else
if [[ ${{ inputs.package }} == stackslib ]]; then
if [[ -f mutants_by_packages/regex-stackslib.txt ]]; then
echo "Running mutants with shard ${{ inputs.shard }} on stackslib package"
cargo mutants --timeout-multiplier 1.5 --no-shuffle -vV -F "$(<mutants_by_packages/regex-stackslib.txt)" -E ": replace .{1,2} with .{1,2} in " --shard ${{ inputs.shard }}/8 --output ./ --test-tool=nextest -- --all-targets --test-threads 1
exit_code=$?
else
echo "File containing mutants doesn't exist!"
fi
elif [[ ${{ inputs.package }} == stacks-node ]]; then
if [[ -f mutants_by_packages/regex-stacks-node.txt ]]; then
echo "Running mutants with shard ${{ inputs.shard }} on stacks-node package"
cargo mutants --timeout-multiplier 1.5 --no-shuffle -vV -F "$(<mutants_by_packages/regex-stacks-node.txt)" -E ": replace .{1,2} with .{1,2} in " --shard ${{ inputs.shard }}/4 --output ./ --test-tool=nextest -- --all-targets --test-threads 1
exit_code=$?
else
echo "File containing mutants doesn't exist!"
fi
else
if [[ -f mutants_by_packages/regex-small-packages.txt ]]; then
echo "Running mutants with shard ${{ inputs.shard }} on small packages"
cargo mutants --timeout-multiplier 1.5 --no-shuffle -vV -F "$(<mutants_by_packages/regex-small-packages.txt)" -E ": replace .{1,2} with .{1,2} in " --shard ${{ inputs.shard }}/4 --output ./ --test-tool=nextest -- --all-targets
exit_code=$?
else
echo "File containing mutants doesn't exist!"
fi
fi
fi
# Create the folder only containing the outcomes (.txt files) and make a file containing the exit code of the command
mkdir mutants-shard-${{ inputs.package }}-${{ inputs.shard }}
echo "$exit_code" > ./mutants-shard-${{ inputs.package }}-${{ inputs.shard }}/exit_code.txt
mv ./mutants.out/*.txt mutants-shard-${{ inputs.package }}-${{ inputs.shard }}/
# Enable immediate exit on error again
set -e
- name: Upload artifact
id: upload_artifact
uses: actions/upload-artifact@1eb3cb2b3e0f29609092a73eb033bb759a334595 # v4.1.0
with:
name: mutants-shard-${{ inputs.package }}-${{ inputs.shard }}
path: mutants-shard-${{ inputs.package }}-${{ inputs.shard }}