Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .github/workflows/verify-bundle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Bundle verify-and-bump loop (ADR 0049). Copy into your bundle repo's
# .github/workflows/ — under examples/ in protoAgent this file is inert.
#
# Two jobs:
# verify — installs THIS manifest's pin set into a scratch agent on a fresh
# protoAgent checkout and probes every declared console view. Runs on
# every PR (so a pin-bump must prove itself), on demand, and weekly
# (so a rotted pin set turns the schedule red instead of rotting silently).
# bump — (every trigger except pull_request: the schedule, manual dispatch,
# and the `member-released` repository_dispatch member repos send on
# release, #2960) checks each tag-pinned member for a newer
# release tag and opens/updates a PR with the bump; that PR then runs
# `verify`. But a PR opened with the repository GITHUB_TOKEN never
# auto-starts a `pull_request` run — GitHub holds it `action_required`
# until a maintainer approves it (see README.md "Pin-bump PR lifecycle",
# #2645). So this job (a) reuses ONE branch/PR per bundle repo instead of
# piling up duplicates every week, and (b) fails loudly — PR comment +
# label + a red job — if the run it just pushed doesn't show up started
# within a bounded wait, so an unapproved candidate reads as a
# maintenance failure instead of quietly rotting.

name: verify-bundle

on:
pull_request:
workflow_dispatch:
# Sent by a member repo's release.yml the moment it publishes a release (the
# member-side step lives in protoAgent's examples/bundles/member-release-notify.yml,
# #2960), so pins bump within minutes of a member release instead of at the
# next cron. The dispatch is a hint; the schedule below stays the backstop.
repository_dispatch:
types: [member-released]
schedule:
- cron: "17 6 * * 1" # weekly, Monday 06:17 UTC

permissions:
contents: write
pull-requests: write
issues: write # labeling the pin-bump PR (`gh pr edit --add-label`) rides the issues API
actions: read # `gh run list`, to detect the approval-required stall below

jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# The core to verify against — keep in sync with the manifest's
# `verified_against:` (a release tag), or use `main` to verify ahead.
# The repo variable PROTOAGENT_REF overrides `main` while this bundle depends on
# core that hasn't merged yet (e.g. `refs/pull/<n>/head`) — delete the variable
# once it lands, so verify tracks main again.
- uses: actions/checkout@v4
with:
repository: protoLabsAI/protoAgent
ref: ${{ vars.PROTOAGENT_REF || 'main' }}
path: protoagent

- uses: astral-sh/setup-uv@v5
- name: Sync protoAgent deps
working-directory: protoagent
run: uv sync

- name: Verify pin set (install + load + probe declared views)
working-directory: protoagent
run: uv run --no-sync python "$GITHUB_WORKSPACE/scripts/verify_bundle.py" "$GITHUB_WORKSPACE"

bump:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Check tag-pinned members for newer releases
id: check
run: |
python3 scripts/check_bundle_updates.py protoagent.bundle.yaml | tee "${BUMP_PINS_SCRATCH_DIR:-/tmp}/bumps.txt"
echo "changed=$(git diff --quiet && echo false || echo true)" >> "$GITHUB_OUTPUT"

# ONE candidate per bundle repo (#2645): a stable branch name means a later
# scheduled run force-pushes and updates the existing open PR instead of
# opening a duplicate. One manifest per bundle repo, so "per repo" here is
# just "per repo" — see README.md "Pin-bump PR lifecycle" for the full
# contract. Treat `bump-pins` as bot-owned: it is rewritten wholesale every
# run, so hand edits to it don't survive the next bump. Logic lives in
# scripts/bump_pins_pr.sh (#2669) — a real, unit-tested script rather than
# inline YAML bash, so a change to this contract has automated coverage
# instead of relying on a manual dry-run against a live repo.
- name: Open or update the pin-bump PR
if: steps.check.outputs.changed == 'true'
id: pr
env:
GH_TOKEN: ${{ github.token }}
run: bash "$GITHUB_WORKSPACE/scripts/bump_pins_pr.sh" open-or-update

# Make the approval-required stall visible instead of silent (#2645): poll
# for the `verify` run this push should have queued. If it comes back
# `action_required` (GitHub's recursion guard for GITHUB_TOKEN-authored
# PRs) — or never shows up at all within the bounded wait, which is worse —
# comment on the PR, label it, and fail this job so an unapproved candidate
# turns the weekly schedule red instead of rotting quietly.
#
# `bump-pins` is a permanently-reused branch (one candidate per bundle repo,
# see the step above), so on a repeat run the branch name alone can
# match a STALE prior run (already-approved from last week, or a
# leftover from a since-closed PR) before GitHub has even registered a
# run for the commit just pushed — run creation is async. Filter on the
# exact commit SHA (`gh run list -c/--commit`) so the poll can only ever
# see the run for THIS push, not whatever last happened to be on top of
# the branch's run list.
- name: Flag the approval-required verify run
if: steps.check.outputs.changed == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: >
bash "$GITHUB_WORKSPACE/scripts/bump_pins_pr.sh" flag-approval
"${{ steps.pr.outputs.number }}" "${{ steps.pr.outputs.branch }}" "${{ steps.pr.outputs.sha }}"
Loading
Loading