Skip to content

perf(ci): skip container init for changeset PRs#2902

Merged
amikofalvy merged 3 commits intomainfrom
perf/skip-container-init-changeset-prs
Mar 30, 2026
Merged

perf(ci): skip container init for changeset PRs#2902
amikofalvy merged 3 commits intomainfrom
perf/skip-container-init-changeset-prs

Conversation

@amikofalvy
Copy link
Copy Markdown
Collaborator

Summary

  • Service containers (Doltgres, Postgres) in cypress-e2e and create-agents-e2e were initialized before the changeset check ran, wasting ~30s of ubuntu-32gb runner time on every changeset PR
  • Extracts the changeset check into a lightweight job on ubuntu-latest that runs first. The heavy jobs depend on it via needs: and skip entirely (including container init) when it's a changeset PR
  • Also removes all redundant step-level if: changeset-check guards since the job-level if already gates everything (-83 lines net)

Affects: ci.yml (both ci and create-agents-e2e jobs), cypress.yml (cypress-e2e job)

Test plan

  • Verify CI/Cypress/Create Agents E2E checks still pass on this PR (non-changeset)
  • After merge, verify changeset PRs show the heavy jobs as "skipped" without container init

🤖 Generated with Claude Code

amikofalvy and others added 2 commits March 30, 2026 12:11
The changesets/action pushes commits using the default GITHUB_TOKEN
credential, which GitHub ignores for triggering downstream workflows.
This left the Version Packages PR (#2881) stuck with required checks
(ci, Cypress E2E, Create Agents E2E) permanently waiting.

Configures the git remote URL with the inkeep-internal-ci App token
before changesets/action runs — same pattern applied to ci.yml and
auto-format.yml in #2871.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Service containers (Doltgres, Postgres) in cypress-e2e and
create-agents-e2e were initialized before the changeset check ran,
wasting ~30s of ubuntu-32gb runner time on every changeset PR.

Extracts the changeset check into a lightweight job on ubuntu-latest
that runs first. The heavy jobs now depend on it via `needs:` and
skip entirely (including container init) when it's a changeset PR.

Also removes all redundant step-level `if: changeset-check` guards
since the job-level `if` already gates everything.

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

changeset-bot Bot commented Mar 30, 2026

⚠️ No Changeset found

Latest commit: 709bfed

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

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 30, 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 30, 2026 7:35pm
agents-docs Ready Ready Preview, Comment Mar 30, 2026 7:35pm
agents-manage-ui Ready Ready Preview, Comment Mar 30, 2026 7:35pm

Request Review

@pullfrog
Copy link
Copy Markdown
Contributor

pullfrog Bot commented Mar 30, 2026

TL;DR — Changeset PRs no longer allocate expensive ubuntu-32gb runners or spin up service containers. A reusable composite action detects changeset PRs, and a lightweight changeset-check job on ubuntu-latest gates the heavy CI/E2E jobs at the job level — skipping runner allocation and container init entirely.

Key changes

  • Extract changeset detection into a reusable composite action — New .github/composite-actions/changeset-check/action.yml encapsulates branch-name checks, merge-group API lookups, and .changeset/-only file-change detection in a single reusable action.
  • Add changeset-check job to gate heavy CI runners — Each workflow (ci.yml, cypress.yml) runs the composite action on ubuntu-latest first; the expensive jobs skip entirely via needs: + job-level if, preventing container init.
  • Remove redundant step-level if guards and duplicated scripts — With the job-level gate in place, per-step if: steps.changeset-check.outputs.is_changeset != 'true' conditions and the duplicated inline scripts in create-agents-e2e and cypress-e2e are removed.
  • Configure git remote with App token in release.yml — Ensures commits pushed by changesets/action use the GitHub App token so they trigger downstream CI workflows.

Summary | 4 files | 3 commits | base: mainperf/skip-container-init-changeset-prs


Reusable composite action for changeset detection

Before: Each workflow (ci.yml, cypress.yml, create-agents-e2e) duplicated a ~50-line bash script inline to detect changeset PRs — three copies of the same logic that had to be kept in sync.
After: A single composite action at .github/composite-actions/changeset-check/action.yml encapsulates all detection heuristics (branch name, merge-group API lookup, .changeset/-only file changes) and exposes an is_changeset output.

The composite action uses a sparse checkout (sparse-checkout: .github/composite-actions/changeset-check) with fetch-depth: 1 to keep the detection job as fast as possible.

.github/composite-actions/changeset-check/action.yml


Lightweight job gates heavy CI runners

Before: The changeset detection script ran inside the main CI job — after the ubuntu-32gb runner was allocated and service containers (Doltgres, Postgres) were started. Every step had an individual if guard that no-op'd on changeset PRs.
After: A new changeset-check job runs on ubuntu-latest first. The ci, create-agents-e2e, and cypress-e2e jobs declare needs: changeset-check and if: needs.changeset-check.outputs.is_changeset != 'true', so GitHub Actions skips them entirely — no runner allocation, no container init.

This saves ~30s of ubuntu-32gb runner time per changeset PR across all three workflows. The step-level if guards are removed since the job-level condition makes them redundant (~105 lines deleted net).

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


App token for release workflow git pushes

Before: changesets/action pushed commits using the default GITHUB_TOKEN, which GitHub ignores for triggering downstream workflows.
After: The git remote URL is reconfigured with the GitHub App token before changesets/action runs, so pushed commits trigger CI as expected.

.github/workflows/release.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.

Clean refactor — the approach is sound. Extracting the changeset check into a lightweight ubuntu-latest job avoids allocating ubuntu-32gb runners and spinning up service containers for changeset PRs. One behavioral change to be aware of regarding required status checks (see inline comment).

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread .github/workflows/ci.yml

ci:
needs: changeset-check
if: needs.changeset-check.outputs.is_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.

Required status check interaction: Previously, ci always reported "success" (steps were individually skipped). Now it reports "skipped" when the changeset check fires. If ci, create-agents-e2e, or cypress-e2e are required status checks in branch protection, verify that your GitHub settings treat skipped checks as passing — this is the default for newer repos but may not be configured here. If not, changeset PRs will be blocked from merging.

Same applies to create-agents-e2e (line 302) and cypress-e2e in cypress.yml (line 86).

# changesets/action trigger downstream CI workflows. Without this, the
# push uses the default GITHUB_TOKEN which GitHub ignores for triggering.
- name: Configure git remote with App token
run: git remote set-url origin "https://x-access-token:${APP_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
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 is a separate fix from the changeset-skip optimization — configuring the git remote with the App token so changesets/action pushes trigger downstream CI. Worth calling out in the PR description that this is bundled in, since it's unrelated to the container-init skip.

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

(1) Total Issues | Risk: Low

🟠⚠️ Major (1) 🟠⚠️

🟠 1) ci.yml, cypress.yml Duplicated changeset-check logic across workflows

