chore: backfill missing jammy checksums #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" |