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
100 changes: 100 additions & 0 deletions .github/scripts/pin-ffi-to-tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env bash
#
# Pin the aa-ffi-python git deps to the agent-assembly commit a release tag
# points at, so the maturin-built wheel always compiles against the SAME core
# release whose aasm-* binaries it bundles (binary_source_tag).
#
# Background (AAASM-2959): release-python.yml builds the PyPI wheel with maturin,
# which compiles aa-ffi-python (PyO3) from source against the git-SHA `rev`
# pins in native/aa-ffi-python/Cargo.toml (aa-core, aa-proto, aa-sdk-client).
# Those pins are only bumped to the just-released core commit by a SEPARATE PR
# that lands AFTER publish, so without this rewrite the published wheel would
# pin the PREVIOUS core release (one-cycle source-pin lag). This script makes
# the wheel self-consistent by rewriting the pins to binary_source_tag's commit
# in the CI working tree before each maturin build. It is an ephemeral edit β€”
# CI must NOT commit it back (the update-python-sdk-ffi-pin PR keeps master
# synced separately).
#
# Usage:
# .github/scripts/pin-ffi-to-tag.sh <tag> [cargo_toml_path]
#
# <tag> agent-assembly release tag, e.g. v0.0.1-alpha.8
# [cargo_toml_path] defaults to native/aa-ffi-python/Cargo.toml
#
# Resolves the tag to a full 40-hex commit SHA on
# ai-agent-assembly/agent-assembly, dereferencing annotated tags (the peeled
# `^{}` ref), and falling back to the lightweight tag ref if peeling yields
# nothing. Then rewrites every `rev = "<sha>"` on the aa-core / aa-proto /
# aa-sdk-client git dep lines to that SHA. Idempotent: re-running with the same
# tag is a no-op.

set -euo pipefail

TAG="${1:?usage: pin-ffi-to-tag.sh <tag> [cargo_toml_path]}"
CARGO_TOML="${2:-native/aa-ffi-python/Cargo.toml}"
REPO_URL="https://github.com/ai-agent-assembly/agent-assembly.git"

if [[ ! -f "$CARGO_TOML" ]]; then
echo "::error::Cargo.toml not found at '$CARGO_TOML'" >&2
exit 1
fi

# Resolve tag -> full commit SHA. Prefer the peeled (`^{}`) ref so annotated
# tags resolve to the commit they point at, not the tag object's own SHA.
# Fall back to the lightweight ref when the peeled form is empty.
sha="$(git ls-remote "$REPO_URL" "refs/tags/${TAG}^{}" | awk '{print $1}' | head -n1)"
if [[ -z "$sha" ]]; then
sha="$(git ls-remote "$REPO_URL" "refs/tags/${TAG}" | awk '{print $1}' | head -n1)"
fi