files:

Issue: The changeset-check job script is nearly identical across both workflows (~60 lines of shell script). This violates DRY and increases maintenance burden when the detection logic needs updating.

Why: When the changeset detection logic needs to change (e.g., adding new branch patterns, fixing edge cases), both workflows must be updated in sync. Having two copies doubles the risk of drift and bugs. The detection logic already has several conditions (branch name check, merge group PR lookup, changed files analysis) that have evolved over time.

Fix: Extract the changeset-check logic into a reusable composite action at .github/composite-actions/changeset-check/action.yml with an is_changeset output. Both workflows can then reference it:

changeset-check:
  runs-on: ubuntu-latest
  outputs:
    is_changeset: ${{ steps.check.outputs.is_changeset }}
  steps:
    - uses: ./.github/composite-actions/changeset-check
      id: check

Refs:

🧹 While You're Here (1) 🧹

Inline Comments:

  • 🧹 While You're Here: ci.yml:308 Doltgres image uses mutable :latest tag (pre-existing)

💡 APPROVE WITH SUGGESTIONS

Summary: The optimization is well-designed — extracting the changeset check into a lightweight job that runs before expensive ubuntu-32gb jobs ensures container initialization is skipped entirely for changeset PRs. The job-level conditionals are correctly placed, and the release.yml git remote configuration fix is appropriate. The main suggestion is to extract the duplicated changeset detection script (~60 lines) into a composite action to avoid drift between ci.yml and cypress.yml. This is not blocking but would improve maintainability.

Reviewers (1)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-devops 5 1 0 0 1 0 0
Total 5 1 0 0 1 0 0

Note: 3 findings were INFO-level confirmations that the implementation is correct (not issues).

@github-actions github-actions Bot deleted a comment from claude Bot Mar 30, 2026
The changeset detection logic (~60 lines of shell) was duplicated
across ci.yml and cypress.yml. Extracts it into a shared composite
action at .github/composite-actions/changeset-check/action.yml.

Both workflows now do a sparse checkout (just the composite action
directory) and delegate to the shared action, keeping the changeset
detection logic in one place.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
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

Re-review scope: This review covers only the delta since commit f45f47ff1ac9 — specifically commit 709bfed92 which extracts the duplicated changeset-check logic into a reusable composite action, addressing the prior review's feedback.

✅ Prior Feedback Addressed

The previous review flagged that the changeset-check job script (~60 lines) was duplicated across ci.yml and cypress.yml. This commit cleanly addresses that by:

  1. Creating .github/composite-actions/changeset-check/action.yml with the shared logic
  2. Both workflows now reference it with sparse-checkout for minimal fetch overhead
  3. Net reduction of ~108 lines across the two workflow files

The refactor correctly preserves all detection logic:

  • Branch name check (changeset-release/main)
  • Merge group PR lookup via gh pr view
  • File-change analysis for .changeset/-only PRs

