Skip to content

Remove fork PR guards from CI workflows#2092

Merged
lawrencecchen merged 3 commits intomainfrom
feat-ci-fork-guards
Mar 25, 2026
Merged

Remove fork PR guards from CI workflows#2092
lawrencecchen merged 3 commits intomainfrom
feat-ci-fork-guards

Conversation

@lawrencecchen
Copy link
Copy Markdown
Contributor

@lawrencecchen lawrencecchen commented Mar 25, 2026

Summary

  • Remove the if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository guards from all WarpBuild jobs (tests, tests-build-and-lag, ui-regressions, build-ghosttykit, compat-tests)
  • Fork PRs are already gated by GitHub's "Require approval for outside collaborators" repo setting, so the workflow-level guards were redundant
  • Update the self-hosted guard test to only verify WarpBuild runner usage (no longer checks for fork conditions)

Test plan

  • Verify workflow-guard-tests passes (the updated test_ci_self_hosted_guard.sh)
  • After merge, push a new commit to an open fork PR (e.g. feat: cmux.json for custom commands #2011) and confirm WarpBuild jobs run after approval

Summary by cubic

Removed fork PR guards from CI so WarpBuild jobs run on approved fork PRs. We now rely on GitHub’s “Require approval for outside collaborators,” and skip GhosttyKit uploads on forks when no token is present.

  • Refactors

    • Removed fork-only if guards from WarpBuild jobs in ci.yml (tests, tests-build-and-lag, ui-regressions), build-ghosttykit.yml, and ci-macos-compat.yml.
    • Extended tests/test_ci_self_hosted_guard.sh to verify WarpBuild runner usage across all three workflows.
  • Bug Fixes

    • Check GHOSTTY_RELEASE_TOKEN at runtime in the GhosttyKit upload step and skip when missing to avoid fork PR failures.

Written for commit 334fd7d. Summary will update on new commits.

Summary by CodeRabbit

  • Chores
    • CI and macOS compatibility workflows now run for all push and pull-request events (removed prior fork-based restrictions).
    • Release upload now skips gracefully when no release token is configured, avoiding failed publish attempts.
  • Tests
    • Test suite updated to check required build runners are present instead of enforcing fork-specific guards.

Fork PRs are already gated by GitHub's "Require approval for outside
collaborators" setting. The workflow-level guards were redundant and
prevented WarpBuild jobs from running even after maintainer approval.
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Mar 25, 2026 3:57am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 66c2450c-75c0-4f79-87ef-df898f63ecdc

📥 Commits

Reviewing files that changed from the base of the PR and between 742d4cc and 334fd7d.

📒 Files selected for processing (1)
  • .github/workflows/build-ghosttykit.yml

📝 Walkthrough

Walkthrough

Removed job-level if: guards that prevented several GitHub Actions jobs from running on forked pull requests; tightened an upload step check to require a non-empty secrets.GHOSTTY_RELEASE_TOKEN. Updated CI guard test to assert presence of WarpBuild runners instead of fork-PR gating.

Changes

Cohort / File(s) Summary
Workflows — build job
.github/workflows/build-ghosttykit.yml
Deleted job-level fork-PR if: guard; added check in "Upload xcframework release" step to skip upload when secrets.GHOSTTY_RELEASE_TOKEN is empty.
Workflows — compat tests
.github/workflows/ci-macos-compat.yml
Removed if: guard from compat-tests so the job runs for configured push and pull_request events.
Workflows — tests & UI
.github/workflows/ci.yml
Removed if: guards from tests, tests-build-and-lag, and ui-regressions so those jobs run unconditionally for configured events.
Tests — guard script
tests/test_ci_self_hosted_guard.sh
Removed fork-PR guard checks and related variables; added check_warp_runner(file, job) to assert WarpBuild runner presence (runs-on / os matching warp-macos-*-arm64) for affected jobs; updated messages accordingly.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

aardvark, codex

Poem

🐰 I hopped through CI fields where old fences fell,
Jobs now wake on forks and begin to swell.
I sniffed for warp runners, cozy and bright,
Pipelines chatter and dance through the night. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: removing fork PR guards from CI workflows, which is the primary objective of this pull request.
Description check ✅ Passed The description provides a clear summary, testing details, and rationale. The test plan is present, though marked as incomplete. Core sections from the template are addressed adequately.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-ci-fork-guards

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 4 files

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 25, 2026

Greptile Summary

This PR removes the workflow-level if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository guards from all five WarpBuild jobs (tests, tests-build-and-lag, ui-regressions, build-ghosttykit, compat-tests), relying instead on GitHub's repo-level "Require approval for outside collaborators" setting to gate fork PRs. The companion test script is updated to match, dropping fork-guard assertions and keeping only the WarpBuild runner assertions.

  • The rationale is sound: GitHub's approval gate fires before any workflow jobs run, so the in-workflow guards were genuinely redundant.
  • Secrets (e.g. GHOSTTY_RELEASE_TOKEN) are not passed to fork PRs by default, so the build-ghosttykit release-upload step remains naturally protected even without an explicit if: guard.
  • The updated test_ci_self_hosted_guard.sh only covers ci.yml; no assertions are added for build-ghosttykit.yml or ci-macos-compat.yml, leaving a minor gap in automated regression coverage.

Confidence Score: 5/5

  • Safe to merge — the change is a clean removal of redundant guards backed by a platform-level control, with no functional risk to the CI pipeline.
  • All removed guards are genuinely covered by GitHub's built-in approval gate; paid-runner billing exposure only exists after a maintainer explicitly approves a fork PR. Custom secrets remain inaccessible to fork PRs regardless of the guard removal. The only open item is a non-blocking test coverage gap for the two secondary workflow files.
  • No files require special attention; the minor test coverage gap in tests/test_ci_self_hosted_guard.sh is non-blocking.

Important Files Changed

Filename Overview
.github/workflows/ci.yml Removes the if: fork-guard from three WarpBuild jobs (tests, tests-build-and-lag, ui-regressions). Change is intentional and safe given the repo-level approval gate.
.github/workflows/build-ghosttykit.yml Removes the fork-guard from build-ghosttykit. The sensitive GHOSTTY_RELEASE_TOKEN secret is already unavailable to fork PRs by GitHub's default secret-isolation policy, so the upload step is still protected.
.github/workflows/ci-macos-compat.yml Removes the fork-guard from compat-tests. The removed comment noted "GhosttyKit download needs repo access"; this is now implicitly covered by the repo-level approval gate.
tests/test_ci_self_hosted_guard.sh Updated regression test now only verifies WarpBuild runner usage for the three jobs in ci.yml. No coverage added for build-ghosttykit.yml or ci-macos-compat.yml.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Fork PR opened] --> B{GitHub repo setting:\nRequire approval for\noutside collaborators?}
    B -- No approval yet --> C[Workflows queued\nbut not run]
    B -- Approved by maintainer --> D[All CI jobs triggered]
    D --> E[ubuntu-latest jobs\nworkflow-guard-tests\nremote-daemon-tests\nweb-typecheck]
    D --> F[WarpBuild paid runners\ntests\ntests-build-and-lag\nui-regressions\nbuild-ghosttykit\ncompat-tests]
    F --> G{secrets available?}
    G -- GITHUB_TOKEN only\nfor fork PRs --> H[Jobs run normally\nGHOSTTY_RELEASE_TOKEN\nnot available to forks]
    G -- Full secrets\nfor internal PRs --> I[All steps including\nrelease upload succeed]
