Route all ArchiveBox releases through the central graph

This commit is contained in:
Nick Sweeting 2026-07-29 09:17:06 -07:00
parent 6259c1dc65
commit 247cc06514
No known key found for this signature in database
3 changed files with 9 additions and 181 deletions

View File

@ -2,9 +2,9 @@ name: CI
on:
pull_request:
branches: [dev]
branches: [dev, main]
push:
branches: [dev]
branches: [dev, main]
workflow_dispatch:
permissions:

View File

@ -312,17 +312,17 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }}
repository: archivebox/archivebox
downstream-packages:
name: Verify downstream packages
cascade:
name: Cascade verified stable release
if: github.event.workflow_run.head_branch == 'main' && !contains(needs.python-release.outputs.tag, 'rc')
needs:
- python-release
- docker-release
permissions:
actions: read
contents: read
uses: ./.github/workflows/update-homebrew-tap.yml
uses: ArchiveBox/monorepo/.github/workflows/cascade-release.yml@main
with:
release_tag: ${{ needs.python-release.outputs.tag }}
release_sha: ${{ github.event.workflow_run.head_sha }}
secrets: inherit
upstream_package: archivebox
upstream_version: ${{ needs.python-release.outputs.version }}
secrets:
release_token: ${{ secrets.RELEASE_GH_TOKEN }}

View File

