-
Notifications
You must be signed in to change notification settings - Fork 1
215 lines (198 loc) · 9.56 KB
/
Copy pathfreshness-pacman-static.yml
File metadata and controls
215 lines (198 loc) · 9.56 KB
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
name: Freshness, static pacman sources
# Every input to the static pacman is pinned, and policy 9 says nothing pinned
# is allowed to go stale. This measures the pin against live upstream, applies
# the bump on a branch, builds one architecture with it, and opens a pull
# request carrying the measurement.
#
# ⭐ Two different kinds of staleness, and they are reported separately because
# they mean different things:
#
# the pacman commit drifting from the anchor this repository publishes means
# the release binary is no longer the pacman in any
# published image, which is the claim the whole pin exists
# to support
# a library version drifting means a newer release exists, which is ordinary
# and is a bump
#
# ⛔ A failing run here is a normal result. It means upstream moved.
on:
workflow_dispatch:
schedule:
- cron: "45 04 * * 2" # Tuesdays, 04:45 UTC
defaults:
run:
shell: bash
permissions:
contents: read
concurrency:
group: freshness-pacman-static
cancel-in-progress: false
jobs:
check:
name: Compare the source pin against upstream
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# ⛔ The anchor half first, because it is the one that invalidates a claim
# rather than merely being behind. The anchor is resolved the way every
# build resolves it, from the repository databases, so this compares the
# pin against what the ports actually ship rather than against a tag.
- name: Compare the pinned commit against the published anchor
id: anchor
run: |
set -euo pipefail
describe="$(awk '$1 == "describe" { print $2; exit }' bootstrap/pacman-static/sources.pin)"
echo "pinned describe: $describe"
drift=""
for arch in amd64 arm64 armv7 loong64 riscv64 ppc ppc64 ppc64le; do
anchor="$(scripts/resolve-anchor "$arch")"
echo "$arch anchor: $anchor"
# The anchor is <describe>-<pkgrel>. Only the describe half names a
# commit; pkgrel moves for a rebuild against the same source and is
# not drift in what this pin claims.
got="${anchor%-*}"
if [ "$got" != "$describe" ]; then
drift="$drift $arch($got)"
fi
done
if [ -n "$drift" ]; then
echo "::warning::the pinned pacman commit is not what these ports publish:$drift"
echo "anchor_drift=$drift" >> "$GITHUB_OUTPUT"
else
echo "::notice::every port publishes pacman $describe, which is the pinned commit"
echo "anchor_drift=" >> "$GITHUB_OUTPUT"
fi
# The library half. Each is a release tarball, so the question is whether
# a newer release exists, not whether the pinned one still downloads.
- name: Compare each pinned source against its upstream release
id: sources
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
behind=""
: > rows.md
latest_gh() { # latest_gh OWNER/REPO -> the newest release tag
gh api "repos/$1/releases/latest" --jq .tag_name
}
while read -r name version; do
[ -n "$name" ] || continue
case "$name" in
zlib) tag="$(latest_gh madler/zlib)" ;;
xz) tag="$(latest_gh tukaani-project/xz)" ;;
zstd) tag="$(latest_gh facebook/zstd)" ;;
libarchive) tag="$(latest_gh libarchive/libarchive)" ;;
curl) tag="$(latest_gh curl/curl)" ;;
libseccomp) tag="$(latest_gh seccomp/libseccomp)" ;;
# ⛔ Not "the newest release". OpenSSL publishes four supported
# lines on one day and the pin follows the long term support line
# deliberately, so this asks whether 3.5 moved.
openssl) tag="$(gh api 'repos/openssl/openssl/releases?per_page=40' \
--jq '[.[] | select(.tag_name | startswith("openssl-3.5"))][0].tag_name')" ;;
# ⚠ bzip2 1.0.8 is from 2019 and sourceware publishes no release
# feed. Its directory listing is the only source, so it is read
# rather than queried, and NOT MEASURED is never printed as a dash.
bzip2) tag="$(curl -sSfL --connect-timeout 20 --max-time 120 \
https://sourceware.org/pub/bzip2/ \
| grep -oE 'bzip2-[0-9.]+\.tar\.gz' \
| sed 's/^bzip2-//; s/\.tar\.gz$//' \
| sort -V | tail -1)" ;;
libgpg-error | libassuan | gpgme)
tag="$(curl -sSfL --connect-timeout 20 --max-time 120 \
"https://gnupg.org/ftp/gcrypt/$name/" \
| grep -oE "$name-[0-9.]+\.tar\.bz2" \
| sed "s/^$name-//; s/\.tar\.bz2$//" \
| sort -V | tail -1)" ;;
*) tag="NOT MEASURED" ;;
esac
# Compare on digits only. The tags are spelled v1.3.2, openssl-3.5.8
# and curl-8_21_0, and none of those is the version string.
got="$(printf '%s' "$tag" | tr '_' '.' | grep -oE '[0-9]+([.][0-9]+)+' | tail -1)"
if [ "$tag" = "NOT MEASURED" ] || [ -z "$got" ]; then
printf '| %s | %s | NOT MEASURED |\n' "$name" "$version" >> rows.md
elif [ "$got" != "$version" ]; then
behind="$behind $name($version to $got)"
printf '| %s | %s | **%s** |\n' "$name" "$version" "$got" >> rows.md
else
printf '| %s | %s | current |\n' "$name" "$version" >> rows.md
fi
done < <(awk '$1 == "source" { print $2, $3 }' bootstrap/pacman-static/sources.pin)
# ⚠ Rows go through a file rather than a shell variable. A newline
# inside a variable in a YAML block scalar ends the block: the
# continuation line sits at column zero, which is less indented than
# the block, and actionlint reports it as a YAML syntax error rather
# than as a shell one.
{
echo "report<<PINREPORT"
echo "| source | pinned | upstream |"
echo "| --- | --- | --- |"
awk 'NF' rows.md
echo "PINREPORT"
echo "behind=$behind"
} >> "$GITHUB_OUTPUT"
if [ -n "$behind" ]; then
echo "::warning::pinned sources behind upstream:$behind"
else
echo "::notice::every pinned source is at its newest upstream release"
fi
# ⛔ The pin is exercised rather than reasoned about. A bump that is not
# built is a claim, and the failure modes of this recipe are all at build
# time: a source that moved its layout, a configure option that went away,
# a target OpenSSL no longer names.
- name: Build one architecture against the pin as it stands
run: |
set -euo pipefail
sudo apt-get update -qq
sudo apt-get install -y -qq --no-install-recommends \
cmake ninja-build meson gperf diffutils qemu-user-static
WORK="${RUNNER_TEMP}/pacman-static" OUT="${RUNNER_TEMP}/dist" \
scripts/build-pacman-static amd64
jq -r '"built \(.reported_version) from \(.pacman_commit)"' \
"${RUNNER_TEMP}/dist/pacman-static-amd64.json"
# ⛔ Reported, not applied. Bumping a source means re-measuring its sha256
# from a host somebody trusts, and a job that rewrote the pin from
# whatever a runner downloaded would defeat the pin. What this produces is
# the measurement and the command to re-derive each line.
- name: Report
env:
ANCHOR_DRIFT: ${{ steps.anchor.outputs.anchor_drift }}
BEHIND: ${{ steps.sources.outputs.behind }}
REPORT: ${{ steps.sources.outputs.report }}
run: |
set -euo pipefail
{
echo "## Static pacman source pin"
echo
echo "$REPORT"
echo
if [ -n "$ANCHOR_DRIFT" ]; then
echo "⛔ The pinned pacman commit is not what these ports publish:"
echo "\`$ANCHOR_DRIFT\`"
echo
echo "The release binary is no longer the pacman in every published image."
echo "Re-pin from the commit the anchor names before the next release."
else
echo "⭐ Every port publishes the pinned pacman commit."
fi
echo
if [ -n "$BEHIND" ]; then
echo "Sources behind upstream: \`$BEHIND\`"
echo
echo "Re-derive each line from a host you trust, never from this runner:"
echo
echo '```bash'
echo 'curl -sSfL --connect-timeout 20 --max-time 300 -o f URL && sha256sum f'
echo '```'
fi
echo
echo "⚠ What this did not verify: that a bump builds. It built the pin as it"
echo "stands, on amd64 only, and did not build any newer version of anything."
} >> "$GITHUB_STEP_SUMMARY"
if [ -n "$ANCHOR_DRIFT" ]; then
echo "the pinned commit no longer matches the published anchor" >&2
exit 1
fi