Loading

Reviews (1): Last reviewed commit: "Remove fork PR guards from CI workflows" | Re-trigger Greptile

Comment thread tests/test_ci_self_hosted_guard.sh Outdated
Comment on lines +1 to +46
#!/usr/bin/env bash
# Regression test for https://github.com/manaflow-ai/cmux/issues/385.
# Ensures paid/gated CI jobs are never run for fork pull requests.
# Ensures paid CI jobs use WarpBuild runners.
# Fork PRs are gated by GitHub's built-in "Require approval for outside
# collaborators" setting, so workflow-level fork guards are not needed.
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
WORKFLOW_FILE="$ROOT_DIR/.github/workflows/ci.yml"

EXPECTED_IF="if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository"

if ! grep -Fq "$EXPECTED_IF" "$WORKFLOW_FILE"; then
echo "FAIL: Missing fork pull_request guard in $WORKFLOW_FILE"
echo "Expected line:"
echo " $EXPECTED_IF"
exit 1
fi

# tests: must use WarpBuild runner with fork guard (paid runner)
# tests: must use WarpBuild runner (paid runner)
if ! awk '
/^ tests:/ { in_tests=1; next }
in_tests && /^ [^[:space:]]/ { in_tests=0 }
in_tests && /runs-on: warp-macos-15-arm64-6x/ { saw_warp=1 }
in_tests && /github.event.pull_request.head.repo.full_name == github.repository/ { saw_guard=1 }
END { exit !(saw_warp && saw_guard) }
END { exit !(saw_warp) }
' "$WORKFLOW_FILE"; then
echo "FAIL: tests block must keep both warp-macos-15-arm64-6x runner and fork guard"
echo "FAIL: tests block must use warp-macos-15-arm64-6x runner"
exit 1
fi

