external/ag-shared/prompts/skills/nx-performance/references/ci-patterns.md
AG product monorepos manage three layers of caching in CI via a setup-nx composite action:
Key: yarn.lock + patches/*.patch + all package.json files
Fallback: prefix restore (any matching yarn.lock)
Release branches: release-{branch}-{hash}
Using only yarn.lock misses changes to workspace package.json files (new scripts, resolutions). Include all package.json files in the key.
Key: yarn.lock + package.json hashes + github.sha
Prefix restore: partial cache hits from prior commits
Tidy step: prune stale entries before save
GHA caches have a 10 GB limit. Pruning stale Nx cache entries before saving prevents eviction of valuable entries.
init job: uploads dist/ + generated examples
e2e jobs: download artifacts — no rebuild needed
init job uses read-write — it populates the cache for all downstream jobs.lint, build, test, e2e) use read-only — they restore but never write, preventing cache corruption from parallel writes.The action sets NX_PARALLEL to the CPU count unless already set. CI jobs needing serial execution (e.g., tests with NX_PARALLEL: 1) override this explicitly.
| Branch type | NX_BASE value |
|---|---|
latest / next | {branch}-success tag |
Release (b*.*.*) | {branch}-success if exists, else {branch} |
| PR | origin/{base_branch} |
The report job tags successful CI runs with {branch}-success. This means nx affected compares against the last successful build, not just the previous commit — ensuring a failed CI run doesn't shift the baseline and mask regressions.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/latest' && github.ref != 'refs/heads/next' }}
latest/next: runs are never cancelled (success tag must be set reliably).A detect-changes job uses dorny/paths-filter to check if the PR only touches non-code files. If so, only lint runs — all other jobs are skipped.
Code paths: packages/**, libraries/**, plugins/**, tests/**, tools/**, external/ag-shared/**, *.json, *.ts, *.js, yarn.lock, nx.json.
affected vs run-many toggleThe CI workflow supports switching between nx affected (default) and nx run-many (full workspace) via workflow_dispatch input. Useful for debugging where affected may compute the wrong diff, or for validating a full-workspace build before releases.
The task autogen plugin tags volatile examples with skip-gha-cache. CI uses a two-phase strategy:
tag:skip-gha-cache)--excludeTaskDependencies --skip-nx-cacheThis ensures volatile examples are always rebuilt fresh while cacheable ones benefit from Nx caching.
The CI pipeline dynamically calculates test shard counts based on the number of affected projects.
no-sharding, bundle size validation (size-limit), package sanity checks (pack:verify).--shard=N/total.Only run on latest/release branches or when test files are directly modified.
NX_PARALLEL: 1 for test jobs — tests run sequentially within each shard to avoid resource contention (canvas rendering, GC-sensitive benchmarks).
The init job builds all packages and generates all examples, then uploads outputs as a GHA artifact. E2E test shards download this artifact instead of rebuilding.
# init job: persist build outputs
- uses: actions/upload-artifact@v4
with:
name: e2e-init-outputs
path: |
dist/
packages/*/dist/
external/*/dist/
packages/<product>-website/e2e/generated/
# e2e job: restore build outputs
- uses: actions/download-artifact@v4
with:
name: e2e-init-outputs
Visual regression tests generate image snapshots across sharded test runs. A custom snapshot workflow collects them:
snapshot-prepare — creates a temporary branch for snapshot updatessnapshot-branch — each shard commits its snapshot changessnapshot-notify — report job checks for updates and notifies via Slack/PR commentParallel OK: build:types, build:package, lint:eslint, generate-example
Serial (parallelism: false): benchmark (GC-sensitive), test:e2e (Playwright), test (GC-exposed Jest)
NX_DAEMON=false set for CI (avoids daemon startup overhead in ephemeral environments)parallelism: false for CPU-intensive/flaky targetsyarn.lock + patches/ + all package.json filesgithub.sha with prefix restore)NX_BASE set to a success tag for affected accuracycancel-in-progress for PR branches, never for main.nxignore excludes generated files, patches, and vendored directoriesaffected vs run-many toggle available