1616 runs-on : ubuntu-slim
1717 permissions :
1818 pull-requests : write
19+ statuses : write
1920 steps :
2021 - name : Download artefacts
2122 uses : actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
@@ -41,30 +42,50 @@ jobs:
4142 set -x
4243 > requisites-before.list
4344 > requisites-after.list
44- TABLE=$(
45+ {
4546 echo '| Platform | Number of requisites | Proportion of new derivations |'
4647 echo '| :-: | -: | -: |'
4748 TOTAL_BEFORE=0
4849 TOTAL_AFTER=0
4950 TOTAL_CHANGED=0
5051 QUOTE='`'
5152 for PLATFORM in x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin; do
53+ if [ ! -f "requisites-${PLATFORM}-before.list" ] || [ ! -f "requisites-${PLATFORM}-after.list" ]; then
54+ echo "| ${QUOTE}${PLATFORM}${QUOTE} | _missing data_ | _missing data_ |"
55+ continue
56+ fi
5257 BEFORE=$(wc -l < "requisites-${PLATFORM}-before.list")
5358 TOTAL_BEFORE=$(($TOTAL_BEFORE + $BEFORE))
5459 AFTER=$(wc -l < "requisites-${PLATFORM}-after.list")
5560 TOTAL_AFTER=$(($TOTAL_AFTER + $AFTER))
5661 DIFF="_no changes_"
5762 [ "$BEFORE" = "$AFTER" ] || DIFF="**$([ "$AFTER" -lt "$BEFORE" ] || echo '+')$(($AFTER - $BEFORE))**"
58- CHANGED=$(git diff --no-index "requisites-${PLATFORM}-before.list" "requisites-${PLATFORM}-after.list" | grep -c '^+[^+]')
63+ CHANGED=$(git diff --no-index "requisites-${PLATFORM}-before.list" "requisites-${PLATFORM}-after.list" | grep -c '^+[^+]' || true )
5964 TOTAL_CHANGED=$(($TOTAL_CHANGED + $CHANGED))
6065 PERCENT=100
6166 [ "$CHANGED" = "$AFTER" ] || {
6267 PERMILLE=$((1000 * $CHANGED / $AFTER))
6368 PERCENT="$((PERMILLE / 10)).$((PERMILLE % 10))"
6469 }
6570 echo "| ${QUOTE}${PLATFORM}${QUOTE} | $BEFORE -> $AFTER => $DIFF | $CHANGED / $AFTER = $PERCENT% |"
66- awk '{ print $0 " ('"$PLATFORM"')" }' "requisites-${PLATFORM}-before.list" >> requisites-before.list
67- awk '{ print $0 " ('"$PLATFORM"')" }' "requisites-${PLATFORM}-after.list" >> requisites-after.list
71+ for STATE in before after; do
72+ # Split store paths into package name, output (or source archive extension), and version.
73+ awk -v OFS='\t' -v PLATFORM="$PLATFORM" '{
74+ name = substr($0, 45)
75+ pname = name
76+ output = "out"
77+ version = "_unversioned_"
78+ if (match(name, /-[^A-Za-z]/)) {
79+ pname = substr(name, 1, RSTART - 1)
80+ version = substr(name, RSTART + 1)
81+ if (match(version, /-[a-z]+$/) || match(version, /\.(tar(\.[a-z0-9]+)?|tgz|tbz2?|txz|zip|patch|diff)$/)) {
82+ output = substr(version, RSTART + 1)
83+ version = substr(version, 1, RSTART - 1)
84+ }
85+ }
86+ print pname, output, version, PLATFORM, $0
87+ }' "requisites-${PLATFORM}-${STATE}.list" >> "requisites-${STATE}.list"
88+ done
6889 done
6990
7091 DIFF="_no changes_"
@@ -75,24 +96,87 @@ jobs:
7596 PERCENT="$((PERMILLE / 10)).$((PERMILLE % 10))"
7697 }
7798 echo "| **Total** | $TOTAL_BEFORE -> $TOTAL_AFTER => $DIFF | $TOTAL_CHANGED / $TOTAL_AFTER = $PERCENT% |"
78- )
79- sort -k1.45 requisites-before.list > requisites-before.sort
80- sort -k1.45 requisites-after.list > requisites-after.sort
99+ } > comment.md
100+ sort requisites-before.list > requisites-before.sort
101+ sort requisites-after.list > requisites-after.sort
81102 if git diff -U0 --no-color --no-index requisites-before.sort requisites-after.sort > requisites.diff; then
82103 echo 'No changes detected.'
83104 else
84- {
85- echo "$TABLE"
86- echo
87- echo '<details><summary>Changelog</summary>'
88- echo
89- echo '```diff'
90- tail -n +5 requisites.diff
91- echo '```'
92- echo
93- echo '</details>'
94- } | gh pr comment -R "$GITHUB_REPOSITORY" "$PR_NUMBER" -F -
105+ awk -F '\t' '
106+ function insert(list, v, n, a, i, out, done) {
107+ n = split(list, a, " ")
108+ for (i = 1; i <= n; i++) if (a[i] == v) return list
109+ out = ""; done = 0
110+ for (i = 1; i <= n; i++) {
111+ if (!done && v < a[i]) { out = out " " v; done = 1 }
112+ out = out " " a[i]
113+ }
114+ if (!done) out = out " " v
115+ return substr(out, 2)
116+ }
117+ function join(list, pre, post, s) {
118+ s = pre list post
119+ gsub(/ /, post ", " pre, s)
120+ return s
121+ }
122+ /^[-+]/ && NF == 5 {
123+ key = substr($1, 2) SUBSEP $2 SUBSEP $4
124+ if (substr($1, 1, 1) == "-") removed[key] = insert(removed[key], $3)
125+ else added[key] = insert(added[key], $3)
126+ }
127+ END {
128+ for (key in removed) if (!(key in added)) added[key] = ""
129+ for (key in added) {
130+ split(key, k, SUBSEP)
131+ r = (key in removed) ? removed[key] : ""
132+ a = added[key]
133+ if (r == a) change = "_no version change_: " join(a)
134+ else if (r == "") change = "_added_: " join(a, "**", "**")
135+ else if (a == "") change = "_removed_: " join(r)
136+ else change = join(r) " -> " join(a, "**", "**")
137+ platforms[k[1] SUBSEP k[2] SUBSEP change] = insert(platforms[k[1] SUBSEP k[2] SUBSEP change], k[3])
138+ }
139+ for (key in platforms) {
140+ split(key, k, SUBSEP)
141+ row = k[1] SUBSEP k[3] SUBSEP join(platforms[key])
142+ outputs[row] = insert(outputs[row], k[2])
143+ }
144+ for (row in outputs) {
145+ split(row, k, SUBSEP)
146+ n = split(outputs[row], o, " ")
147+ name = ""
148+ for (i = 1; i <= n; i++) name = name ", `" k[1] (o[i] == "out" ? "" : "." o[i]) "`"
149+ rank = k[2] ~ /^_added_/ ? 0 : k[2] ~ /^_removed_/ ? 2 : k[2] ~ /^_no version change_/ ? 3 : 1
150+ print rank "\t| " substr(name, 3) " | " k[2] " | " k[3] " |"
151+ }
152+ }
153+ ' requisites.diff > versions.tsv
154+ {
155+ echo
156+ echo '<details><summary>Version changes</summary>'
157+ echo
158+ echo '| Package | Version | Platforms |'
159+ echo '| :- | :- | :- |'
160+ LC_ALL=C sort -t '`' -k1,1 -k2,2 -k3 versions.tsv | cut -f2-
161+ echo
162+ echo '</details>'
163+ } >> comment.md
164+ gh pr comment -R "$GITHUB_REPOSITORY" "$PR_NUMBER" -F comment.md
95165 fi
96166 env :
97167 GH_TOKEN : ${{ github.token }}
98168 PR_NUMBER : ${{ steps.pr-data.outputs.NUMBER }}
169+
170+ - name : Report status on the PR
171+ if : ${{ always() }}
172+ run : |
173+ gh api --method POST "repos/${GITHUB_REPOSITORY}/statuses/${HEAD_SHA}" \
174+ -f state="$STATE" \
175+ -f context="$GITHUB_WORKFLOW" \
176+ -f description="$DESCRIPTION" \
177+ -f target_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
178+ env :
179+ GH_TOKEN : ${{ github.token }}
180+ HEAD_SHA : ${{ github.event.workflow_run.head_sha }}
181+ STATE : ${{ job.status == 'success' && 'success' || 'failure' }}
182+ DESCRIPTION : ${{ job.status == 'success' && 'Nix requisites changes aggregated' || 'Failed to aggregate Nix requisites changes' }}
0 commit comments