# tests-build-and-lag: must use WarpBuild runner with fork guard (paid runner)
# tests-build-and-lag: must use WarpBuild runner (paid runner)
if ! awk '
/^ tests-build-and-lag:/ { in_tests=1; next }
in_tests && /^ [^[:space:]]/ { in_tests=0 }
in_tests && /runs-on: warp-macos-15-arm64-6x/ { saw_warp=1 }
in_tests && /github.event.pull_request.head.repo.full_name == github.repository/ { saw_guard=1 }
END { exit !(saw_warp && saw_guard) }
END { exit !(saw_warp) }
' "$WORKFLOW_FILE"; then
echo "FAIL: tests-build-and-lag block must keep both warp-macos-15-arm64-6x runner and fork guard"
echo "FAIL: tests-build-and-lag block must use warp-macos-15-arm64-6x runner"
exit 1
fi

# ui-regressions: must use WarpBuild runner with fork guard (paid runner)
# ui-regressions: must use WarpBuild runner (paid runner)
if ! awk '
/^ ui-regressions:/ { in_tests=1; next }
in_tests && /^ [^[:space:]]/ { in_tests=0 }
in_tests && /runs-on: warp-macos-15-arm64-6x/ { saw_warp=1 }
in_tests && /github.event.pull_request.head.repo.full_name == github.repository/ { saw_guard=1 }
END { exit !(saw_warp && saw_guard) }
END { exit !(saw_warp) }
' "$WORKFLOW_FILE"; then
echo "FAIL: ui-regressions block must keep both warp-macos-15-arm64-6x runner and fork guard"
echo "FAIL: ui-regressions block must use warp-macos-15-arm64-6x runner"
exit 1
fi

echo "PASS: tests WarpBuild runner fork guard is present"
echo "PASS: tests-build-and-lag WarpBuild runner fork guard is present"
echo "PASS: ui-regressions WarpBuild runner fork guard is present"
echo "PASS: tests WarpBuild runner is present"
echo "PASS: tests-build-and-lag WarpBuild runner is present"
echo "PASS: ui-regressions WarpBuild runner is present"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Test coverage doesn't extend to the other two changed workflows

The script validates WarpBuild runner usage for tests, tests-build-and-lag, and ui-regressions in ci.yml, but the PR also removes fork guards from build-ghosttykit.yml (build-ghosttykit job) and ci-macos-compat.yml (compat-tests job). Neither of those workflows is checked here.

If someone later accidentally swaps those jobs off the WarpBuild runner (e.g. to ubuntu-latest) the test won't catch it. Consider adding analogous awk checks against build-ghosttykit.yml and ci-macos-compat.yml, similar to what already exists for the three ci.yml jobs:

# build-ghosttykit: must use WarpBuild runner (paid runner)
GHOSTTYKIT_WORKFLOW="$ROOT_DIR/.github/workflows/build-ghosttykit.yml"
if ! awk '
  /^  build-ghosttykit:/ { in_job=1; next }
  in_job && /^  [^[:space:]]/ { in_job=0 }
  in_job && /runs-on: warp-macos-15-arm64-6x/ { saw_warp=1 }
  END { exit !(saw_warp) }
' "$GHOSTTYKIT_WORKFLOW"; then
  echo "FAIL: build-ghosttykit block must use warp-macos-15-arm64-6x runner"
  exit 1
fi
echo "PASS: build-ghosttykit WarpBuild runner is present"

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a84165666

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 14 to 15
build-ghosttykit:
# Never run WarpBuild jobs for fork pull requests (avoid billing on external PRs).
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: warp-macos-15-arm64-6x
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reintroduce fork guard for GhosttyKit release job

