Skip to content

chore: backfill missing jammy checksums #1

chore: backfill missing jammy checksums

chore: backfill missing jammy checksums #1

name: backfill-checksums
# Temporary: computes the missing `.sha512` files of old releases and uploads
# them. Runs on push to this branch only, as `workflow_dispatch` needs the
# workflow on the default branch. Delete the branch when done.
on:
push:
branches:
- chore/backfill-checksums
permissions:
contents: write
env:
# first run reports only, a follow-up commit sets it to 'false' to upload
DRY_RUN: 'true'
jobs:
backfill:
runs-on: ubuntu-24.04
timeout-minutes: 180
steps:
- name: backfill
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
set -euo pipefail
work="${RUNNER_TEMP}/assets"
mkdir -p "${work}"
summary="${GITHUB_STEP_SUMMARY}"
{
echo "## Missing checksums (dry run: ${DRY_RUN})"
echo
echo "| release | asset | validated by | action |"
echo "| --- | --- | --- | --- |"
} >> "${summary}"
gh release list --limit 1000 --exclude-drafts --json tagName --jq '.[].tagName' > "${work}/tags"
while read -r tag; do
gh release view "${tag}" --json assets \
--jq '.assets[] | [.name, (.digest // "-"), (.size | tostring)] | @tsv' \
< /dev/null > "${work}/assets"
cut -f1 "${work}/assets" > "${work}/names"
while IFS=$'\t' read -r name digest size; do
# only jammy, which noble and resolute use too
case "${name}" in
*-jammy-*.tar.xz) ;;
*) continue ;;
esac
# keep existing checksums untouched
if grep -qxF "${name}.sha512" "${work}/names"; then
continue
fi
file="${work}/${name}"
gh release download "${tag}" --pattern "${name}" --dir "${work}" --clobber < /dev/null
# the download must match what github reports for the asset
actual_size=$(stat -c %s "${file}")
if [[ "${actual_size}" != "${size}" ]]; then
echo "::error::${tag}/${name}: size ${actual_size} != ${size}"
exit 1
fi
validated="size"
if [[ "${digest}" == sha256:* ]]; then
actual=$(sha256sum "${file}" | cut -d' ' -f1)
if [[ "sha256:${actual}" != "${digest}" ]]; then
echo "::error::${tag}/${name}: sha256 ${actual} != ${digest}"
exit 1
fi
validated="github digest"
fi
# same format as the existing files: the bare hex hash, no newline
sha512sum "${file}" | cut -d' ' -f1 | tr -d '\n' > "${file}.sha512"
action="would upload"
if [[ "${DRY_RUN}" == "false" ]]; then
# no --clobber, an existing checksum is never replaced
gh release upload "${tag}" "${file}.sha512" < /dev/null
action="uploaded"
fi
echo "| ${tag} | ${name} | ${validated} | ${action} |" >> "${summary}"
rm -f "${file}" "${file}.sha512"
done < "${work}/assets"
done < "${work}/tags"