Skip to content
Open
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
35 changes: 19 additions & 16 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,13 @@ jobs:
# id-token: write — GCP WIF auth in functional-tests
# pull-requests: write — gate job (pull_request_target only; skipped
# on tag pushes, but still validated)
# checks: read — functional-tests-complete roll-up on agents
# main (not used by the pinned gate yet;
# granted now so a pin bump cannot
# reintroduce the startup failure)
# checks: read — functional-tests-complete roll-up job
permissions:
contents: read
id-token: write
pull-requests: write
checks: read
uses: fullsend-ai/agents/.github/workflows/functional-tests.yml@a8566cd5305fe094b96588690118022967ad0061 # main
uses: fullsend-ai/agents/.github/workflows/functional-tests.yml@beed20e7e85f7f7cf9678a78fd1f440755560ca3 # main (includes agents#1010 cross-repo checkout fix)
with:
fullsend_ref: ${{ github.ref_name }}
secrets:
Expand All @@ -85,13 +82,11 @@ jobs:
EVAL_GH_TOKEN: ${{ secrets.EVAL_GH_TOKEN }}

resolve-agents:
# Resolve the agents tree to tag exactly once, when the release starts.
# tag-agents previously re-resolved agents main at tag time, so anything
# merged into agents while the gate ran was tagged unvalidated (#6512).
# Until the agents gate exposes the SHA it checked out as a
# workflow_call output, validate-agents still exercises the pinned
# gate's agents tree; this at least makes the tagged tree deterministic
# from the moment the release begins.
# Resolve agents main once at release start. Since agents#1010 the gate
# itself reports the SHA it validated (validate-agents' agents_sha
# output), and tag-agents prefers that; this job's resolution is the
# fallback if that output is ever empty, and the input for the
# informational pin-drift check below (#6512).
needs: release
runs-on: ubuntu-24.04
timeout-minutes: 5
Expand Down Expand Up @@ -129,8 +124,10 @@ jobs:
# Sync the version tag to fullsend-ai/agents. Runs for all tags
# including pre-releases — agents' own release.yml handles
# pre-release semantics. Only runs after agents functional tests
# pass against the release tag. Tags the SHA resolve-agents captured
# at release start — never re-resolves main here (#6512).
# pass against the release tag. Tags the SHA the gate actually
# validated (validate-agents' agents_sha output, agents#1010), falling
# back to the SHA resolve-agents captured at release start — never
# re-resolves main here (#6512).
needs: [release, validate-agents, resolve-agents]
runs-on: ubuntu-24.04
timeout-minutes: 5
Expand All @@ -148,13 +145,19 @@ jobs:
- name: Push tag to fullsend-ai/agents
env:
GH_TOKEN: ${{ steps.agents-token.outputs.token }}
AGENTS_SHA: ${{ needs.resolve-agents.outputs.agents_sha }}
GATE_SHA: ${{ needs.validate-agents.outputs.agents_sha }}
RESOLVED_SHA: ${{ needs.resolve-agents.outputs.agents_sha }}
run: |
set -euo pipefail
AGENTS_SHA="${GATE_SHA:-${RESOLVED_SHA}}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] edge-case

The preference for the gate-validated SHA (GATE_SHA) depends on the called reusable workflow (functional-tests.yml at b9c07455...) declaring agents_sha as a workflow_call output. This cannot be verified from this repository. If agents#1010 did not add that output declaration, GATE_SHA will silently be empty and the fallback to RESOLVED_SHA will always activate, making the gate-preference logic functionally inert. The fallback is safe but the PR's core improvement would not take effect.

Suggested fix: Confirm the agents workflow at b9c0745580084af09d1f1e2df8448d1d478458c6 declares agents_sha under on.workflow_call.outputs. Consider adding a warning log when GATE_SHA is empty to make the fallback observable.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] edge-case

The preference for the gate-validated SHA (GATE_SHA) depends on the called reusable workflow (functional-tests.yml at beed20e7...) declaring agents_sha as a workflow_call output. This cannot be verified from this repository alone. If the output declaration is missing, GATE_SHA will silently be empty and the fallback to RESOLVED_SHA will always activate — making the gate-preference logic functionally inert. The fallback is safe (tagging still works), but the PR's core improvement would not take effect.

Suggested fix: Confirm the agents workflow at beed20e7e85f7f7cf9678a78fd1f440755560ca3 declares agents_sha under on.workflow_call.outputs. Consider adding a ::warning annotation when GATE_SHA is empty to make the fallback more visible in CI logs.

if [[ ! "${AGENTS_SHA}" =~ ^[a-f0-9]{40}$ ]]; then
echo "::error::resolve-agents output is not a commit SHA: ${AGENTS_SHA//::/}"
echo "::error::no usable agents SHA (gate='${GATE_SHA//::/}' resolved='${RESOLVED_SHA//::/}')"
exit 1
fi
if [[ -n "${GATE_SHA}" && "${GATE_SHA}" != "${RESOLVED_SHA}" ]]; then
echo "::notice::tagging the gate-validated SHA ${GATE_SHA} (agents main was ${RESOLVED_SHA} at release start)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] GHA workflow command injection

The ::notice:: line interpolates GATE_SHA and RESOLVED_SHA without the //::/} sanitization pattern used on the ::error:: line above it. Not exploitable in practice (both values are validated as 40-character hex strings before this line is reached), but applying consistent sanitization would be a defense-in-depth improvement.

Suggested fix: Change to: echo "::notice::tagging the gate-validated SHA ${GATE_SHA//::/} (agents main was ${RESOLVED_SHA//::/} at release start)"

fi
echo "Tagging fullsend-ai/agents at ${AGENTS_SHA} (source: $([[ -n "${GATE_SHA}" ]] && echo validate-agents || echo resolve-agents))"
TAG="${GITHUB_REF_NAME}"

HTTP_CODE=$(gh api "repos/fullsend-ai/agents/git/ref/tags/${TAG}" \
Expand Down
Loading