if [[ ! "$sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "::error::could not resolve tag '${TAG}' to a 40-hex commit SHA on ${REPO_URL} (got '${sha}')" >&2
exit 1
fi

echo "::notice::Pinning aa-ffi git deps to ${TAG} -> ${sha}"

# Rewrite the `rev = "..."` on each aa-core / aa-proto / aa-sdk-client git dep
# line, keyed on the dep name at line start so unrelated `rev`s are untouched.
# Done in Python (not sed) for portable, identical behaviour across the GNU-sed
# (ubuntu) and BSD-sed (macOS) build runners. Verifies exactly 3 deps were
# repinned so a silent no-op (e.g. a Cargo.toml refactor that broke the match)
# cannot let a stale-pinned wheel slip through.
SHA="$sha" CARGO_TOML="$CARGO_TOML" python3 - <<'PY'
import os
import re
import sys

sha = os.environ["SHA"]
path = os.environ["CARGO_TOML"]
deps = ("aa-core", "aa-proto", "aa-sdk-client")
# Match `<dep> = { ... rev = "<40-hex>" ... }` at line start.
line_re = re.compile(r'^(aa-(?:core|proto|sdk-client))\s*=.*$')
rev_re = re.compile(r'(rev\s*=\s*")[0-9a-fA-F]{40}(")')

with open(path, encoding="utf-8") as fh:
lines = fh.readlines()

repinned = set()
for i, line in enumerate(lines):
m = line_re.match(line)
if not m:
continue
new_line, n = rev_re.subn(rf'\g<1>{sha}\g<2>', line)
if n:
lines[i] = new_line
repinned.add(m.group(1))

if repinned != set(deps):
missing = set(deps) - repinned
sys.stderr.write(
f"::error::expected to repin {sorted(deps)}, missing {sorted(missing)} in {path}\n"
)
sys.exit(1)

with open(path, "w", encoding="utf-8") as fh:
fh.writelines(lines)
PY

echo "aa-ffi git deps pinned to ${sha}:"
grep -nE '^aa-(core|proto|sdk-client)[[:space:]]*=' "$CARGO_TOML"
45 changes: 45 additions & 0 deletions .github/workflows/release-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Pin aa-ffi git deps to released core (binary_source_tag)
# Rewrite native/aa-ffi-python/Cargo.toml so the wheel compiles against
# the SAME core release whose aasm-* binaries it bundles. master's pins
# lag by one cycle (bumped only by the post-publish update PR), so
# without this the wheel would pin the PREVIOUS core. Ephemeral CI edit
# β€” not committed back. See AAASM-2959.
env:
BINARY_SOURCE_TAG: ${{ needs.resolve.outputs.binary_source_tag }}
run: .github/scripts/pin-ffi-to-tag.sh "$BINARY_SOURCE_TAG"
- name: Sync version
uses: ./.github/actions/sync-version
with:
Expand Down Expand Up @@ -208,6 +217,15 @@ jobs:
rm -f agent_assembly/bin/aasm-x86_64-unknown-linux-gnu.tar.gz
chmod +x agent_assembly/bin/aasm
echo "Bundled aasm binary into wheel"
- name: Pin aa-ffi git deps to released core (binary_source_tag)
# Rewrite native/aa-ffi-python/Cargo.toml so the wheel compiles against
# the SAME core release whose aasm-* binaries it bundles. master's pins
# lag by one cycle (bumped only by the post-publish update PR), so
# without this the wheel would pin the PREVIOUS core. Ephemeral CI edit
# β€” not committed back. See AAASM-2959.
env:
BINARY_SOURCE_TAG: ${{ needs.resolve.outputs.binary_source_tag }}
run: .github/scripts/pin-ffi-to-tag.sh "$BINARY_SOURCE_TAG"
- name: Sync version
uses: ./.github/actions/sync-version
with:
Expand Down Expand Up @@ -279,6 +297,15 @@ jobs:
rm -f agent_assembly/bin/aasm-aarch64-unknown-linux-gnu.tar.gz
chmod +x agent_assembly/bin/aasm
echo "Bundled aasm binary into wheel"
- name: Pin aa-ffi git deps to released core (binary_source_tag)
# Rewrite native/aa-ffi-python/Cargo.toml so the wheel compiles against
# the SAME core release whose aasm-* binaries it bundles. master's pins
# lag by one cycle (bumped only by the post-publish update PR), so
# without this the wheel would pin the PREVIOUS core. Ephemeral CI edit
# β€” not committed back. See AAASM-2959.
env:
BINARY_SOURCE_TAG: ${{ needs.resolve.outputs.binary_source_tag }}
run: .github/scripts/pin-ffi-to-tag.sh "$BINARY_SOURCE_TAG"
- name: Sync version
uses: ./.github/actions/sync-version
with:
Expand Down Expand Up @@ -344,6 +371,15 @@ jobs:
echo "Bundled aasm binary into wheel"
- name: Install protoc (macOS)
run: brew install protobuf
- name: Pin aa-ffi git deps to released core (binary_source_tag)
# Rewrite native/aa-ffi-python/Cargo.toml so the wheel compiles against
# the SAME core release whose aasm-* binaries it bundles. master's pins
# lag by one cycle (bumped only by the post-publish update PR), so
# without this the wheel would pin the PREVIOUS core. Ephemeral CI edit
# β€” not committed back. See AAASM-2959.
env:
BINARY_SOURCE_TAG: ${{ needs.resolve.outputs.binary_source_tag }}
run: .github/scripts/pin-ffi-to-tag.sh "$BINARY_SOURCE_TAG"
- name: Sync version
uses: ./.github/actions/sync-version
with:
Expand Down Expand Up @@ -390,6 +426,15 @@ jobs:
echo "Bundled aasm binary into wheel"
- name: Install protoc (macOS)
run: brew install protobuf
- name: Pin aa-ffi git deps to released core (binary_source_tag)
# Rewrite native/aa-ffi-python/Cargo.toml so the wheel compiles against
# the SAME core release whose aasm-* binaries it bundles. master's pins
# lag by one cycle (bumped only by the post-publish update PR), so
# without this the wheel would pin the PREVIOUS core. Ephemeral CI edit
# β€” not committed back. See AAASM-2959.
env:
BINARY_SOURCE_TAG: ${{ needs.resolve.outputs.binary_source_tag }}
run: .github/scripts/pin-ffi-to-tag.sh "$BINARY_SOURCE_TAG"
- name: Sync version
uses: ./.github/actions/sync-version
with:
Expand Down