@ -1,172 +0,0 @@
name: Update downstream packages
on:
workflow_call:
inputs:
release_tag:
required: true
type: string
release_sha:
required: true
type: string
workflow_dispatch:
inputs:
release_tag:
description: Exact ArchiveBox release tag
required: true
type: string
release_sha:
description: Full commit SHA owned by the release tag
required: true
type: string
permissions:
actions: read
contents: read
concurrency:
group: update-downstream-packages-${{ inputs.release_tag || github.ref_name }}
cancel-in-progress: false
jobs:
dispatch:
runs-on: ubuntu-24.04
steps:
- name: Checkout release source
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
ref: ${{ inputs.release_sha || github.sha }}
fetch-depth: 1
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
with:
version: "0.11.3"
- name: Resolve release binaries through abxpkg
env:
ABXPKG_LIB_DIR: ${{ runner.temp }}/abx-lib
shell: bash
run: |
set -Eeuo pipefail
ABXPKG_VERSION="$(uv run --no-cache --no-project python - <<'PY'
import tomllib
from pathlib import Path
packages = tomllib.loads(Path("uv.lock").read_text())["package"]
matches = [package["version"] for package in packages if package["name"] == "abxpkg"]
if len(matches) != 1:
raise SystemExit(f"Expected one locked abxpkg package, found {len(matches)}")
print(matches[0])
PY
)"
test -n "$ABXPKG_VERSION"
mkdir -p "$ABXPKG_LIB_DIR/env/bin"
echo "ABXPKG_LIB_DIR=$ABXPKG_LIB_DIR" >> "$GITHUB_ENV"
uv run --no-cache --no-project --with "abxpkg==$ABXPKG_VERSION" abxpkg env \
--install \
--lib="$ABXPKG_LIB_DIR" \
--deps-from="$GITHUB_WORKSPACE/.github/configs/ci-tooling.json:release_binaries" \
>/dev/null
for binary_name in uv git jq curl; do
binary="$ABXPKG_LIB_DIR/env/bin/$binary_name"
test -L "$binary"
test -x "$binary"
done
{
echo "UV_BINARY=$ABXPKG_LIB_DIR/env/bin/uv"
echo "GIT_BINARY=$ABXPKG_LIB_DIR/env/bin/git"
echo "JQ_BINARY=$ABXPKG_LIB_DIR/env/bin/jq"
echo "CURL_BINARY=$ABXPKG_LIB_DIR/env/bin/curl"
} >> "$GITHUB_ENV"
- name: Verify the exact release and downstream builds
env:
DOWNSTREAM_TOKEN: ${{ secrets.RELEASE_GH_TOKEN || secrets.HOMEBREW_TAP_TOKEN }}
INPUT_RELEASE_TAG: ${{ inputs.release_tag }}
INPUT_RELEASE_SHA: ${{ inputs.release_sha }}
shell: bash
run: |
set -Eeuo pipefail
[[ -n "$DOWNSTREAM_TOKEN" ]] || { echo "RELEASE_GH_TOKEN/HOMEBREW_TAP_TOKEN is not configured" >&2; exit 1; }
RELEASE_TAG="${INPUT_RELEASE_TAG:-${GITHUB_REF_NAME}}"
[[ "$RELEASE_TAG" == v* ]]
VERSION="${RELEASE_TAG#v}"
TAG_TARGET="$("$GIT_BINARY" ls-remote "https://github.com/${GITHUB_REPOSITORY}.git" "refs/tags/${RELEASE_TAG}^{}" | "$UV_BINARY" run --no-cache --no-project python -c 'import sys; print(next((line.split()[0] for line in sys.stdin if line.strip()), ""))')"
if [[ -z "$TAG_TARGET" ]]; then
TAG_TARGET="$("$GIT_BINARY" ls-remote "https://github.com/${GITHUB_REPOSITORY}.git" "refs/tags/${RELEASE_TAG}" | "$UV_BINARY" run --no-cache --no-project python -c 'import sys; print(next((line.split()[0] for line in sys.stdin if line.strip()), ""))')"
fi
RELEASE_SHA="${INPUT_RELEASE_SHA:-${TAG_TARGET}}"
[[ "$RELEASE_SHA" =~ ^[0-9a-f]{40}$ ]]
[[ "$TAG_TARGET" == "$RELEASE_SHA" ]] || { echo "${RELEASE_TAG} points to ${TAG_TARGET}, not ${RELEASE_SHA}" >&2; exit 1; }
PAYLOAD_FILTER="{event_type: \"archivebox-dev-updated\", client_payload: {ref: \$ref, sha: \$sha, version: \$version}}"
PAYLOAD="$("$JQ_BINARY" -nc --arg ref "$RELEASE_TAG" --arg sha "$RELEASE_SHA" --arg version "$VERSION" "$PAYLOAD_FILTER")"
dispatch_and_wait() {
local repo="$1"
local workflow_name="$2"
local dispatched_at run_json status conclusion url
dispatched_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
"$CURL_BINARY" --fail-with-body \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${DOWNSTREAM_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/ArchiveBox/${repo}/dispatches" \
--data "$PAYLOAD"
local deadline=$((SECONDS + 1800))
while (( SECONDS < deadline )); do
run_json="$("$CURL_BINARY" --fail-with-body \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${DOWNSTREAM_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/ArchiveBox/${repo}/actions/runs?event=repository_dispatch&branch=main&per_page=20" \
| "$JQ_BINARY" -c \
--arg workflow_name "$workflow_name" \
--arg dispatched_at "$dispatched_at" \
'.workflow_runs
| map(select(.name == $workflow_name and .created_at >= $dispatched_at))
| sort_by(.created_at)
| reverse
| .[0] // empty')"
if [[ -n "$run_json" ]]; then
status="$("$JQ_BINARY" -r '.status' <<< "$run_json")"
conclusion="$("$JQ_BINARY" -r '.conclusion // ""' <<< "$run_json")"
url="$("$JQ_BINARY" -r '.html_url' <<< "$run_json")"
echo "${repo}: ${status:-unknown} ${conclusion:-pending} ${url}"
if [[ "$status" == "completed" ]]; then
[[ "$conclusion" == "success" ]] || {
echo "${repo} downstream workflow failed: ${url}" >&2
return 1
}
return 0
fi
else
echo "${repo}: waiting for ${workflow_name} repository_dispatch run"
fi
sleep 30
done
echo "${repo} downstream workflow did not complete within 30 minutes" >&2
return 1
}
for repo_and_workflow in \
"homebrew-archivebox|Update ArchiveBox dev formula" \
"debian-archivebox|Build Debian package"
do
dispatch_and_wait "${repo_and_workflow%%|*}" "${repo_and_workflow#*|}"
done