Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .claude/skills/nx-ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Nx CI Skill

Before committing, simulate what CI would do by running the same affected tasks locally.
This catches failures that would only surface after pushing.

## How CI works

The main CI workflow (`.github/workflows/ci.yml`) runs these steps on every push/PR:

1. `npx nx format:check` — checks formatting for all files
2. `npx nx affected -t lint test build e2e-ci --parallel=3` — runs lint, test, build, e2e-ci
only for projects affected by the change (using `NX_BASE`/`NX_HEAD` set by `nrwl/nx-set-shas`)

## Pre-commit: replicate CI locally with `nx affected`

Run these commands **before committing**, using the same targets CI uses:

```bash
# 1. Check formatting (same as CI)
npx nx format:check

# 2. Find what is affected by your changes vs the base branch
# (omit --base if origin/main is already the default — check nx.json "defaultBase")
npx nx affected -t lint test build e2e-ci --parallel=3 --base=origin/main --head=HEAD
```

> **Why `affected` and not `run-many`?**
> `nx affected` only rebuilds and retests the projects touched by your diff,
> matching exactly what CI will do. `run-many` runs everything regardless of
> whether it changed, which is much slower and doesn't match CI behaviour.

> **`e2e-ci` locally**: The `e2e-ci` target is included to match CI faithfully.
> If no project in your workspace defines this target, Nx skips it silently.
> Remove it from the command if you want a faster pre-commit check that skips e2e.

## Determine what is affected before running

To preview which projects and tasks will run without executing them:

```bash
# Show affected projects
npx nx show projects --affected --base=origin/main --head=HEAD

# Dry-run to see the exact task list
npx nx affected -t lint test build e2e-ci --base=origin/main --head=HEAD --dry-run
```

> **Default base**: `nx affected` uses `defaultBase` from `nx.json` when `--base` is
> omitted. In this repo `nx.json` sets `"defaultBase": "main"`. On CI, `nrwl/nx-set-shas`
> overrides it via the `NX_BASE` / `NX_HEAD` environment variables.

## Circular dependency check

If CI fails with "Could not execute command because the task graph has a circular
dependency", check for circular package dependencies:

```bash
npx nx graph --file=/tmp/nx-graph.json
# then inspect /tmp/nx-graph.json for cycles
```

The most common cause is a package depending on another package that already
depends on it (e.g. `adt-client` ↔ `adk`). Fix by removing the erroneous
dependency from the package that should NOT depend on the other.

> **Why CI may still fail after the fix**: If the PR was branched from an older
> commit of `main` (before the bad dep was introduced), GitHub's auto-created
> merge commit (`refs/pull/N/merge`) re-adds the dep via 3-way merge semantics
> (base has no dep, main added it, your branch didn't touch it → merge keeps it).
> The CI workflow uses `ref: github.event.pull_request.head.sha` to check out
> the PR head instead of the merge commit, which avoids this problem.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0
# For pull_request events, check out the PR head (not GitHub's auto-created
# merge commit). This prevents 3-way merge from re-introducing deps that
# the PR is supposed to remove. nrwl/nx-set-shas still computes the correct
# affected range from git history. Falls back to github.sha for push events.
ref: ${{ github.event.pull_request.head.sha || github.sha }}
Comment on lines +21 to +25
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Fork pr ci checkout 🐞 Bug ⛯ Reliability

The CI workflow checks out github.event.pull_request.head.sha but does not set repository to the
PR head repo. For fork-based pull requests, that SHA is not present in the base repo, so the
checkout step can fail and CI won’t run for external contributors.
Agent Prompt
## Issue description
CI currently checks out `github.event.pull_request.head.sha`, but `actions/checkout` defaults to the base repo unless `repository` is provided. For fork PRs, the head SHA exists only in the fork repo, so checkout can fail and CI won't run.

## Issue Context
Workflow triggers on `pull_request`, so fork PRs are a normal scenario for public repos. The current change explicitly prefers PR head SHA.

## Fix Focus Areas
- .github/workflows/ci.yml[18-26]

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

- uses: actions/setup-node@v6
with:
node-version: 24
Expand Down
Loading