Skip to content

fix(ci): skip CI when PR only changes .changeset/ files#2874

Merged
amikofalvy merged 1 commit intomainfrom
feat/changeset-only-skip-ci
Mar 27, 2026
Merged

fix(ci): skip CI when PR only changes .changeset/ files#2874
amikofalvy merged 1 commit intomainfrom
feat/changeset-only-skip-ci

Conversation

@amikofalvy
Copy link
Copy Markdown
Collaborator

Summary

  • Extends changeset detection in ci.yml and cypress.yml to also skip CI when a PR's only changes are files in .changeset/ (changelog entries, config)
  • Previously, only the automated changeset-release/main bot PR was detected — now any PR with changeset-only changes skips the expensive CI pipeline (32GB runners, databases, Playwright, Cypress)
  • Uses gh pr diff --name-only to check changed files; fail-safe — if the API call fails, CI runs normally

Test plan

  • PR with only .changeset/*.md files → CI skipped
  • PR with .changeset/*.md + code changes → CI runs
  • changeset-release/main bot PR → CI skipped (existing behavior preserved)
  • Push to main → CI always runs
  • Merge group with changeset-only PR → CI skipped

🤖 Generated with Claude Code

PRs that only add/modify files in .changeset/ (changelog entries, config)
don't need full CI (build, test, lint, E2E, Cypress). This extends the
existing changeset-release/main branch detection to also check changed
files via `gh pr diff --name-only`. Fail-safe: if the API call fails or
returns empty, CI runs normally.

Affects: ci.yml (ci + create-agents-e2e jobs), cypress.yml

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 27, 2026

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

Project Deployment Actions Updated (UTC)
agents-api Ready Ready Preview, Comment Mar 27, 2026 7:52pm
agents-docs Ready Ready Preview, Comment Mar 27, 2026 7:52pm
agents-manage-ui Ready Ready Preview, Comment Mar 27, 2026 7:52pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 27, 2026

⚠️ No Changeset found

Latest commit: 7ad17dd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pullfrog
Copy link
Copy Markdown
Contributor

pullfrog Bot commented Mar 27, 2026

TL;DR — Extends the changeset-detection step in CI and Cypress workflows to also skip pipeline runs when a PR's only changed files live under .changeset/. Previously only the changeset-release/main bot branch triggered the skip — now any changeset-only PR avoids spinning up 32 GB runners, databases, and browser tests.

Key changes

  • Skip CI for changeset-only PRs in ci.yml and cypress.yml — after the existing bot-branch check, a new block uses gh pr diff --name-only to list changed files and sets IS_CHANGESET=true when every file matches .changeset/. Fails safe (CI runs) if the API call errors. Also pipes PR_NUMBER into the environment for pull_request events.

Summary | 2 files | 1 commit | base: mainfeat/changeset-only-skip-ci


File-based changeset detection for all PRs

Before: Only the automated changeset-release/main bot PR skipped CI; a human PR containing nothing but .changeset/*.md files still ran the full pipeline.
After: Any PR (or merge-group entry) whose diff is entirely inside .changeset/ is detected and skipped, regardless of branch name.

The new guard runs after the existing branch-name check. It fetches the PR diff via gh pr diff "$PR_NUMBER" --name-only, pipes the output through grep -v '^\\.changeset/', and flips IS_CHANGESET=true when no non-changeset files remain. The || true on grep and 2>/dev/null || echo "" on gh ensure the step never fails — if anything goes wrong, CI proceeds normally.

Why is the same block duplicated three times? Each workflow file (ci.yml, cypress.yml) has its own independent changeset-check step, and ci.yml contains two copies (one for the main job matrix and one for the E2E job). The logic is identical in all three locations.

.github/workflows/ci.yml · .github/workflows/cypress.yml

Pullfrog  | View workflow run | Triggered by Pullfrog | Using Claude Opus𝕏

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

Low urgency. Logic is correct and fail-safe — API errors or unexpected event types fall through to running CI normally. The three-way duplication is a pre-existing pattern; this PR just extends it consistently. One minor concern flagged inline about CHANGED_FILES and empty-line edge cases with echo.

Pullfrog  | View workflow run | Using Claude Opus𝕏

Comment thread .github/workflows/ci.yml
fi

if [ -n "$CHANGED_FILES" ]; then
NON_CHANGESET=$(echo "$CHANGED_FILES" | grep -v '^\.changeset/' || true)
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.

Nit: echo "$CHANGED_FILES" will produce a trailing empty line if $CHANGED_FILES ends with a newline (it won't, since command substitution strips it — but if gh pr diff ever outputs a trailing blank line, $() strips it). More defensibly, you could use printf '%s' "$CHANGED_FILES" to avoid echo's implicit trailing newline, but in practice this is fine because grep -v on an empty line would produce that empty line in NON_CHANGESET, causing the skip to not trigger (a safe false-negative). No action needed — just calling it out.

Comment thread .github/workflows/ci.yml
Comment on lines +61 to +76
# Check if PR only contains .changeset/ file changes
if [ "$IS_CHANGESET" = "false" ] && [ "$GITHUB_EVENT_NAME" != "push" ]; then
if [ "$GITHUB_EVENT_NAME" = "pull_request" ] && [ -n "$PR_NUMBER" ]; then
CHANGED_FILES=$(gh pr diff "$PR_NUMBER" --name-only --repo "$GITHUB_REPOSITORY" 2>/dev/null || echo "")
elif [ "$GITHUB_EVENT_NAME" = "merge_group" ] && [ -n "$PR_NUM" ]; then
CHANGED_FILES=$(gh pr diff "$PR_NUM" --name-only --repo "$GITHUB_REPOSITORY" 2>/dev/null || echo "")
fi

if [ -n "$CHANGED_FILES" ]; then
NON_CHANGESET=$(echo "$CHANGED_FILES" | grep -v '^\.changeset/' || true)
if [ -z "$NON_CHANGESET" ]; then
IS_CHANGESET=true
echo "Only .changeset/ files changed — skipping CI checks"
fi
fi
fi
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.

This 16-line block is now copy-pasted in three jobs across two files. Consider extracting it into a composite action or a reusable workflow step that all three jobs call. That would eliminate the maintenance risk of the blocks drifting out of sync over time. Not blocking for this PR, but worth considering as a follow-up.

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

Approving. Logic is sound and fail-safe.

Pullfrog  | View workflow run | Using Claude Opus𝕏

Copy link
Copy Markdown
Contributor

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low

🟢 No Blocking Issues

The implementation is correct and well-designed:

Correct fail-safe behavior — If the gh pr diff API call fails, CI runs normally (safe default)

Proper shell scripting — Variables are quoted correctly, || true handles grep non-matches, error output is redirected appropriately

Complete event coverage — Handles pull_request, merge_group, and correctly skips the check for push events

Backward compatible — Existing changeset-release/main bot detection is preserved

💭 Consider (1) 💭

Inline Comments:

  • 💭 Consider: .github/workflows/ci.yml:61-76 — Extract duplicated changeset detection logic to composite action

📝 Notes

Fork PRs: The github.token has limited permissions for PRs from forks, so changeset-only PRs from forks will still run full CI. This is acceptable fail-safe behavior and doesn't need to be "fixed" — just documenting for awareness.


✅ APPROVE

Summary: Clean implementation with proper fail-safe behavior. The test plan covers the key scenarios. The duplication suggestion is a nice-to-have for future maintainability but doesn't block this PR.

Reviewers (2)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-devops 4 0 0 0 1 0 3
pr-review-standards 0 0 0 0 0 0 0
Total 4 0 0 0 1 0 3
Discarded (3)
Location Issue Reason Discarded
.github/workflows/ci.yml:62 Condition structure regarding PR_NUMBER availability is subtle Logic is correct as confirmed by both reviewers; clarity is subjective
.github/workflows/ci.yml:64 Fork PRs will run full CI due to token limitations Acceptable fail-safe behavior, documented in notes above
.github/workflows/ci.yml:87 PR_NUMBER variable correctly added Positive observation, not an issue

Comment thread .github/workflows/ci.yml
Comment on lines +61 to +76
# Check if PR only contains .changeset/ file changes
if [ "$IS_CHANGESET" = "false" ] && [ "$GITHUB_EVENT_NAME" != "push" ]; then
if [ "$GITHUB_EVENT_NAME" = "pull_request" ] && [ -n "$PR_NUMBER" ]; then
CHANGED_FILES=$(gh pr diff "$PR_NUMBER" --name-only --repo "$GITHUB_REPOSITORY" 2>/dev/null || echo "")
elif [ "$GITHUB_EVENT_NAME" = "merge_group" ] && [ -n "$PR_NUM" ]; then
CHANGED_FILES=$(gh pr diff "$PR_NUM" --name-only --repo "$GITHUB_REPOSITORY" 2>/dev/null || echo "")
fi

if [ -n "$CHANGED_FILES" ]; then
NON_CHANGESET=$(echo "$CHANGED_FILES" | grep -v '^\.changeset/' || true)
if [ -z "$NON_CHANGESET" ]; then
IS_CHANGESET=true
echo "Only .changeset/ files changed — skipping CI checks"
fi
fi
fi
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.

💭 Consider: Extract changeset detection to composite action

Issue: This 16-line block is duplicated 3 times across ci.yml (2x) and cypress.yml (1x).

Why: DRY violation makes future changes error-prone — any fix or enhancement must be applied in 3 places. The repo already uses composite actions in .github/composite-actions/ for reusable workflow logic.

Fix: Consider extracting to a composite action (e.g., .github/composite-actions/changeset-check/action.yml) that outputs is_changeset. This is non-blocking since the duplication follows existing patterns in the workflow file, but would improve maintainability for future changes.

Refs:

@github-actions github-actions Bot deleted a comment from claude Bot Mar 27, 2026
@amikofalvy amikofalvy enabled auto-merge March 27, 2026 19:54
@amikofalvy amikofalvy added this pull request to the merge queue Mar 27, 2026
Merged via the queue into main with commit 97936a0 Mar 27, 2026
27 of 28 checks passed
@amikofalvy amikofalvy deleted the feat/changeset-only-skip-ci branch March 27, 2026 20:13
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