Skip to content

feat: build fullsend from source in functional tests - #776

Merged
maruiz93 merged 5 commits into
fullsend-ai:mainfrom
maruiz93:agents-dev-ci
Aug 14, 2026
Merged

feat: build fullsend from source in functional tests#776
maruiz93 merged 5 commits into
fullsend-ai:mainfrom
maruiz93:agents-dev-ci

Conversation

@maruiz93

@maruiz93 maruiz93 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add workflow_call trigger with fullsend_ref input so external workflows (e.g. fullsend release pipeline) can invoke functional tests against a specific fullsend ref
  • Replace release binary download with clone-and-build from source (make go-build), matching what fullsend's own CI already does
  • Replace GitHub API fetches of openshell scripts with direct reads from the cloned fullsend checkout

Context

Closes #775

This is the agents-side half of decoupling development velocity between fullsend and agents. The fullsend-side counterpart (fullsend-ai/fullsend#6173 — gating the agents tag on these tests at release time) depends on this change.

Related: fullsend-ai/fullsend#4931 (stale v0 tag in functional tests).

Test plan

  • push / merge_group triggered runs build fullsend from main and run successfully
  • PR-triggered runs (pull_request_target) work unchanged
  • workflow_call with default fullsend_ref (main) builds and runs successfully
  • workflow_call with fullsend_ref set to a release tag (e.g. v0.98.0) builds correctly
  • Invalid fullsend_ref values (arbitrary branches, SHAs) are rejected by validation
  • OpenShell scripts are sourced from the cloned checkout (no gh api calls to fullsend contents)

🤖 Generated with Claude Code

@maruiz93
maruiz93 requested a review from a team as a code owner August 13, 2026 10:23
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 10:24 AM UTC · Ended 10:27 AM UTC

Commit: 652a3b7 · View workflow run →

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Build fullsend from source in functional tests

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Allow workflow_call/workflow_dispatch to specify fullsend_ref (branch, tag, or SHA).
• Clone and build fullsend from source via make go-build during functional tests.
• Read OpenShell scripts from the cloned fullsend checkout (no GitHub API content fetches).
Diagram

graph TD
  trig(["GitHub triggers"]) --> wf["Functional tests workflow"] --> clone["Clone fullsend ref"] --> build["Build fullsend (make)"] --> openshell["Source OpenShell scripts"] --> tests["Run eval functional tests"]
  fsrepo{{"fullsend repo"}} --> clone
  subgraph Legend
    direction LR
    _tr(["Trigger"]) ~~~ _wf["Workflow/step"] ~~~ _ext{{"External repo"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep downloading release binaries
  • ➕ Faster setup (no compilation)
  • ➕ Less toolchain variability (no Go build dependencies)
  • ➖ Harder to test arbitrary SHAs
  • ➖ Susceptible to stale/mismatched tags and release asset availability
  • ➖ Still requires separate logic to fetch OpenShell scripts by ref
2. Download build artifacts from fullsend CI for a given ref
  • ➕ Avoids local compilation time while staying source-aligned
  • ➕ Can support SHAs if artifacts are produced per-commit
  • ➖ Cross-repo artifact access/permissions and retention complexity
  • ➖ More moving parts (artifact naming, lookup, and fallback behavior)
3. Add caching for the source build (Go build cache + fullsend checkout)
  • ➕ Keeps correctness of building from source but reduces runtime
  • ➕ Straightforward improvement without changing semantics
  • ➖ Cache invalidation and keying (ref/Go version) adds complexity
  • ➖ Caching can hide intermittent build issues if misconfigured

Recommendation: The PR’s approach (clone + build from source using a caller-supplied ref, and source scripts locally) is the most robust way to support branch/tag/SHA testing and eliminate dependence on release assets and GitHub content API calls. Consider adding Go/build caching later if CI duration becomes a concern, but keep the current semantics as the baseline for correctness and reproducibility.

Files changed (1) +35 / -31

Other (1) +35 / -31
functional-tests.ymlAdd fullsend_ref inputs and build fullsend from source in CI +35/-31

Add fullsend_ref inputs and build fullsend from source in CI

• Adds workflow_dispatch and workflow_call inputs to pass a fullsend_ref for functional test runs. Replaces release-asset installation with cloning fullsend at the requested ref and building it via make go-build, with a fallback path for SHA refs. Switches OpenShell script resolution/install from GitHub API content fetches to local reads from the cloned fullsend checkout.

.github/workflows/functional-tests.yml

@maruiz93 maruiz93 changed the title Build fullsend from source in functional tests feat: build fullsend from source in functional tests Aug 13, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 10:28 AM UTC · Ended 10:41 AM UTC

Commit: 2f7335a · View workflow run →

@qodo-code-review

qodo-code-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (1)

Grey Divider


Action required

1. Protected workflow file modified 📜 Skill insight § Compliance
Description
This PR modifies a protected governance/infrastructure path
(.github/workflows/functional-tests.yml), which must not be auto-approved and requires explicit
human review/approval.
Code

.github/workflows/functional-tests.yml[R37-40]

+  workflow_call:
+    inputs:
+      fullsend_ref:
+        description: 'fullsend ref (branch, tag, or SHA) to build from'
Relevance

●● Moderate

Protected-path note is process/policy; sometimes add justification comments, but not always treated
as actionable code change.

PR-#184
PR-#29

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance checklist marks changes under protected paths (including .github/) as requiring a
finding; this PR adds a new workflow_call trigger and inputs inside
.github/workflows/functional-tests.yml, which is a protected path.

.github/workflows/functional-tests.yml[37-40]
Skill: pr-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
This PR changes a protected governance/infrastructure file under `.github/workflows/`. Per compliance requirements, any such change must trigger a “human approval required” posture (not auto-approval).

## Issue Context
Even when the change is justified (e.g., linked to an issue), protected-path modifications must still be surfaced as requiring manual review.

## Fix Focus Areas
- .github/workflows/functional-tests.yml[37-40]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Unpinned Go toolchain ✓ Resolved 🐞 Bug ☼ Reliability
Description
The workflow installs Go with go-version: stable, so identical functional-test runs may compile
fullsend with different Go versions over time, reducing build/test reproducibility now that fullsend
is built from source.
Code

.github/workflows/functional-tests.yml[R227-230]

+      - name: Setup Go
+        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
+        with:
+          go-version: stable
Relevance

●●● Strong

Repo has precedent for pinning workflow tool/dependency versions for reproducibility; unpinned Go
toolchain likely to be fixed.

PR-#37

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The workflow explicitly installs Go using the moving stable channel and then builds fullsend from
source, which makes the toolchain version part of the test’s behavior and prone to drift.

.github/workflows/functional-tests.yml[227-249]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The functional tests now compile fullsend from source, but the Go toolchain is selected via the moving `stable` channel. As Go releases advance, this can change build outputs and introduce intermittent CI drift.

## Issue Context
Because the workflow builds a caller-selected `fullsend_ref` (branch/tag/SHA), the most deterministic approach is to select Go based on that checkout (or pin a known supported Go version).

## Fix Focus Areas
- .github/workflows/functional-tests.yml[227-249]

## Suggested fix
Choose one deterministic strategy:
1) **Derive Go version from the checked-out fullsend ref**:
  - Set `FULLSEND_CHECKOUT` as a job-level env (e.g. `${{ runner.temp }}/fullsend`) so it’s usable in action inputs.
  - Clone fullsend first.
  - Configure `actions/setup-go` with `go-version-file` pointing at `${FULLSEND_CHECKOUT}/go.mod` (or whatever file fullsend uses to declare its toolchain).
2) **Pin a specific Go version**:
  - Replace `stable` with an explicit version (e.g. `1.24.x`) and bump intentionally.

Either approach avoids toolchain drift impacting functional-test stability.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. workflow_call misroutes diff fetch ✓ Resolved 🐞 Bug ≡ Correctness
Description
With the new workflow_call trigger, the detect job’s “Get changed files” step falls through to the
pull-request files API path even though workflow_call has no PR payload, causing a misleading
warning and forcing the conservative “run all tests” behavior on every reusable-workflow invocation.
Code

.github/workflows/functional-tests.yml[R37-40]

+  workflow_call:
+    inputs:
+      fullsend_ref:
+        description: 'fullsend ref (branch, tag, or SHA) to build from'
Relevance

●● Moderate

Likely real bug for workflow_call payloads, but team may accept “run all tests” behavior for
reusable invocations.

PR-#29

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The workflow is now invokable via workflow_call, but the detect job’s “Get changed files” step
only skips for workflow_dispatch and otherwise falls back to PR file fetching using
github.event.pull_request.number, which won’t exist for workflow_call events—causing the
warning+exit-0 precautionary path every time.

.github/workflows/functional-tests.yml[9-43]
.github/workflows/functional-tests.yml[89-177]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The workflow now supports `workflow_call`, but the detect job’s changed-files logic treats any non-`push`/`merge_group` event as a PR and attempts to fetch PR file lists using an empty PR number. This always triggers the warning path for reusable-workflow runs.

## Issue Context
For `workflow_call`, there is no `github.event.pull_request.*` data. The current shell logic only special-cases `merge_group` and `push`, so `workflow_call` falls into the PR branch and warns.

## Fix Focus Areas
- .github/workflows/functional-tests.yml[89-177]
- .github/workflows/functional-tests.yml[9-43]

## Suggested fix
Update the changed-files step to explicitly handle `workflow_call` (and likely treat it the same as `workflow_dispatch`):
- Option A (simplest): skip the “Get changed files” step when `github.event_name` is `workflow_call` (and let the next step run all agents).
- Option B: add an explicit `elif [ "$EVENT_NAME" = "workflow_call" ]; then exit 0` branch with a non-misleading message (or no warning).
- Option C: add an explicit input (e.g., `pr_number`) for workflow_call and only hit the PR files API when it’s provided.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
✅ Compliance rules (platform): 55 rules
✅ Skills: 4 invoked
  code-review
  code-implementation
  pr-review
  docs-review

Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread .github/workflows/functional-tests.yml Outdated
Comment thread .github/workflows/functional-tests.yml Outdated
Comment thread .github/workflows/functional-tests.yml Outdated
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 10:42 AM UTC · Completed 10:57 AM UTC

Commit: 06402c9 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review

Findings

Medium

Low

  • [workflow-command-injection] .github/workflows/functional-tests.yml:256 — The "Validate fullsend ref" step interpolates FULLSEND_REF into an ::error:: workflow command without sanitizing for encoded newlines or :: sequences. Practical risk is very low: workflow_call inputs can only be set by calling workflows (not PR authors), and the regex guard rejects most payloads before the error path is reached.

  • [credential-exposure] .github/workflows/functional-tests.yml:267 — The "Clone fullsend" step embeds GH_TOKEN in the git clone URL. If the clone fails, git may include the URL in stderr. GitHub Actions' built-in log masking redacts ${{ github.token }} values, and the token is short-lived and job-scoped.

  • [input-validation] .github/workflows/functional-tests.yml:255 — The fullsend_ref validation regex ^v[0-9] is only start-anchored, accepting any string starting with v followed by a digit. Git's --branch flag constrains the value to existing refs, and workflow_call is only invocable by trusted callers within the org.

  • [architectural-coherence] .github/workflows/functional-tests.yml:52 — The concurrency group uses github.repository != 'fullsend-ai/agents' to detect cross-repo calls. This introduces implicit coupling to the canonical repo name. However, this pattern is used consistently throughout the workflow, so it is not a new coupling unique to the concurrency group.

  • [scope-alignment] .github/workflows/functional-tests.yml:371 — The functional-tests-complete job now fails if a cross-repo call completes with zero functional tests. This is a guard rail for the workflow_call feature being added — it ensures cross-repo callers do not silently succeed with zero tests.

  • [documentation-completeness] README.md:85 — The Workflows section in README.md documents fullsend.yaml, release.yml, and script-test.yml, but omits functional-tests.yml. The PR adds a workflow_call trigger making it callable from other repos, but this cross-repo capability is undocumented.

Previous run

Review

Findings

Medium

Low

  • [logic-error] .github/workflows/functional-tests.yml:410 — The AGENTS environment variable is set in the functional-tests-complete job but is never referenced in the shell script. It appears intended for diagnostic use in the cross-repo skipped-tests error message.

  • [edge-case] .github/workflows/functional-tests.yml:284 — The "Configure OpenShell gateway" step changed from eval with a grep -E '^OPENSHELL_(VERSION|SHA)=' filter to source on the entire openshell-version.sh script. If that script contains side effects beyond variable assignments, the step's behavior could differ from the original. However, the workflow already fully trusts the fullsend checkout (executing make go-build, install-openshell.sh), so the trust boundary is consistent.

  • [workflow-command-injection] .github/workflows/functional-tests.yml:255 — The "Validate fullsend ref" step interpolates FULLSEND_REF into an ::error:: workflow command without sanitizing for encoded newlines or :: sequences. Practical risk is very low: workflow_call inputs can only be set by calling workflows (not PR authors), and the regex guard rejects most payloads before the error path is reached.

  • [credential-exposure] .github/workflows/functional-tests.yml:266 — The "Clone fullsend" step embeds GH_TOKEN in the git clone URL. If the clone fails, git may include the URL in stderr. GitHub Actions' built-in log masking redacts ${{ github.token }} values, and the token is short-lived and job-scoped.

  • [input-validation] .github/workflows/functional-tests.yml:254 — The fullsend_ref validation regex ^v[0-9] is only start-anchored, accepting any string starting with v followed by a digit. Git's --branch flag constrains the value to existing refs, and workflow_call is only invocable by trusted callers within the org.

  • [architectural-coherence] .github/workflows/functional-tests.yml:52 — The concurrency group uses github.repository != 'fullsend-ai/agents' to detect cross-repo calls. This introduces implicit coupling to the canonical repo name. However, this pattern is used consistently throughout the workflow, so it is not a new coupling unique to the concurrency group.

  • [documentation-completeness] .github/workflows/functional-tests.ymlworkflow_call invocations always run all functional tests (skipping changed-files detection). While likely intentional for cross-repo callers wanting comprehensive validation, this behavior is undocumented.

Previous run

Review

Findings

Medium

Low

  • [edge-case] .github/workflows/functional-tests.yml:270 — The "Configure OpenShell gateway" step changed from eval with a grep -E '^OPENSHELL_(VERSION|SHA)=' filter to source on the entire openshell-version.sh script. If that script contains side effects beyond variable assignments, the step's behavior could differ from the original. However, the workflow already fully trusts the fullsend checkout (executing make go-build, install-openshell.sh), so the trust boundary is consistent.

  • [workflow-command-injection] .github/workflows/functional-tests.yml:240 — The "Validate fullsend ref" step interpolates FULLSEND_REF into a ::error:: workflow command without sanitizing for %0A/%0D URL-encoded newlines or :: sequences. Practical risk is very low: workflow_call inputs can only be set by calling workflows (not PR authors), and the regex filters most payloads before the error path is reached.

  • [credential-exposure] .github/workflows/functional-tests.yml:252 — The "Clone fullsend" step embeds GH_TOKEN in the git clone URL. If the clone fails, git may include the URL in stderr. GitHub Actions' built-in log masking redacts ${{ github.token }} values, and the token is short-lived and job-scoped.

  • [input-validation] .github/workflows/functional-tests.yml:239 — The fullsend_ref validation regex ^v[0-9] is only start-anchored, accepting any string starting with v followed by a digit. Git's own ref resolution constrains the value to existing refs, and workflow_call is only invocable by trusted callers.

Previous run

Review

Findings

Medium

Low

  • [logic-error] .github/workflows/functional-tests.yml:410 — The AGENTS environment variable is set in the functional-tests-complete job but is never referenced in the shell script. It appears intended for diagnostic use in the cross-repo skipped-tests error message.

  • [edge-case] .github/workflows/functional-tests.yml:284 — The "Configure OpenShell gateway" step changed from eval with a grep -E '^OPENSHELL_(VERSION|SHA)=' filter to source on the entire openshell-version.sh script. If that script contains side effects beyond variable assignments, the step's behavior could differ from the original. However, the workflow already fully trusts the fullsend checkout (executing make go-build, install-openshell.sh), so the trust boundary is consistent.

  • [workflow-command-injection] .github/workflows/functional-tests.yml:255 — The "Validate fullsend ref" step interpolates FULLSEND_REF into an ::error:: workflow command without sanitizing for encoded newlines or :: sequences. Practical risk is very low: workflow_call inputs can only be set by calling workflows (not PR authors), and the regex guard rejects most payloads before the error path is reached.

  • [credential-exposure] .github/workflows/functional-tests.yml:266 — The "Clone fullsend" step embeds GH_TOKEN in the git clone URL. If the clone fails, git may include the URL in stderr. GitHub Actions' built-in log masking redacts ${{ github.token }} values, and the token is short-lived and job-scoped.

  • [input-validation] .github/workflows/functional-tests.yml:254 — The fullsend_ref validation regex ^v[0-9] is only start-anchored, accepting any string starting with v followed by a digit. Git's --branch flag constrains the value to existing refs, and workflow_call is only invocable by trusted callers within the org.

  • [architectural-coherence] .github/workflows/functional-tests.yml:52 — The concurrency group uses github.repository != 'fullsend-ai/agents' to detect cross-repo calls. This introduces implicit coupling to the canonical repo name. However, this pattern is used consistently throughout the workflow, so it is not a new coupling unique to the concurrency group.

  • [documentation-completeness] .github/workflows/functional-tests.ymlworkflow_call invocations always run all functional tests (skipping changed-files detection). While likely intentional for cross-repo callers wanting comprehensive validation, this behavior is undocumented.

Previous run (2)

Review

Findings

Medium

Low

  • [edge-case] .github/workflows/functional-tests.yml:270 — The "Configure OpenShell gateway" step changed from eval with a grep -E '^OPENSHELL_(VERSION|SHA)=' filter to source on the entire openshell-version.sh script. If that script contains side effects beyond variable assignments, the step's behavior could differ from the original. However, the workflow already fully trusts the fullsend checkout (executing make go-build, install-openshell.sh), so the trust boundary is consistent.

  • [workflow-command-injection] .github/workflows/functional-tests.yml:240 — The "Validate fullsend ref" step interpolates FULLSEND_REF into a ::error:: workflow command without sanitizing for %0A/%0D URL-encoded newlines or :: sequences. Practical risk is very low: workflow_call inputs can only be set by calling workflows (not PR authors), and the regex filters most payloads before the error path is reached.

  • [credential-exposure] .github/workflows/functional-tests.yml:252 — The "Clone fullsend" step embeds GH_TOKEN in the git clone URL. If the clone fails, git may include the URL in stderr. GitHub Actions' built-in log masking redacts ${{ github.token }} values, and the token is short-lived and job-scoped.

  • [input-validation] .github/workflows/functional-tests.yml:239 — The fullsend_ref validation regex ^v[0-9] is only start-anchored, accepting any string starting with v followed by a digit. Git's own ref resolution constrains the value to existing refs, and workflow_call is only invocable by trusted callers.

  • [architectural-coherence] .github/workflows/functional-tests.yml:52 — The concurrency group uses github.repository != 'fullsend-ai/agents' to detect cross-repo calls. This introduces implicit coupling to the canonical repo name. Checking github.event_name == 'workflow_call' would be more explicit and self-documenting, though both approaches are functionally equivalent for this use case.

  • [architectural-coherence] .github/workflows/functional-tests.ymlworkflow_call invocations always run all functional tests (skipping changed-files detection). While likely intentional for cross-repo callers wanting comprehensive validation, this behavior is undocumented.

Previous run (3)

Review

Findings

Medium

Low

  • [edge-case] .github/workflows/functional-tests.yml:270 — The "Configure OpenShell gateway" step changed from eval with a grep -E '^OPENSHELL_(VERSION|SHA)=' filter to source on the entire openshell-version.sh script. If that script contains side effects beyond variable assignments, the step's behavior could differ from the original. However, the workflow already fully trusts the fullsend checkout (executing make go-build, install-openshell.sh), so the trust boundary is consistent.

  • [workflow-command-injection] .github/workflows/functional-tests.yml:241 — The "Validate fullsend ref" step interpolates FULLSEND_REF into a ::error:: workflow command without sanitizing for %0A/%0D URL-encoded newlines or :: sequences. The practical risk is low because workflow_call inputs can only be set by calling workflows (not PR authors), and ACTIONS_ALLOW_UNSECURE_COMMANDS is off by default.

  • [credential-exposure] .github/workflows/functional-tests.yml:252 — The "Clone fullsend" step embeds GH_TOKEN in the git clone URL, which git may include in stderr error messages on failure. However, github.token is set via ${{ github.token }}, which GitHub Actions' log masking automatically redacts in CI output. The token is also short-lived and scoped to the job. The practical exposure risk is minimal given built-in masking.

  • [input-validation] .github/workflows/functional-tests.yml:240 — The fullsend_ref validation regex ^v[0-9] only anchors the start and accepts any branch name starting with v followed by a digit. Since the value is passed to git clone --branch, git itself provides the real safety boundary (only existing refs can be checked out).

Previous run (4)

Review

Findings

Medium

  • [protected-path] .github/workflows/functional-tests.yml — This PR modifies a file under the .github/ protected path. The PR links to issue Build fullsend from source in functional tests instead of downloading release binary #775 and provides clear rationale for the change (building fullsend from source to decouple development velocity). Human approval is always required for protected-path changes, regardless of context.

  • [undocumented-api] CONTRIBUTING.md:58 — The "Functional tests for external contributors" section does not document the new workflow_call trigger or the fullsend_ref input. The YAML input has a self-documenting description field, but callers outside the repo may look to CONTRIBUTING.md for usage guidance.

Low

  • [error-handling] .github/workflows/functional-tests.yml:236 — The "Clone fullsend" step embeds GH_TOKEN in the git clone URL, which git may include in stderr error messages on failure. However, github.token is set via ${{ github.token }}, which GitHub Actions' log masking automatically redacts in CI output. The token is also short-lived and scoped to the job. The practical exposure risk is minimal given built-in masking.

  • [defense-in-depth-reduction] .github/workflows/functional-tests.yml:248 — The old code filtered openshell-version.sh through grep -E '^OPENSHELL_(VERSION|SHA)=' before eval, restricting execution to only variable assignments matching the pattern. The new code uses source on the entire script without filtering, meaning any side effects in openshell-version.sh would execute in the current shell. However, the workflow already executes other scripts from the same checkout without filtering (install-openshell.sh, make go-build), so the trust boundary is consistent.

  • [missing-documentation] README.md:87 — The Workflows table does not document functional-tests.yml, which is now a reusable workflow (via workflow_call) that other repos may invoke.

Previous run (5)

Review

Findings

Medium

Low

  • [error-handling] .github/workflows/functional-tests.yml:236 — The "Clone fullsend" step embeds GH_TOKEN in the git clone URL, which git may include in stderr error messages on failure. However, github.token is set via ${{ github.token }}, which GitHub Actions' log masking automatically redacts in CI output. The token is also short-lived and scoped to the job. The practical exposure risk is minimal given built-in masking.
  • [defense-in-depth-reduction] .github/workflows/functional-tests.yml:248 — The old code filtered openshell-version.sh through grep -E '^OPENSHELL_(VERSION|SHA)=' before eval, restricting execution to only variable assignments matching the pattern. The new code uses source on the entire script without filtering, meaning any side effects in openshell-version.sh (e.g., set -e, exit, cd, modifying PATH) would affect subsequent commands. However, the workflow already executes other scripts from the same checkout without filtering (install-openshell.sh, make go-build), so the trust boundary is consistent.
Previous run (6)

Review

Findings

Medium

Low

  • [conditional-formatting] .github/workflows/functional-tests.yml:103 — Conditional expression uses single-line format with && while other complex conditionals in the file (gate if, detect if, functional-tests if) use multi-line YAML >- format.
  • [contract-completeness] .github/workflows/functional-tests.yml:37 — The new workflow_call contract lacks output definitions. Callers determine success/failure via workflow conclusion status, which is standard, but custom outputs could provide richer programmatic visibility to the fullsend release pipeline.
  • [error-handling] .github/workflows/functional-tests.yml — The "Clone fullsend" step redirects stderr to /dev/null on the first clone attempt (2>/dev/null). If the failure is due to auth or network issues, those errors are lost and the fallback clone will also fail with potentially confusing diagnostics.
  • [edge-case] .github/workflows/functional-tests.yml:247 — The go-version-file input hardcodes ${{ runner.temp }}/fullsend/go.mod rather than using ${{ env.FULLSEND_CHECKOUT }}/go.mod. The path is independently constructed in two places; changing the checkout location in one step would silently break the other.
  • [defense-in-depth-reduction] .github/workflows/functional-tests.yml:248 — The old code filtered openshell-version.sh through grep -E '^OPENSHELL_(VERSION|SHA)=' before eval. The new code sources the entire script without filtering. Practical risk is bounded since the workflow already executes other scripts from the same checkout without filtering (install-openshell.sh, make go-build).

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Aug 13, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 11:52 AM UTC · Completed 12:09 PM UTC

Commit: ed48ceb · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 12:15 PM UTC · Completed 12:32 PM UTC

Commit: bb1e4bc · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review findings from an automated pass, focused on the workflow_call reusable-workflow path this PR wires up. Several of the assumptions about github.event_name/github.ref inside a workflow_call invocation don't hold per GitHub's documented behavior (the github context is always the caller's), which affects a few of the changes below.


Two additional findings on lines outside this PR's diff hunks (GitHub's review API can't anchor inline comments there):

.github/workflows/functional-tests.yml:49

HIGH: Concurrency group collides across callers/repos for workflow_call, and with this repo's own CI

concurrency.group falls back to format('{0}-{1}', github.workflow, github.ref) for every non-pull_request_target event, and cancel-in-progress (line 52) is false whenever github.ref == 'refs/heads/main'. Per the same caller-context behavior noted above, for a workflow_call invocation github.ref and github.workflow are the CALLER's values, not anything unique to the call or derived from inputs.fullsend_ref.

A workflow_call from fullsend's release pipeline triggered off refs/heads/main computes the exact same group string (Functional Tests-refs/heads/main) as this repo's own routine push-triggered CI on main, so one queues behind the other instead of running independently — a release-gating run can be silently delayed by unrelated CI here (or vice versa), and multiple concurrent workflow_call invocations for different fullsend_ref values from the same caller ref also serialize behind each other. This undermines the PR's stated goal of decoupling this repo's CI from fullsend's release cadence.

Suggestion: include something call-specific in the concurrency group for workflow_call, e.g. github.event_name == 'workflow_call' && format('functional-call-{0}-{1}', inputs.fullsend_ref, github.run_id) || ..., so cross-repo/cross-ref invocations never collide with each other or with this repo's own CI.

.github/workflows/functional-tests.yml:199

MEDIUM: fullsend is cloned and rebuilt from source independently for every matrix leg

functional-tests fans out into a matrix over agent, and each leg independently clones fullsend and runs make -C "${FULLSEND_CHECKOUT}" go-build — a full Go module download + compile, repeated once per selected agent in parallel. fullsend-ai/fullsend's own functional-tests.yml builds fullsend exactly once in a single, non-matrixed job, so the claim of matching fullsend's own CI is only true for the build mechanism, not the multiplied cost. For a PR touching several agents this multiplies clone bandwidth and build time by the matrix size — a cost not incurred by the previous release-tarball-download approach.

Suggestion: build fullsend once in a preceding job (or in detect) and share the binary across matrix legs via actions/upload-artifact/download-artifact, rather than repeating the clone+build per agent.

Comment thread .github/workflows/functional-tests.yml
Comment thread .github/workflows/functional-tests.yml
Comment thread .github/workflows/functional-tests.yml
Comment thread .github/workflows/functional-tests.yml
Comment thread .github/workflows/functional-tests.yml
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 4:22 PM UTC · Ended 4:36 PM UTC

Commit: df90aed · View workflow run →

@maruiz93

Copy link
Copy Markdown
Contributor Author

Addressing the two non-inline findings from this review:

Concurrency group collision (line 49): Addressed in df90aed — cross-repo calls now get a unique concurrency group (functional-call-{run_id}) via a github.repository != 'fullsend-ai/agents' check, so they never collide with this repo's own CI.

Per-matrix-leg fullsend build (line 199): Filed as #783 for follow-up. The current approach is correct; the --depth 1 shallow clone and Go module caching (also added in df90aed) mitigate some cost. The full optimization (build once, share via artifact) is a structural workflow change better suited for a separate PR.

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 4:37 PM UTC · Completed 4:54 PM UTC

Commit: bf4f479 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@ralphbean ralphbean left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1 to the idea

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

CRITICAL: actions/checkout has no repository/ref override, so cross-repo workflow_call runs will check out the caller's repo instead of fullsend-ai/agents (.github/workflows/functional-tests.yml:208, also affects the detect job's checkout at line 161 — outside this PR's diff hunks, so posted here rather than inline)

This PR's stated purpose is to let fullsend-ai/fullsend's release pipeline invoke this workflow via the new workflow_call trigger (fullsend#6173). None of the actions/checkout steps (gate: line 75, detect: line 161, functional-tests: line 208) set an explicit repository:/ref: input, so they default to ${{ github.repository }}/${{ github.ref }}. Per GitHub's documented reusable-workflow semantics, when a workflow_call job runs, the github context (including github.repository, github.sha, github.ref) reflects the CALLING workflow's repo/ref, not the repo hosting the reusable workflow — this repo's own detect-job fix (gating "Get changed files" on github.repository == 'fullsend-ai/agents') already relies on this exact fact. The gate job is unaffected since its if restricts it to pull_request_target, but detect and functional-tests both proceed for any non-pull_request_target event, including workflow_call. So when fullsend-ai/fullsend's pipeline calls this workflow, actions/checkout at lines 161 and 208 will check out fullsend-ai/fullsend at fullsend's SHA instead of fullsend-ai/agents — meaning .github/scripts/select-eval-agents.sh, eval/run-functional.sh, eval/*/eval.yaml, etc. are all missing and the job fails (or worse, silently misbehaves if any paths happen to coincide). This is not raised in any existing review thread on the PR.

Suggestion: pin these checkout steps to this repo/ref explicitly, e.g. repository: fullsend-ai/agents with a ref: derived from github.workflow_ref/github.workflow_sha (which do identify the reusable workflow's own repo/ref) when github.event_name == 'workflow_call', or hardcode repository: fullsend-ai/agents / ref: main if a moving target is acceptable. Verify with an actual cross-repo workflow_call invocation before merging.


The remaining findings are posted as inline comments on this review.

Comment thread .github/workflows/functional-tests.yml
Comment thread .github/workflows/functional-tests.yml
Comment thread .github/workflows/functional-tests.yml
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 7:38 PM UTC · Ended 7:42 PM UTC

Commit: 66b2a54 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:43 PM UTC · Completed 8:01 PM UTC

Commit: 64eb158 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review-only pass focused on the new workflow_call trigger added in this PR. Two findings below (one file-level comment for a checkout config issue on lines outside the diff, one inline comment on the new workflow_call block).

Comment thread .github/workflows/functional-tests.yml
Comment thread .github/workflows/functional-tests.yml
maruiz93 and others added 4 commits August 14, 2026 09:13
Allow external workflows (e.g. fullsend release pipeline) to invoke
functional tests against a specific fullsend ref. Defaults to main
for standalone runs. Also adds fullsend_ref to workflow_dispatch for
manual testing.

Ref: fullsend-ai#775

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Marta Anon <manon@redhat.com>
Replace the release binary download with clone-and-build from source
using make go-build. Replace GitHub API fetches of openshell scripts
with direct reads from the cloned fullsend checkout. The fallback
clone path handles SHA refs that --branch doesn't support.

Ref: fullsend-ai#775

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Marta Anon <manon@redhat.com>
Fixes actionlint SC2086 (shellcheck) by using a block scalar with
proper double quoting around the variable expansion.

Ref: fullsend-ai#775

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Marta Anon <manon@redhat.com>
…ckout

- Add workflow_call to the skip condition in the detect job's
  changed-files step, so reusable-workflow invocations run all agents
  without a misleading PR API warning.
- Replace go-version: stable with go-version-file pointing at the
  cloned fullsend go.mod for deterministic toolchain selection.
- Split clone and build into separate steps so setup-go can use the
  cloned go.mod.

Ref: fullsend-ai#775

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Marta Anon <manon@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 14, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 7:14 AM UTC · Ended 7:24 AM UTC

Commit: 1827c27 · View workflow run →

@maruiz93

Copy link
Copy Markdown
Contributor Author

Addressed in f58beb8 — three changes:

  1. Both checkout steps now set repository: and ref: for cross-repo calls: pins to fullsend-ai/agents with github.workflow_sha when github.repository != 'fullsend-ai/agents', preserving existing behavior for same-repo triggers.

  2. functional-tests-complete now hard-fails when CROSS_REPO == true && TESTS_RESULT == skipped, preventing the silent vacuous-pass scenario.

  3. Org-level guard (repository_owner == 'fullsend-ai') on both jobs as defense-in-depth.

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 14, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:25 AM UTC · Completed 7:47 AM UTC

Commit: f58beb8 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

Match the existing graceful-skip design — the "Check for secrets"
step already handles missing GCP secrets by skipping functional
tests with a warning. Making secrets required at the workflow_call
schema level would hard-fail callers before the skip logic runs.

Ref: fullsend-ai#775

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Marta Anon <manon@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 14, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:25 AM UTC · Completed 8:46 AM UTC

Commit: 4f4e6ce · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the review comment for full details.


Note: The following inline comments could not be posted on the diff (GitHub returned 422) and are included here instead:

  • .github/workflows/functional-tests.yml:256: [low] workflow-command-injection

The "Validate fullsend ref" step interpolates FULLSEND_REF into an ::error:: workflow command without sanitizing for encoded newlines or :: sequences. Practical risk is very low: workflow_call inputs can only be set by calling workflows (not PR authors), and the regex guard rejects most payloads before the error path is reached.

Suggested fix: Sanitize FULLSEND_REF before interpolating into the ::error:: command: SAFE_REF=$(echo "${FULLSEND_REF}" | tr -d \n\r | sed -e s/%0[aAdD]//g -e s/::/: :/g) and use ${SAFE_REF} in the error message.

  • .github/workflows/functional-tests.yml:267: [low] credential-exposure

The "Clone fullsend" step embeds GH_TOKEN in the git clone URL. If the clone fails, git may include the URL in stderr. GitHub Actions built-in log masking redacts github.token values, and the token is short-lived and job-scoped.

Suggested fix: Use git -c http.extraHeader="Authorization: bearer ${GH... or configure credentials via git credential helper instead of embedding the token in the URL.

  • .github/workflows/functional-tests.yml:255: [low] input-validation

The fullsend_ref validation regex ^v[0-9] is only start-anchored, accepting any string starting with v followed by a digit. Git --branch flag constrains the value to existing refs, and workflow_call is only invocable by trusted callers within the org.

Suggested fix: Tighten the regex to ^v[0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9.]+)?$ to match only semver release tags, or at minimum add $ anchor and restrict the character set.

  • .github/workflows/functional-tests.yml:52: [low] architectural-coherence

The concurrency group uses github.repository != fullsend-ai/agents to detect cross-repo calls. This introduces implicit coupling to the canonical repo name. However, this pattern is used consistently throughout the workflow, so it is not a new coupling unique to the concurrency group.

  • .github/workflows/functional-tests.yml (file-level): Line 371 · [low] scope-alignment

The functional-tests-complete job now fails if a cross-repo call completes with zero functional tests. This is a guard rail for the workflow_call feature being added — it ensures cross-repo callers do not silently succeed with zero tests.

Suggested fix: Add a brief code comment explaining the rationale for the cross-repo zero-test guard.

@maruiz93
maruiz93 added this pull request to the merge queue Aug 14, 2026
Merged via the queue into fullsend-ai:main with commit a8566cd Aug 14, 2026
12 checks passed
@maruiz93
maruiz93 deleted the agents-dev-ci branch August 14, 2026 09:19
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 14, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 9:21 AM UTC · Completed 9:36 AM UTC

Commit: 4f4e6ce · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #776 — Build fullsend from source in functional tests

A human-authored, single-file PR modifying .github/workflows/functional-tests.yml to add workflow_call support and build fullsend from source. The review agent ran 7 successful rounds (plus 4 cancelled) and posted 22 inline comments — all low severity. Meanwhile, human reviewer waynesun09 caught 2 CRITICAL bugs that the review agent missed entirely across every round:

  1. github.event_name in called workflows: The PR initially conditioned logic on github.event_name == 'workflow_call', which is never true inside a called workflow — event_name reflects the caller's event. The review agent never flagged this.
  2. actions/checkout without repository:: Without explicit repository: and ref: parameters, checkout in a workflow_call context checks out the calling repo, not the callee. This would have caused functional tests to silently pass against the wrong codebase.

Notably, the review agent's own architectural-coherence finding at line 52 actively suggested using github.event_name == 'workflow_call' as a replacement for the author's correct github.repository != 'fullsend-ai/agents' check — recommending exactly the CRITICAL anti-pattern the human reviewer identified. The qodo-code-review bot, in a single run, also caught a medium-severity correctness bug (workflow_call misrouting the diff fetch step) that the fullsend review agent missed.

The review agent's 22 inline comments repeated the same 4-5 low-severity findings across rounds (defense-in-depth-reduction 5x, credential-exposure 4x, workflow-command-injection 3x, input-validation 3x). One useful finding was surfaced: an unused AGENTS env var (logic-error), which the author fixed.

Autonomy assessment

The requires-manual-review label (triggered by .github/ protected path) worked as intended. Human review was essential — without it, the PR would have merged with 2 CRITICAL bugs causing silent test failures on cross-repo invocations. Until GHA platform semantic knowledge is added to the review agent, human review of workflow changes adding workflow_call triggers should remain mandatory.

Evidence for existing issues (no new proposals needed)

All improvement opportunities identified are covered by open issues:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires-manual-review Review requires human judgment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build fullsend from source in functional tests instead of downloading release binary

3 participants