Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 102 additions & 18 deletions .github/workflows/nix-changes-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
runs-on: ubuntu-slim
permissions:
pull-requests: write
statuses: write
steps:
- name: Download artefacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
Expand All @@ -41,30 +42,50 @@ jobs:
set -x
> requisites-before.list
> requisites-after.list
TABLE=$(
{
echo '| Platform | Number of requisites | Proportion of new derivations |'
echo '| :-: | -: | -: |'
TOTAL_BEFORE=0
TOTAL_AFTER=0
TOTAL_CHANGED=0
QUOTE='`'
for PLATFORM in x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin; do
if [ ! -f "requisites-${PLATFORM}-before.list" ] || [ ! -f "requisites-${PLATFORM}-after.list" ]; then
echo "| ${QUOTE}${PLATFORM}${QUOTE} | _missing data_ | _missing data_ |"
continue
fi
BEFORE=$(wc -l < "requisites-${PLATFORM}-before.list")
TOTAL_BEFORE=$(($TOTAL_BEFORE + $BEFORE))
AFTER=$(wc -l < "requisites-${PLATFORM}-after.list")
TOTAL_AFTER=$(($TOTAL_AFTER + $AFTER))
DIFF="_no changes_"
[ "$BEFORE" = "$AFTER" ] || DIFF="**$([ "$AFTER" -lt "$BEFORE" ] || echo '+')$(($AFTER - $BEFORE))**"
CHANGED=$(git diff --no-index "requisites-${PLATFORM}-before.list" "requisites-${PLATFORM}-after.list" | grep -c '^+[^+]')
CHANGED=$(git diff --no-index "requisites-${PLATFORM}-before.list" "requisites-${PLATFORM}-after.list" | grep -c '^+[^+]' || true)
TOTAL_CHANGED=$(($TOTAL_CHANGED + $CHANGED))
PERCENT=100
[ "$CHANGED" = "$AFTER" ] || {
PERMILLE=$((1000 * $CHANGED / $AFTER))
PERCENT="$((PERMILLE / 10)).$((PERMILLE % 10))"
}
echo "| ${QUOTE}${PLATFORM}${QUOTE} | $BEFORE -> $AFTER => $DIFF | $CHANGED / $AFTER = $PERCENT% |"
awk '{ print $0 " ('"$PLATFORM"')" }' "requisites-${PLATFORM}-before.list" >> requisites-before.list
awk '{ print $0 " ('"$PLATFORM"')" }' "requisites-${PLATFORM}-after.list" >> requisites-after.list
for STATE in before after; do
# Split store paths into package name, output (or source archive extension), and version.
awk -v OFS='\t' -v PLATFORM="$PLATFORM" '{
name = substr($0, 45)
pname = name
output = "out"
version = "_unversioned_"
if (match(name, /-[^A-Za-z]/)) {
pname = substr(name, 1, RSTART - 1)
version = substr(name, RSTART + 1)
if (match(version, /-[a-z]+$/) || match(version, /\.(tar(\.[a-z0-9]+)?|tgz|tbz2?|txz|zip|patch|diff)$/)) {
output = substr(version, RSTART + 1)
version = substr(version, 1, RSTART - 1)
}
}
print pname, output, version, PLATFORM, $0
}' "requisites-${PLATFORM}-${STATE}.list" >> "requisites-${STATE}.list"
done
done

DIFF="_no changes_"
Expand All @@ -75,24 +96,87 @@ jobs:
PERCENT="$((PERMILLE / 10)).$((PERMILLE % 10))"
}
echo "| **Total** | $TOTAL_BEFORE -> $TOTAL_AFTER => $DIFF | $TOTAL_CHANGED / $TOTAL_AFTER = $PERCENT% |"
)
sort -k1.45 requisites-before.list > requisites-before.sort
sort -k1.45 requisites-after.list > requisites-after.sort
} > comment.md
sort requisites-before.list > requisites-before.sort
sort requisites-after.list > requisites-after.sort
if git diff -U0 --no-color --no-index requisites-before.sort requisites-after.sort > requisites.diff; then
echo 'No changes detected.'
else
{
echo "$TABLE"
echo
echo '<details><summary>Changelog</summary>'
echo
echo '```diff'
tail -n +5 requisites.diff
echo '```'
echo
echo '</details>'
} | gh pr comment -R "$GITHUB_REPOSITORY" "$PR_NUMBER" -F -
awk -F '\t' '
function insert(list, v, n, a, i, out, done) {
n = split(list, a, " ")
for (i = 1; i <= n; i++) if (a[i] == v) return list
out = ""; done = 0
for (i = 1; i <= n; i++) {
if (!done && v < a[i]) { out = out " " v; done = 1 }
out = out " " a[i]
}
if (!done) out = out " " v
return substr(out, 2)
}
function join(list, pre, post, s) {
s = pre list post
gsub(/ /, post ", " pre, s)
return s
}
/^[-+]/ && NF == 5 {
key = substr($1, 2) SUBSEP $2 SUBSEP $4
if (substr($1, 1, 1) == "-") removed[key] = insert(removed[key], $3)
else added[key] = insert(added[key], $3)
}
END {
for (key in removed) if (!(key in added)) added[key] = ""
for (key in added) {
split(key, k, SUBSEP)
r = (key in removed) ? removed[key] : ""
a = added[key]
if (r == a) change = "_no version change_: " join(a)
else if (r == "") change = "_added_: " join(a, "**", "**")
else if (a == "") change = "_removed_: " join(r)
else change = join(r) " -> " join(a, "**", "**")
platforms[k[1] SUBSEP k[2] SUBSEP change] = insert(platforms[k[1] SUBSEP k[2] SUBSEP change], k[3])
}
for (key in platforms) {
split(key, k, SUBSEP)
row = k[1] SUBSEP k[3] SUBSEP join(platforms[key])
outputs[row] = insert(outputs[row], k[2])
}
for (row in outputs) {
split(row, k, SUBSEP)
n = split(outputs[row], o, " ")
name = ""
for (i = 1; i <= n; i++) name = name ", `" k[1] (o[i] == "out" ? "" : "." o[i]) "`"
rank = k[2] ~ /^_added_/ ? 0 : k[2] ~ /^_removed_/ ? 2 : k[2] ~ /^_no version change_/ ? 3 : 1
print rank "\t| " substr(name, 3) " | " k[2] " | " k[3] " |"
}
}
' requisites.diff > versions.tsv
{
echo
echo '<details><summary>Version changes</summary>'
echo
echo '| Package | Version | Platforms |'
echo '| :- | :- | :- |'
LC_ALL=C sort -t '`' -k1,1 -k2,2 -k3 versions.tsv | cut -f2-
echo
echo '</details>'
} >> comment.md
gh pr comment -R "$GITHUB_REPOSITORY" "$PR_NUMBER" -F comment.md
fi
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ steps.pr-data.outputs.NUMBER }}

- name: Report status on the PR
if: ${{ always() }}
run: |
gh api --method POST "repos/${GITHUB_REPOSITORY}/statuses/${HEAD_SHA}" \
-f state="$STATE" \
-f context="$GITHUB_WORKFLOW" \
-f description="$DESCRIPTION" \
-f target_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
env:
GH_TOKEN: ${{ github.token }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
STATE: ${{ job.status == 'success' && 'success' || 'failure' }}
DESCRIPTION: ${{ job.status == 'success' && 'Nix requisites changes aggregated' || 'Failed to aggregate Nix requisites changes' }}
Loading