tickmarkr 2.7.7 → 2.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tickmarkr",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.8",
|
|
4
4
|
"description": "Spec in, verified work out.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
"skills/tickmarkr-auto/",
|
|
95
95
|
"skills/tickmarkr-loop/",
|
|
96
96
|
"skills/tickmarkr-overseer/",
|
|
97
|
+
"scripts/ci/",
|
|
97
98
|
"src/",
|
|
98
99
|
"tests/"
|
|
99
100
|
]
|
|
@@ -1601,9 +1601,12 @@ Create specialist seats using `orca terminal create --worktree path:<repo> --com
|
|
|
1601
1601
|
|
|
1602
1602
|
- **GRADE PUBLIC CI FROM JOB LOGS AT RUN-END ONLY (law 48).** A badge is not the grade, and
|
|
1603
1603
|
`gh run view --job --log` is empty while the run is in progress. At run-end execute
|
|
1604
|
-
`scripts/grade-ci.sh <run-id> <expected-count> <tag>` and require GREEN from
|
|
1605
|
-
|
|
1606
|
-
`
|
|
1604
|
+
`scripts/grade-ci.sh <run-id> <expected-count> <tag>` and require GREEN from every job of the
|
|
1605
|
+
declared inventory it prints first — serial `test` and `test-macos`, or sharded, per OS, the four
|
|
1606
|
+
`suite <os> k/4` shards, `single-fork <os>` and `aggregate <os>`; a missing, duplicated or unknown
|
|
1607
|
+
job reads UNREADABLE, never a skip. Its UNREADABLE state is a hard stop, not a green default.
|
|
1608
|
+
Derive the expected glob pathspec count with `git ls-files ':(glob)tests/**/*.test.ts'`
|
|
1609
|
+
(including the `.tsx` sibling where present), never a bare
|
|
1607
1610
|
`tests/**/*.test.ts`: bare `**` is not a git glob (law 49).
|
|
1608
1611
|
|
|
1609
1612
|
- **RE-READ THE REGISTRY BEFORE RULING (law 51).** A successful Release run and the first
|
|
@@ -1,9 +1,36 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# grade-ci.sh <run-id> <expected-count> [tag] — grade
|
|
3
|
-
# Grade only at run-end. A missing/in-progress/empty log is UNREADABLE, never evidence of green.
|
|
2
|
+
# grade-ci.sh <run-id> <expected-count> [tag] — grade EVERY job of a public CI run's closed inventory from
|
|
3
|
+
# its JOB LOG. Grade only at run-end. A missing/in-progress/empty log is UNREADABLE, never evidence of green.
|
|
4
4
|
# Exit 0 GREEN, 1 RED, 2 UNREADABLE, 3 INFRA_KILLED: a job the GitHub runner shut down or cancelled with
|
|
5
5
|
# no failed or timed-out test (the classifier's class, D-897) — never green, never a pass, only unproven.
|
|
6
6
|
# UNREADABLE dominates a mixed result, then RED: a failure anywhere dominates a kill.
|
|
7
|
+
#
|
|
8
|
+
# Two CLOSED inventories (v2.7.8 T4; the workflow renders these names): serial {test, test-macos}; sharded,
|
|
9
|
+
# for os in ubuntu-latest and macos-latest, `suite <os> k/4` for k 1..4, `single-fork <os>`, `aggregate <os>`.
|
|
10
|
+
# A run holding any sharded name is graded against the sharded inventory, else the serial one. The first
|
|
11
|
+
# line is `INVENTORY form=<serial|sharded> declared=<n> observed=<n>`; each missing, duplicated or unknown
|
|
12
|
+
# name prints `INVENTORY_DEFECT kind=<missing|duplicate|unknown> job=<json-quoted name>` and makes the run
|
|
13
|
+
# UNREADABLE: a job the inventory does not name is never skipped.
|
|
14
|
+
#
|
|
15
|
+
# A verdict line is read only from the log lines whose gh step column equals its declared step, exactly
|
|
16
|
+
# once, else UNREADABLE — a line a test or any other step prints, before or after the real one, never decides:
|
|
17
|
+
# COUNT_ORACLE <GREEN|RED> expected=<n|UNREADABLE> actual=<n|UNREADABLE> step `Assert collected test-file count`
|
|
18
|
+
# COVERAGE_FLOORS verdict=… floors=… failing=… (T1's final floors line) step `Recheck coverage floors`
|
|
19
|
+
# SET_ORACLE verdict=… expected=… actual=… defects=… (T3's set oracle) step `Assert collected test-file set`
|
|
20
|
+
# ROLES — the shared classifier (classify-vitest-log.sh) stays the one log verdict:
|
|
21
|
+
# serial the base rule (count oracle GREEN at the expected count, the classifier given that count
|
|
22
|
+
# reading CLEAN or RPC_ONLY, passed+skipped equal to it) AND exactly one COVERAGE_FLOORS
|
|
23
|
+
# verdict=GREEN, so a dropped floors step reads UNREADABLE.
|
|
24
|
+
# shard, single-fork
|
|
25
|
+
# GREEN only on conclusion success whose whole log the classifier, given no count, reads CLEAN
|
|
26
|
+
# or RPC_ONLY: their wrapper already applied the shard contract in-job.
|
|
27
|
+
# aggregate GREEN only on conclusion success with exactly one COVERAGE_FLOORS verdict=GREEN, exactly one
|
|
28
|
+
# `SET_ORACLE verdict=GREEN expected=N actual=N defects=0`, and the lines of its step
|
|
29
|
+
# `Merge coverage (one threshold check per OS)` classified CLEAN or RPC_ONLY.
|
|
30
|
+
# Exit annotations: SERIAL keeps the one exception run-ci-vitest.sh grants (a failure explained ONLY by steps
|
|
31
|
+
# that exited exactly 1 on a log of their own the classifier reads RPC_ONLY); any other failing annotation is
|
|
32
|
+
# never GREEN. Shard, single-fork and aggregate admit none — their wrapper applied the exception in-job.
|
|
33
|
+
# INFRA_KILLED is the base rule for every role.
|
|
7
34
|
set -u
|
|
8
35
|
|
|
9
36
|
run=${1:?run id required}
|
|
@@ -14,34 +41,96 @@ repo=${TKR_GRADE_CI_REPO:-alzahrani-khalid/tickmarkr}
|
|
|
14
41
|
out_dir=${TKR_GRADE_CI_DIR:-${TKR_STATE_DIR:-.tickmarkr}/overseer/diag}
|
|
15
42
|
mkdir -p "$out_dir" || { echo "UNREADABLE: cannot create log directory $out_dir"; exit 2; }
|
|
16
43
|
|
|
44
|
+
serial_inventory=$'test\ntest-macos'
|
|
45
|
+
sharded_inventory=$(for os in ubuntu-latest macos-latest; do
|
|
46
|
+
for k in 1 2 3 4; do echo "suite $os $k/4"; done
|
|
47
|
+
echo "single-fork $os"
|
|
48
|
+
echo "aggregate $os"
|
|
49
|
+
done)
|
|
50
|
+
COUNT_STEP="Assert collected test-file count"
|
|
51
|
+
FLOORS_STEP="Recheck coverage floors"
|
|
52
|
+
SET_STEP="Assert collected test-file set"
|
|
53
|
+
MERGE_STEP="Merge coverage (one threshold check per OS)"
|
|
54
|
+
COUNT_FORMAT='COUNT_ORACLE (GREEN|RED) expected=([0-9]+|UNREADABLE) actual=([0-9]+|UNREADABLE)'
|
|
55
|
+
FLOORS_FORMAT='COVERAGE_FLOORS verdict=(GREEN|RED|UNREADABLE) floors=([0-9]+|UNREADABLE) failing=([0-9]+|UNREADABLE)'
|
|
56
|
+
SET_FORMAT='SET_ORACLE verdict=(GREEN|RED|UNREADABLE) expected=([0-9]+|UNREADABLE) actual=([0-9]+|UNREADABLE) defects=[0-9]+'
|
|
57
|
+
|
|
17
58
|
verdict=0
|
|
18
59
|
mark_unreadable() { verdict=2; }
|
|
19
60
|
mark_red() { [ "$verdict" -eq 2 ] || verdict=1; }
|
|
20
61
|
mark_killed() { [ "$verdict" -ne 0 ] || verdict=3; }
|
|
21
62
|
field() { printf '%s\n' "$classified" | sed -n "s/^VITEST_LOG.* $1=\([^ ]*\).*/\1/p"; }
|
|
63
|
+
count() { printf '%s' "$1" | grep -c ''; }
|
|
64
|
+
# json <name> — one JSON string; awk -v decodes gh's @tsv escapes (\t \n \r \\) first
|
|
65
|
+
json() {
|
|
66
|
+
LC_ALL=C awk -v s="$1" 'BEGIN {
|
|
67
|
+
for (i = 1; i < 32; i++) esc[sprintf("%c", i)] = sprintf("\\u%04x", i)
|
|
68
|
+
esc["\""] = "\\\""; esc["\\"] = "\\\\"
|
|
69
|
+
for (i = 1; i <= length(s); i++) { c = substr(s, i, 1); out = out (c in esc ? esc[c] : c) }
|
|
70
|
+
print "\"" out "\""
|
|
71
|
+
}'
|
|
72
|
+
}
|
|
73
|
+
defect() { echo "INVENTORY_DEFECT kind=$1 job=$(json "$2")"; mark_unreadable; }
|
|
74
|
+
# step_log <log> <step> — the job-log lines gh's step column attributes to <step>, as gh printed them
|
|
75
|
+
step_log() { awk -F'\t' -v s="$2" 'NF >= 3 && $2 == s' "$1"; }
|
|
76
|
+
# verdict_line <log> <step> <family> <format> — the ONE <family> line <step> printed, in <format>;
|
|
77
|
+
# else MISSING, MULTIPLE(n) or MALFORMED, each UNREADABLE
|
|
78
|
+
verdict_line() {
|
|
79
|
+
local lines
|
|
80
|
+
lines=$(step_log "$1" "$2" | awk -v esc="$(printf '\033')" '{
|
|
81
|
+
gsub(/\^\[\[[0-9;]*m/, ""); gsub(esc "\\[[0-9;]*m", "")
|
|
82
|
+
sub(/^[^\t]*\t[^\t]*\t[0-9T:.-]+Z ?/, ""); sub(/[ \t\r]+$/, ""); print
|
|
83
|
+
}' | grep -E "^$3( |\$)")
|
|
84
|
+
case $(count "$lines") in
|
|
85
|
+
0) echo MISSING ;;
|
|
86
|
+
1) if printf '%s\n' "$lines" | grep -qxE "$4"; then printf '%s\n' "$lines"; else echo MALFORMED; fi ;;
|
|
87
|
+
*) echo "MULTIPLE($(count "$lines"))" ;;
|
|
88
|
+
esac
|
|
89
|
+
}
|
|
90
|
+
readable() { case $1 in MISSING|MULTIPLE*|MALFORMED) return 1 ;; esac; }
|
|
91
|
+
floors_green() { printf '%s\n' "$1" | grep -qxE 'COVERAGE_FLOORS verdict=GREEN floors=[0-9]+ failing=0'; }
|
|
22
92
|
|
|
23
93
|
jobs=$(gh run view "$run" --repo "$repo" --json jobs \
|
|
24
94
|
--jq '.jobs[] | [.databaseId, .name, .status, (.conclusion // "")] | @tsv') \
|
|
25
95
|
|| { echo "UNREADABLE: job list"; exit 2; }
|
|
26
|
-
|
|
96
|
+
# an empty job list is an inventory like any other: serial, observed=0, every declared job missing
|
|
97
|
+
|
|
98
|
+
names=$(printf '%s\n' "$jobs" | cut -f2)
|
|
99
|
+
if printf '%s\n' "$names" | grep -qxF -f <(printf '%s\n' "$sharded_inventory"); then
|
|
100
|
+
form=sharded; declared=$sharded_inventory
|
|
101
|
+
else
|
|
102
|
+
form=serial; declared=$serial_inventory
|
|
103
|
+
fi
|
|
104
|
+
echo "INVENTORY form=$form declared=$(count "$declared") observed=$(count "$names")"
|
|
105
|
+
while IFS= read -r name; do
|
|
106
|
+
case $(printf '%s\n' "$names" | grep -cxF -- "$name") in
|
|
107
|
+
0) defect missing "$name" ;;
|
|
108
|
+
1) ;;
|
|
109
|
+
*) defect duplicate "$name" ;;
|
|
110
|
+
esac
|
|
111
|
+
done <<< "$declared"
|
|
112
|
+
while IFS= read -r name; do
|
|
113
|
+
printf '%s\n' "$declared" | grep -qxF -- "$name" || defect unknown "$name"
|
|
114
|
+
done < <([ -z "$jobs" ] || printf '%s\n' "$names" | awk '!seen[$0]++')
|
|
27
115
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
116
|
+
[ -z "$jobs" ] || while IFS=$'\t' read -r id name status conclusion; do
|
|
117
|
+
# an unknown job has no role to grade: its INVENTORY_DEFECT already made the run UNREADABLE
|
|
118
|
+
printf '%s\n' "$declared" | grep -qxF -- "$name" || continue
|
|
31
119
|
case "$name" in
|
|
32
|
-
test)
|
|
33
|
-
|
|
34
|
-
*)
|
|
120
|
+
test|test-macos) role=serial ;;
|
|
121
|
+
suite\ *) role=shard ;;
|
|
122
|
+
single-fork\ *) role=single-fork ;;
|
|
123
|
+
*) role=aggregate ;;
|
|
35
124
|
esac
|
|
36
125
|
|
|
37
|
-
echo "$name: status=$status conclusion=${conclusion:-none} job=$id"
|
|
126
|
+
echo "$name: role=$role status=$status conclusion=${conclusion:-none} job=$id"
|
|
38
127
|
if [ "$status" != "completed" ]; then
|
|
39
128
|
echo "$name: UNREADABLE (job has not reached run-end)"
|
|
40
129
|
mark_unreadable
|
|
41
130
|
continue
|
|
42
131
|
fi
|
|
43
132
|
|
|
44
|
-
log="$out_dir/CI-$tag-$name.log"
|
|
133
|
+
log="$out_dir/CI-$tag-$(printf '%s' "$name" | tr -c 'A-Za-z0-9._-' '-').log"
|
|
45
134
|
gh run view --repo "$repo" --job "$id" --log > "$log" 2>/dev/null
|
|
46
135
|
if [ ! -s "$log" ]; then
|
|
47
136
|
echo "$name: UNREADABLE (empty log)"
|
|
@@ -49,24 +138,28 @@ while IFS=$'\t' read -r id name status conclusion; do
|
|
|
49
138
|
continue
|
|
50
139
|
fi
|
|
51
140
|
|
|
52
|
-
oracle=$(grep -oE 'COUNT_ORACLE [A-Z]+ expected=[0-9A-Z]+ actual=[0-9A-Z]+' "$log" | tail -1)
|
|
53
141
|
files=$(grep -oE 'Test Files .*' "$log" | sed 's/[[:space:]]*$//')
|
|
54
142
|
# OBS-1184: the log verdict comes from the ONE classifier the public CI wrapper also uses
|
|
55
143
|
# (scripts/run-ci-vitest.sh), so the badge and this grade cannot disagree. Its rules — complete
|
|
56
144
|
# summaries, failed/timed-out tests, coverage-threshold misses, and the RPC-timeout-only exception
|
|
57
145
|
# to "any unhandled error is RED" (OBS-1058) — live in classify-vitest-log.sh, stated once there.
|
|
58
|
-
#
|
|
59
|
-
|
|
146
|
+
# A serial job's expected count is its declared file contract: both steps' summaries must collect it all.
|
|
147
|
+
# A shard or single-fork job carries no count: its wrapper held it to its plan in-job.
|
|
148
|
+
if [ "$role" = serial ]; then
|
|
149
|
+
classified=$(bash "$here/classify-vitest-log.sh" "$log" "$expected" 2>&1)
|
|
150
|
+
else
|
|
151
|
+
classified=$(bash "$here/classify-vitest-log.sh" "$log" 2>&1)
|
|
152
|
+
fi
|
|
60
153
|
log_verdict=$(field verdict)
|
|
61
154
|
passed=$(field passed); skipped=$(field skipped); failed=$(field failed); timedout=$(field timedout)
|
|
62
155
|
unhandled=$(field unhandled); rpc=$(field runner_rpc_timeouts); coverage=$(field coverage_misses)
|
|
63
156
|
kills=$(field runner_kills)
|
|
64
157
|
errors=$(grep -oE '##\[error\].*' "$log" | sort | uniq -c | sed 's/^ *//' | tr '\n' ';')
|
|
65
158
|
# The commands' own outcomes stand, as in the wrapper: GREEN needs a success conclusion with no step
|
|
66
|
-
# exit annotation, or a failure explained ONLY by steps that exited exactly 1 on a log
|
|
67
|
-
# (gh's step column) that the classifier calls RPC_ONLY
|
|
68
|
-
#
|
|
69
|
-
#
|
|
159
|
+
# exit annotation, or — SERIAL only — a failure explained ONLY by steps that exited exactly 1 on a log
|
|
160
|
+
# of their own (gh's step column) that the classifier calls RPC_ONLY. Any other code (2, a signal's
|
|
161
|
+
# 137), any annotation on another role, an unexplained failure, or a cancelled, timed-out or missing
|
|
162
|
+
# conclusion is RED.
|
|
70
163
|
exits=$(grep -E '##\[error\]Process completed with exit code [0-9]+' "$log")
|
|
71
164
|
case "$conclusion" in
|
|
72
165
|
success) outcome=ok ;;
|
|
@@ -76,9 +169,9 @@ while IFS=$'\t' read -r id name status conclusion; do
|
|
|
76
169
|
if [ -n "$exits" ]; then
|
|
77
170
|
while IFS= read -r exit_line; do
|
|
78
171
|
code=$(printf '%s\n' "$exit_line" | sed -E 's/.*Process completed with exit code ([0-9]+).*/\1/')
|
|
79
|
-
if [ "$code" != 1 ]; then outcome="exit-$code"; break; fi
|
|
172
|
+
if [ "$code" != 1 ] || [ "$role" != serial ]; then outcome="exit-$code"; break; fi
|
|
80
173
|
step=$(printf '%s\n' "$exit_line" | awk -F'\t' 'NF >= 3 { print $2 }')
|
|
81
|
-
|
|
174
|
+
step_log "$log" "$step" > "$log.step"
|
|
82
175
|
case $(bash "$here/classify-vitest-log.sh" "$log.step" 2>&1) in
|
|
83
176
|
"VITEST_LOG verdict=RPC_ONLY "*) ;;
|
|
84
177
|
*) outcome="exit-1-not-rpc-only"; break ;;
|
|
@@ -86,36 +179,60 @@ while IFS=$'\t' read -r id name status conclusion; do
|
|
|
86
179
|
done <<< "$exits"
|
|
87
180
|
fi
|
|
88
181
|
|
|
89
|
-
|
|
90
|
-
|
|
182
|
+
oracles=
|
|
183
|
+
case $role in
|
|
184
|
+
serial)
|
|
185
|
+
oracle=$(verdict_line "$log" "$COUNT_STEP" COUNT_ORACLE "$COUNT_FORMAT")
|
|
186
|
+
floors=$(verdict_line "$log" "$FLOORS_STEP" COVERAGE_FLOORS "$FLOORS_FORMAT")
|
|
187
|
+
oracles="oracle=[$oracle] floors=[$floors] " ;;
|
|
188
|
+
aggregate)
|
|
189
|
+
floors=$(verdict_line "$log" "$FLOORS_STEP" COVERAGE_FLOORS "$FLOORS_FORMAT")
|
|
190
|
+
set_oracle=$(verdict_line "$log" "$SET_STEP" SET_ORACLE "$SET_FORMAT")
|
|
191
|
+
step_log "$log" "$MERGE_STEP" > "$log.merge"
|
|
192
|
+
merge=$(bash "$here/classify-vitest-log.sh" "$log.merge" 2>&1 | sed -n 's/^VITEST_LOG verdict=\([^ ]*\) reason=\([^ ]*\) .*/\1 \2/p')
|
|
193
|
+
oracles="floors=[$floors] set=[$set_oracle] merge=[$merge] " ;;
|
|
194
|
+
esac
|
|
195
|
+
|
|
196
|
+
echo "$name: ${oracles}files=[$(printf '%s' "$files" | tr '\n' '|')] passed=$passed skipped=$skipped failed=$failed timedout=$timedout unhandled=$unhandled runner_rpc_timeouts=$rpc coverage_misses=$coverage runner_kills=${kills:-?} log=[$(field reason)] outcome=[$outcome] errors=[$errors]"
|
|
197
|
+
# A killed runner skips the oracle steps, so a missing verdict line is the kill's, not an unreadable log:
|
|
91
198
|
# INFRA_KILLED unless a step's own failing exit or a failed/timed-out test dominates it (then RED).
|
|
92
199
|
if [ "$log_verdict" = INFRA_KILLED ] && [ "${outcome#exit-}" = "$outcome" ]; then
|
|
93
200
|
echo "$name: INFRA_KILLED"
|
|
94
201
|
mark_killed
|
|
202
|
+
continue
|
|
95
203
|
elif [ "${kills:-0}" -gt 0 ] 2>/dev/null; then
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
echo "$name: UNREADABLE"
|
|
100
|
-
mark_unreadable
|
|
101
|
-
elif [ "$oracle" = "COUNT_ORACLE GREEN expected=$expected actual=$expected" ] \
|
|
102
|
-
&& { [ "$log_verdict" = CLEAN ] || [ "$log_verdict" = RPC_ONLY ]; } && [ "$outcome" = ok ] \
|
|
103
|
-
&& [ $((passed + skipped)) -eq "$expected" ]; then
|
|
104
|
-
echo "$name: GREEN"
|
|
204
|
+
grade=RED
|
|
205
|
+
elif [ -z "$log_verdict" ]; then
|
|
206
|
+
grade=UNREADABLE
|
|
105
207
|
else
|
|
106
|
-
|
|
107
|
-
|
|
208
|
+
case $log_verdict in CLEAN|RPC_ONLY) log_ok=1 ;; *) log_ok= ;; esac
|
|
209
|
+
grade=RED
|
|
210
|
+
case $role in
|
|
211
|
+
serial)
|
|
212
|
+
if ! readable "$oracle" || ! readable "$floors" || [ -z "$files" ]; then
|
|
213
|
+
grade=UNREADABLE
|
|
214
|
+
elif [ "$oracle" = "COUNT_ORACLE GREEN expected=$expected actual=$expected" ] && floors_green "$floors" \
|
|
215
|
+
&& [ -n "$log_ok" ] && [ "$outcome" = ok ] && [ $((passed + skipped)) -eq "$expected" ]; then
|
|
216
|
+
grade=GREEN
|
|
217
|
+
fi ;;
|
|
218
|
+
shard|single-fork)
|
|
219
|
+
if [ "$outcome" = ok ] && [ "$conclusion" = success ] && [ -n "$log_ok" ]; then grade=GREEN; fi ;;
|
|
220
|
+
aggregate)
|
|
221
|
+
if ! readable "$floors" || ! readable "$set_oracle"; then
|
|
222
|
+
grade=UNREADABLE
|
|
223
|
+
elif [ "$outcome" = ok ] && [ "$conclusion" = success ] && floors_green "$floors" \
|
|
224
|
+
&& [ "$set_oracle" = "SET_ORACLE verdict=GREEN expected=$expected actual=$expected defects=0" ] \
|
|
225
|
+
&& { [ "${merge%% *}" = CLEAN ] || [ "${merge%% *}" = RPC_ONLY ]; }; then
|
|
226
|
+
grade=GREEN
|
|
227
|
+
fi ;;
|
|
228
|
+
esac
|
|
108
229
|
fi
|
|
230
|
+
echo "$name: $grade"
|
|
231
|
+
case $grade in
|
|
232
|
+
RED) mark_red ;;
|
|
233
|
+
UNREADABLE) mark_unreadable ;;
|
|
234
|
+
esac
|
|
109
235
|
done <<< "$jobs"
|
|
110
236
|
|
|
111
|
-
if [ "$seen_test" -ne 1 ]; then
|
|
112
|
-
echo "test: UNREADABLE (job missing from run)"
|
|
113
|
-
mark_unreadable
|
|
114
|
-
fi
|
|
115
|
-
if [ "$seen_macos" -ne 1 ]; then
|
|
116
|
-
echo "test-macos: UNREADABLE (job missing from run)"
|
|
117
|
-
mark_unreadable
|
|
118
|
-
fi
|
|
119
|
-
|
|
120
237
|
echo "VERDICT rc=$verdict (0=all GREEN 1=RED 2=UNREADABLE 3=INFRA_KILLED)"
|
|
121
238
|
exit "$verdict"
|