Without the removed job-level if on build-ghosttykit, fork pull_request runs can now reach the upload path, but Upload xcframework release authenticates with secrets.GHOSTTY_RELEASE_TOKEN, which is not provided to fork PR workflows. In the case where a fork PR updates ghostty to a SHA that does not already have an xcframework-* release, check-release sets exists=false and the job fails at publish time, making those PRs unable to pass CI until a maintainer reruns from a trusted branch.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_ci_self_hosted_guard.sh`:
- Around line 9-10: The test currently hardcodes
WORKFLOW_FILE="$ROOT_DIR/.github/workflows/ci.yml", which narrows scope to a
single workflow; change it to iterate over an array (e.g.,
WORKFLOW_FILES=("ci.yml" "build-ghosttykit.yml" "compat-tests.yml") or gather
all .github/workflows/*.yml) and loop through each file, running the same
validation logic for each; update the validation to assert that the relevant
jobs (names like build-ghosttykit and compat-tests) reference the
WarpBuild/warpbuild runner or expected runner label, and remove the duplicated
per-file blocks (the repeated logic in the region currently duplicated around
lines 11-42) by extracting the check into a single loop or helper function so
each workflow is validated consistently.
- Around line 4-5: Restore explicit fork-PR guards for jobs that use
paid/self-hosted runners by adding the condition check used by GitHub Actions
(e.g., if: github.event.pull_request.head.repo.full_name == github.repository)
to the jobs invoked from tests/test_ci_self_hosted_guard.sh (the jobs that
currently only check runner presence around the checks referenced in the
comment), or alternatively add a short documented justification in the same file
explaining why relying solely on the repository-level "Require approval for
outside collaborators" is acceptable; ensure you update the job definitions that
trigger expensive WarpBuilds to include the guard expression so fork PRs cannot
run those runners unless the PR is from the same repo.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 28ce61a4-a6ec-4bce-a76d-73bc4017cda0

📥 Commits

Reviewing files that changed from the base of the PR and between 2a2374a and 7a84165.

📒 Files selected for processing (4)
  • .github/workflows/build-ghosttykit.yml
  • .github/workflows/ci-macos-compat.yml
  • .github/workflows/ci.yml
  • tests/test_ci_self_hosted_guard.sh
💤 Files with no reviewable changes (3)
  • .github/workflows/ci-macos-compat.yml
  • .github/workflows/build-ghosttykit.yml
  • .github/workflows/ci.yml

Comment on lines +4 to +5
# Fork PRs are gated by GitHub's built-in "Require approval for outside
# collaborators" setting, so workflow-level fork guards are not needed.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="$(gh repo view --json nameWithOwner -q .nameWithOwner)"
echo "Repo: $repo"

echo "== Fork PR contributor approval setting =="
gh api "repos/$repo/actions/permissions/fork-pr-contributor-approval" | jq

echo
echo "== WarpBuild/self-hosted jobs without explicit fork guard =="
fd -e yml -e yaml . .github/workflows | while read -r f; do
  awk '
    BEGIN {in_jobs=0; job=""; has_warp=0; has_guard=0}
    /^jobs:/ {in_jobs=1; next}
    in_jobs && /^[^[:space:]]/ {in_jobs=0}
    in_jobs && /^  [A-Za-z0-9_-]+:/ {
      if (job != "" && has_warp && !has_guard) print FILENAME ": " job
      job=$1; sub(":","",job); has_warp=0; has_guard=0; next
    }
    in_jobs && job != "" && /runs-on: .*warp-/ {has_warp=1}
    in_jobs && job != "" && /^    if:/ && /github\.event\.pull_request\.head\.repo\.full_name == github\.repository/ {has_guard=1}
    END { if (job != "" && has_warp && !has_guard) print FILENAME ": " job }
  ' "$f"
done

Repository: manaflow-ai/cmux

Length of output: 158


🏁 Script executed:

cat -n tests/test_ci_self_hosted_guard.sh

Repository: manaflow-ai/cmux

Length of output: 2018


🏁 Script executed:

# Check the related workflow files mentioned in the PR objective
fd -e yml -e yaml . .github/workflows | head -20

Repository: manaflow-ai/cmux

Length of output: 352


🏁 Script executed:

# Look at the git history to understand what changed
git log --oneline tests/test_ci_self_hosted_guard.sh | head -10

Repository: manaflow-ai/cmux

Length of output: 107


🏁 Script executed:

git diff 7a84165~1 7a84165 tests/test_ci_self_hosted_guard.sh | head -100

Repository: manaflow-ai/cmux

Length of output: 249


🏁 Script executed:

git diff 7a84165~1 7a84165 .github/workflows/ | head -200

Repository: manaflow-ai/cmux

Length of output: 249


🏁 Script executed:

# Check if any fork guards remain in the actual workflows
rg "github\.event\.pull_request\.head\.repo\.full_name|github\.repository" .github/workflows/ -A 2 -B 2

Repository: manaflow-ai/cmux

Length of output: 822


🏁 Script executed:

# Check the main CI workflow file
cat -n .github/workflows/ci.yml | head -100

Repository: manaflow-ai/cmux

Length of output: 3704


🏁 Script executed:

# Look for any conditions related to forks or PRs in the workflow files
rg "if:" .github/workflows/ci.yml -A 1 -B 1 | head -50

Repository: manaflow-ai/cmux

Length of output: 499


🏁 Script executed:

# Check the git log to see recent changes to these files
git log --oneline .github/workflows/ci.yml | head -10

Repository: manaflow-ai/cmux

Length of output: 107


🏁 Script executed:

# Check if there are any remaining guard patterns or fork-checking logic in other test files
rg "fork|pull_request" tests/*.sh -l

Repository: manaflow-ai/cmux

Length of output: 94


🏁 Script executed:

# Look at the specific issue `#385` referenced in the test file comment
git log --all --oneline | rg "385|fork.*guard" | head -5