💭 Consider (1) 💭

💭 1) changeset-check/action.yml Add explicit inputs for better documentation

Issue: The composite action uses env vars set from github context expressions (HEAD_REF, GITHUB_EVENT_NAME, etc.) within the step, but doesn't declare them as formal inputs.

Why: Adding an inputs: section would make the action's contract self-documenting and allow callers to override values for testing. This is a style/clarity improvement — the current implementation is fully functional.

Fix: Optional — consider adding inputs with defaults:

inputs:
  head_ref:
    description: "Head ref of the PR (defaults to github.head_ref)"
    required: false
    default: ${{ github.head_ref }}

Refs:

🕐 Pending Recommendations (1)

  • 🧹 ci.yml:258 Doltgres image uses mutable :latest tag (raised in prior review)

✅ APPROVE

Summary: The delta cleanly addresses the prior review's feedback by extracting the duplicated changeset-check logic into a reusable composite action. The implementation is correct, the sparse-checkout pattern is appropriate for minimizing fetch overhead, and all detection logic is preserved. Nice refactor! 🎉

Reviewers (1)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-devops 3 0 1 0 0 1 1
Total 3 0 1 0 0 1 1

Note: 1 INFO finding (auto-format.yml inline check) was discarded as pre-existing and not relevant to this PR's scope.

Discarded (1)
Location Issue Reason Discarded
auto-format.yml:21 Uses inline branch check instead of composite action Pre-existing, simpler check is sufficient for that lightweight workflow, and overhead of sparse-checkout not worthwhile.

@github-actions github-actions Bot deleted a comment from claude Bot Mar 30, 2026
@amikofalvy amikofalvy enabled auto-merge March 30, 2026 19:37
@amikofalvy amikofalvy added this pull request to the merge queue Mar 30, 2026
Merged via the queue into main with commit e206624 Mar 30, 2026
19 of 20 checks passed
@amikofalvy amikofalvy deleted the perf/skip-container-init-changeset-prs branch March 30, 2026 19:47
amikofalvy added a commit that referenced this pull request Mar 30, 2026
The changeset-check optimization from #2902 skips the heavy ci,
Cypress E2E, and Create Agents E2E jobs on changeset PRs. But those
job names are required branch-protection checks, so skipping them
leaves the Version Packages PR in UNSTABLE state.

Add lightweight gate jobs that always run on ubuntu-latest and carry
the required check names. They pass unless the real job failed,
satisfying branch protection without spinning up expensive runners.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
github-merge-queue Bot pushed a commit that referenced this pull request Mar 30, 2026
The changeset-check optimization from #2902 skips the heavy ci,
Cypress E2E, and Create Agents E2E jobs on changeset PRs. But those
job names are required branch-protection checks, so skipping them
leaves the Version Packages PR in UNSTABLE state.

Add lightweight gate jobs that always run on ubuntu-latest and carry
the required check names. They pass unless the real job failed,
satisfying branch protection without spinning up expensive runners.

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
tim-inkeep pushed a commit that referenced this pull request Mar 31, 2026
* fix(ci): configure git remote with App token in release workflow

The changesets/action pushes commits using the default GITHUB_TOKEN
credential, which GitHub ignores for triggering downstream workflows.
This left the Version Packages PR (#2881) stuck with required checks
(ci, Cypress E2E, Create Agents E2E) permanently waiting.

Configures the git remote URL with the inkeep-internal-ci App token
before changesets/action runs — same pattern applied to ci.yml and
auto-format.yml in #2871.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* perf(ci): skip container init for changeset PRs by extracting check job

Service containers (Doltgres, Postgres) in cypress-e2e and
create-agents-e2e were initialized before the changeset check ran,
wasting ~30s of ubuntu-32gb runner time on every changeset PR.

Extracts the changeset check into a lightweight job on ubuntu-latest
that runs first. The heavy jobs now depend on it via `needs:` and
skip entirely (including container init) when it's a changeset PR.

Also removes all redundant step-level `if: changeset-check` guards
since the job-level `if` already gates everything.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* refactor(ci): extract changeset check into reusable composite action

The changeset detection logic (~60 lines of shell) was duplicated
across ci.yml and cypress.yml. Extracts it into a shared composite
action at .github/composite-actions/changeset-check/action.yml.

Both workflows now do a sparse checkout (just the composite action
directory) and delegate to the shared action, keeping the changeset
detection logic in one place.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
tim-inkeep pushed a commit that referenced this pull request Mar 31, 2026
The changeset-check optimization from #2902 skips the heavy ci,
Cypress E2E, and Create Agents E2E jobs on changeset PRs. But those
job names are required branch-protection checks, so skipping them
leaves the Version Packages PR in UNSTABLE state.

Add lightweight gate jobs that always run on ubuntu-latest and carry
the required check names. They pass unless the real job failed,
satisfying branch protection without spinning up expensive runners.

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
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