ci: post install-test numbers on the pull request
A second workflow, triggered when the install test completes, posts one comment on the pull request and updates it on every run: install, first boot and everyday boot next to quattro's latest numbers, with the change, and the install phases in a collapsed table. Pushes to quattro now run the install test too, so there is always a baseline. It runs from quattro's copy with write access, which works for pull requests from forks, so it never checks out or runs pull request code. It reads only the finished run's artifact, trusts the pull request number in it only when that pull request's head is the commit the run tested, and keeps phase names to plain text.
This commit is contained in:
1 parent
1ad8872146
commit
6aef3008c1
2 files changed
+118
No files matched your search
@@ -0,0 +1,108 @@
|
||||
name: Install test comment
|
||||
|
||||
# Posts the install test's numbers on the pull request as one comment, kept
|
||||
# up to date on every run, next to quattro's latest numbers. GitHub runs
|
||||
# workflow_run workflows from the default branch, with write access even for
|
||||
# pull requests from forks, so this job never checks out or runs pull request
|
||||
# code: it only reads the finished run's artifact, as data.
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Install test"]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
if: github.event.workflow_run.event == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
REPO: ${{ github.repository }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
RUN_URL: ${{ github.event.workflow_run.html_url }}
|
||||
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
CONCLUSION: ${{ github.event.workflow_run.conclusion }}
|
||||
steps:
|
||||
- name: Fetch this run's numbers and quattro's latest
|
||||
run: |
|
||||
gh run download "$RUN_ID" -R "$REPO" -D pr || true
|
||||
base=$(gh run list -R "$REPO" --workflow install-test.yml --branch quattro --event push \
|
||||
--status success -L 1 --json databaseId -q '.[0].databaseId')
|
||||
if [ -n "$base" ]; then gh run download "$base" -R "$REPO" -D base || true; fi
|
||||
|
||||
- name: Comment on the pull request
|
||||
run: |
|
||||
set -euo pipefail
|
||||
marker='<!-- omarchy-install-test -->'
|
||||
|
||||
# The number comes from the pull request's own run, so trust it only
|
||||
# when that pull request's head is the commit this run tested.
|
||||
pr=$(find pr -name pr-number -exec cat {} + 2>/dev/null | head -1 | tr -dc 0-9)
|
||||
[ -n "$pr" ] || { echo "No pull request number in the artifact"; exit 0; }
|
||||
[ "$(gh api "repos/$REPO/pulls/$pr" -q .head.sha)" = "$HEAD_SHA" ] ||
|
||||
{ echo "PR #$pr has moved past $HEAD_SHA; not commenting"; exit 0; }
|
||||
|
||||
timing() { find "$1" -name omarchy-install-timing.json 2>/dev/null | head -1; }
|
||||
install_s() { [ -n "$1" ] && jq -r '.finished_at - .started_at' "$1" 2>/dev/null; }
|
||||
# "Startup finished in … = 1min 2.3s" or "= 12.104s" -> seconds
|
||||
boot_s() {
|
||||
local f
|
||||
f=$(find "$1" -path "$2" 2>/dev/null | head -1)
|
||||
[ -n "$f" ] && head -1 "$f" | sed -n 's/.*= *//p' |
|
||||
awk '{t=0; for (i=1;i<=NF;i++) { if ($i ~ /min$/) t+=60*$i; else if ($i ~ /ms$/) t+=$i/1000; else t+=$i } printf "%.3f", t}'
|
||||
}
|
||||
cell() { [ -n "$1" ] && awk -v x="$1" 'BEGIN{printf "%.1f s", x}' || echo "–"; }
|
||||
change() {
|
||||
[ -n "$1" ] && [ -n "$2" ] || { echo "–"; return; }
|
||||
awk -v a="$1" -v b="$2" 'BEGIN{d=a-b; printf "%s%.1f s", (d>=0?"+":"−"), (d<0?-d:d)}'
|
||||
}
|
||||
|
||||
pt=$(timing pr); bt=$(timing base)
|
||||
rows=(
|
||||
"Install|$(install_s "$pt")|$(install_s "$bt")"
|
||||
"First boot|$(boot_s pr '*/first-boot-systemd-analyze.txt')|$(boot_s base '*/first-boot-systemd-analyze.txt')"
|
||||
"Everyday boot|$(boot_s pr '*-boot/systemd-analyze.txt')|$(boot_s base '*-boot/systemd-analyze.txt')"
|
||||
)
|
||||
|
||||
status="passed"; [ "$CONCLUSION" = success ] || status="**${CONCLUSION}**"
|
||||
{
|
||||
echo "$marker"
|
||||
echo "### Install test $status"
|
||||
echo
|
||||
echo "| | This PR | quattro | Change |"
|
||||
echo "| --- | ---: | ---: | ---: |"
|
||||
for row in "${rows[@]}"; do
|
||||
IFS='|' read -r name this base_v <<<"$row"
|
||||
echo "| $name | $(cell "$this") | $(cell "$base_v") | $(change "$this" "$base_v") |"
|
||||
done
|
||||
if [ -n "$pt" ]; then
|
||||
echo
|
||||
echo "<details><summary>Install phases</summary>"
|
||||
echo
|
||||
echo "| Phase | This PR | quattro |"
|
||||
echo "| --- | ---: | ---: |"
|
||||
# Phase names come from the pull request's installer: keep them to plain text.
|
||||
jq -r --slurpfile b <( [ -n "$bt" ] && cat "$bt" || echo '{"phases":[]}' ) '
|
||||
($b[0].phases | map({key: .name, value: .elapsed}) | from_entries) as $base
|
||||
| .phases[]
|
||||
| "| \(.name | gsub("[^A-Za-z0-9 +&/().-]"; "") | .[0:60]) | \(.elapsed * 10 | round / 10) s | \(($base[.name] // null) | if . == null then "–" else "\(. * 10 | round / 10) s" end) |"
|
||||
' "$pt"
|
||||
echo
|
||||
echo "</details>"
|
||||
fi
|
||||
echo
|
||||
echo "[Run]($RUN_URL) · ${HEAD_SHA:0:8}"
|
||||
} > comment.md
|
||||
|
||||
existing=$(gh api "repos/$REPO/issues/$pr/comments" --paginate \
|
||||
-q ".[] | select(.user.login == \"github-actions[bot]\" and (.body | startswith(\"$marker\"))) | .id" | head -1)
|
||||
if [ -n "$existing" ]; then
|
||||
gh api -X PATCH "repos/$REPO/issues/comments/$existing" -F body=@comment.md >/dev/null
|
||||
else
|
||||
gh api "repos/$REPO/issues/$pr/comments" -F body=@comment.md >/dev/null
|
||||
fi
|
||||
cat comment.md
|
||||
@@ -7,6 +7,9 @@ name: Install test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
# Each merge records quattro's numbers, which PR comments compare against.
|
||||
push:
|
||||
branches: [quattro]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -88,12 +91,19 @@ jobs:
|
||||
fi
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# The comment workflow runs from quattro and reads only this artifact;
|
||||
# it needs the PR number, which a workflow_run event omits for forks.
|
||||
- name: Record the pull request
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
run: mkdir -p test-runs && echo "${{ github.event.pull_request.number }}" > test-runs/pr-number
|
||||
|
||||
- name: Upload test artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
||||
with:
|
||||
name: install-test-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
path: |
|
||||
test-runs/pr-number
|
||||
test-runs/*/omarchy-install-timing.json
|
||||
test-runs/*/omarchy-install.log
|
||||
test-runs/*/first-boot-systemd-analyze.txt
|
||||
|
||||
Reference in new issue
Block a user