Repository: manaflow-ai/cmux

Length of output: 339


🏁 Script executed:

# Check the other workflows mentioned in the PR objective
cat -n .github/workflows/ci-macos-compat.yml | grep -E "^[[:space:]]+(tests|runs-on)" | head -20

Repository: manaflow-ai/cmux

Length of output: 42


Removing hardcoded fork guards weakens defense-in-depth when you depend on mutable repository settings.

Lines 4-5 justify the removal based on GitHub's built-in fork PR approval setting, but lines 16, 27, and 38 no longer enforce any fork-related constraints—only runner presence. This shifts security enforcement from versioned workflow code to a repository configuration that maintainers could accidentally disable.

If the approval setting is misconfigured or disabled, fork pull requests will run expensive WarpBuild jobs without additional safeguards. Restore explicit fork guards (e.g., if: github.event.pull_request.head.repo.full_name == github.repository) in jobs that use paid runners, or document why GitHub's approval setting is sufficient for this use case.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_ci_self_hosted_guard.sh` around lines 4 - 5, Restore explicit
fork-PR guards for jobs that use paid/self-hosted runners by adding the
condition check used by GitHub Actions (e.g., if:
github.event.pull_request.head.repo.full_name == github.repository) to the jobs
invoked from tests/test_ci_self_hosted_guard.sh (the jobs that currently only
check runner presence around the checks referenced in the comment), or
alternatively add a short documented justification in the same file explaining
why relying solely on the repository-level "Require approval for outside
collaborators" is acceptable; ensure you update the job definitions that trigger
expensive WarpBuilds to include the guard expression so fork PRs cannot run
those runners unless the PR is from the same repo.

Comment thread tests/test_ci_self_hosted_guard.sh Outdated
- Guard test now covers build-ghosttykit.yml and ci-macos-compat.yml
  (not just ci.yml)
- Skip xcframework upload when GHOSTTY_RELEASE_TOKEN is unavailable
  (fork PRs), so the build still validates without failing at publish
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/build-ghosttykit.yml:
- Line 91: The conditional uses the secrets context directly (if:
steps.check-release.outputs.exists == 'false' && secrets.GHOSTTY_RELEASE_TOKEN
!= ''), which is invalid; instead, export the secret into an environment
variable at the job or workflow level (e.g., set env.GHOSTTY_RELEASE_TOKEN = ${{
secrets.GHOSTTY_RELEASE_TOKEN }}), then change the if expression to reference
env.GHOSTTY_RELEASE_TOKEN (for example: if: steps.check-release.outputs.exists
== 'false' && env.GHOSTTY_RELEASE_TOKEN != ''), keeping the rest of the
condition intact so the step checks the output from steps.check-release and the
presence of the token via env.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5831ba90-a5a9-4f5f-964b-dfe529b0a589

