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
58 changes: 58 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,61 @@ jobs:
with:
name: sbom
path: sbom.json

release-tag-consistency:
# Public surfaces (ROADMAP.md's latest-release line, the README
# Action pin, install snippets) all name `v{pyproject version}` and
# move in lockstep — tests/test_public_surface_contract.py enforces
# that. What no test could catch: the whole repo moving in lockstep
# to a version that was never actually released. That happened with
# v0.14.0 (pyproject and the README `@v0.14.0` Action pin landed on
# main a day before the tag existed, so the copy-paste workflow
# 404'd). This job checks the claim against release reality: the
# tag must exist on origin.
#
# Runs on pushes to main only (the `push` trigger above is scoped
# to main), never on pull_request — so a version-bump PR is never
# blocked, but a merged bump without a pushed tag turns main red
# until the tag is pushed or the claim is reverted.
#
# Recovery: pushing the tag triggers release.yml, not this run, so
# a failed run does not clear itself on tag push. It re-checks
# origin's live tag list on re-run — after pushing the tag, use
# "Re-run failed jobs" on this run (or wait for the next push to
# main). A tag trigger on this workflow would not help: it would
# start a *new* run on the tag ref, leave the failed branch run
# red on the CI badge, and re-run the full test job that
# release.yml already runs on the tag.
#
# Deliberately tag-only: the tag is what triggers release.yml, the
# canonical publisher, which itself fails loudly if the PyPI upload
# or GitHub Release step breaks — so "tag exists + release.yml
# green" covers /releases/latest and PyPI. Querying PyPI here would
# add an external dependency that lags publish by minutes (the
# /json index is CDN-cached) and can false-fail right after a
# legitimate release.
if: github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

- name: Verify the claimed latest release tag exists on origin
run: |
version="$(sed -n 's/^version = "\(.*\)"$/\1/p' pyproject.toml | head -n 1)"
if [ -z "${version}" ]; then
echo "::error::Could not read version from pyproject.toml."
exit 1
fi
echo "pyproject.toml version: ${version}"
if git ls-remote --exit-code --tags origin "refs/tags/v${version}" > /dev/null; then
echo "OK: tag v${version} exists on origin."
else
echo "::error::Public surfaces claim v${version} as the latest release, but tag v${version} does not exist on origin."
echo "Cut the release: git tag -a v${version} <release-sha> && git push origin v${version}"
echo "then use 'Re-run failed jobs' on this run — pushing the tag triggers release.yml, not a retest of this run, but a re-run re-checks origin's live tag list. The check also clears on the next push to main."
echo "…or revert the version claim until the release is actually cut."
exit 1
fi
14 changes: 14 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ jobs:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

- name: Verify tag matches package version
# Fail fast before the test/build/publish pipeline if the tag
# was cut on a commit whose pyproject.toml disagrees (e.g. a
# v0.15.0 tag pushed while main still says 0.14.0). PyPI
# uploads are immutable, so this is the last cheap moment to
# catch a mistagged release.
run: |
version="$(sed -n 's/^version = "\(.*\)"$/\1/p' pyproject.toml | head -n 1)"
if [ "${GITHUB_REF_NAME}" != "v${version}" ]; then
echo "::error::Tag ${GITHUB_REF_NAME} does not match pyproject.toml version ${version}; refusing to release."
exit 1
fi
echo "OK: ${GITHUB_REF_NAME} matches pyproject.toml (${version})."

- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
Expand Down
6 changes: 5 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

> **Naming.** This project is **Agents Shipgate** (display name) / `agents-shipgate` (package, CLI, repo). See [`AGENTS.md` § Naming (canonical)](AGENTS.md#naming-canonical) for the full convention.

**Latest release: `v0.14.0`** — the **agent-native contract cleanup** cycle.
**Latest release: `v0.14.0`**
([release page](https://github.com/ThreeMoonsLab/agents-shipgate/releases/latest))
— the **agent-native contract cleanup** cycle. This line is checked against the
actual release tag by the `release-tag-consistency` job in
[`ci.yml`](.github/workflows/ci.yml) on every push to `main`.

## What Agents Shipgate is

Expand Down