📥 Commits

Reviewing files that changed from the base of the PR and between 7a84165 and 742d4cc.

📒 Files selected for processing (2)
  • .github/workflows/build-ghosttykit.yml
  • tests/test_ci_self_hosted_guard.sh

Comment thread .github/workflows/build-ghosttykit.yml Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 742d4ccbb2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/ci.yml
Comment on lines 77 to 78
tests:
# Never run WarpBuild jobs for fork pull requests (avoid billing on external PRs).
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: warp-macos-15-arm64-6x
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore fork guard on GhosttyKit-dependent CI jobs

Removing the fork-PR guard from this WarpBuild job makes fork PRs execute ./scripts/download-prebuilt-ghosttykit.sh, but those PRs still cannot publish missing GhosttyKit releases because build-ghosttykit now skips upload when GHOSTTY_RELEASE_TOKEN is unavailable. As a result, any fork PR that updates ghostty to a SHA without an existing xcframework-* release will deterministically fail these CI jobs (and the same pattern in ci-macos-compat.yml), so contributors cannot get a green run for that class of changes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/build-ghosttykit.yml">

<violation number="1" location=".github/workflows/build-ghosttykit.yml:91">
P2: `secrets.*` is used directly in a step `if`, which GitHub Actions does not support for conditionals. Gate on an `env` value instead.</violation>
</file>

<file name="tests/test_ci_self_hosted_guard.sh">

<violation number="1" location="tests/test_ci_self_hosted_guard.sh:18">
P2: The runner guard can false-pass matrix jobs because it accepts any `os: warp-macos...` line without verifying that `runs-on` actually uses `matrix.os`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread .github/workflows/build-ghosttykit.yml Outdated
if ! awk -v job="$job" '
$0 ~ "^ "job":" { in_job=1; next }
in_job && /^ [^[:space:]]/ { in_job=0 }
in_job && /runs-on:.*warp-macos-.*-arm64/ { saw_warp=1 }
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Mar 25, 2026

Choose a reason for hiding this comment

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

P2: The runner guard can false-pass matrix jobs because it accepts any os: warp-macos... line without verifying that runs-on actually uses matrix.os.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/test_ci_self_hosted_guard.sh, line 18:

<comment>The runner guard can false-pass matrix jobs because it accepts any `os: warp-macos...` line without verifying that `runs-on` actually uses `matrix.os`.</comment>

<file context>
@@ -6,41 +6,32 @@
+  if ! awk -v job="$job" '
+    $0 ~ "^  "job":" { in_job=1; next }
+    in_job && /^  [^[:space:]]/ { in_job=0 }
+    in_job && /runs-on:.*warp-macos-.*-arm64/ { saw_warp=1 }
+    in_job && /os: warp-macos-.*-arm64/ { saw_warp=1 }
+    END { exit !(saw_warp) }
</file context>
Fix with Cubic

secrets context can't be reliably used in step if: conditions.
Check the env var inside the script instead.
@lawrencecchen lawrencecchen merged commit 3a44889 into main Mar 25, 2026
14 checks passed
@lawrencecchen lawrencecchen deleted the feat-ci-fork-guards branch March 25, 2026 04:08
bn-l pushed a commit to bn-l/cmux that referenced this pull request Apr 3, 2026
* Remove fork PR guards from CI workflows

Fork PRs are already gated by GitHub's "Require approval for outside
collaborators" setting. The workflow-level guards were redundant and
prevented WarpBuild jobs from running even after maintainer approval.

* Address review feedback: extend guard test, skip upload on fork PRs

- Guard test now covers build-ghosttykit.yml and ci-macos-compat.yml
  (not just ci.yml)
- Skip xcframework upload when GHOSTTY_RELEASE_TOKEN is unavailable
  (fork PRs), so the build still validates without failing at publish

* Check GHOSTTY_RELEASE_TOKEN at runtime instead of step if

secrets context can't be reliably used in step if: conditions.
Check the env var inside the script instead.

---------

Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant