qv-nx-ci
Skill697 starsChanged 18 days agoApache-2.0View on GitHub
Understand and modify the pnpm+Nx consolidated CI — the generic -nx.yml leaves driven by each package's project.json options.ci. Use when adding/changing a package's CI, onboarding a new package, generalising a bespoke per-package workflow into a leaf, editing the nx-project-matrix action or the on-pr-nx/on-merge-nx/prebuilds-nx/cpp-tests-nx/integration-test-nx leaves, or debugging why a package's CI stage did or didn't run.
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 0 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 30
Mobile stays as
main's: Do not consolidate integration-mobile-test-<pkg>.yml or add mobile to PRs beyond the existing asr/tts … - Very specific: line 43
Add the field under the target's options.ci in the package(s) that need it.
- Very specific: line 45
Do not touch nx-project-matrix — pass-through is generic.
- Very specific: line 49
Add packages/<pkg>/project.json with the targets it needs (build, on-pr, test:cpp, test:integration, benchmark, on-merge) and their …
- Very specific: line 59
Fold: when the flow is the leaf's shape with different values/toggles.
- Very specific: line 60
Carve-out: when steps genuinely diverge (bespoke integration/cpp flow, e.g.
- Very specific: line 63
If the folded flow posts the qvac/prebuild-<pkg> status or gates the merge guard, confirm the producer/trust path …
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Nx CI — consolidated per-package workflows
Per-package CI is consolidated into generic -nx.yml leaves. Each package declares its CI shape as data in packages/<pkg>/project.json under targets.<target>.options.ci; Nx computes the affected set and .github/actions/nx-project-matrix turns each affected package's options.ci into a GitHub Actions matrix that the leaf fans out over.
Full reference (wiring diagram, options.ci cheat-sheet, fork-safety model): docs/ci/nx-ci-consolidation.md. Workspace/tooling primer (pnpm config, Nx affected graph, local commands): docs/pnpm-nx-workspace.md. Read both first.
release-train.yml is not one of these leaves. It publishes the nx release groups in nx.json, not options.ci. See docs/ci/RELEASE-TRAIN.md.
When to use
- Adding or changing a package's CI (prebuilds, cpp tests, integration, on-pr checks, benchmarks, on-merge publish).
- Onboarding a new package to the consolidated pipeline.
- Generalising a bespoke per-package workflow into a leaf.
- Editing
nx-project-matrixor any*-nx.ymlleaf. - Debugging why a stage ran / didn't run for a package.
Mental model: config is data, the leaf is generic
The matrix action flattens every field under options.ci into each matrix row generically ({package, workdir, ...ci} + platform). So a leaf reads a field as ${{ matrix.<field> }} and a new field needs no action change — only the project.json (produce it) and the leaf step (consume it). Keep behaviour in data; touch a .yml only when a genuinely new step/shape is needed.
Hard rules
- Config is read from the trusted default branch, never PR head.
nx-project-matrixdoesgit show <config-ref>:packages/<pkg>/project.json, and onpull_request_targetconfig-ref=default_branch. A new package'sproject.jsonmust land on the default branch before its CI runs. Never "fix" a pre-merge red by reading config from head. - Fork safety is non-negotiable.
on-pr-nx.ymlispull_request_target(base context, secrets). Base = control surface, head = code-under-test. Every privileged job hasfork-approvalfirst inneeds:and gates onauthorize.outputs.allowed. Never add a privileged job without both. Leaves build/testgithub.event.pull_request.head.sha— only after the gates pass. - Mobile stays as
main's. Do not consolidateintegration-mobile-test-<pkg>.ymlor add mobile to PRs beyond the existing asr/ttscoload-smoke-mobilemain-parity job. Never addrun-mobile-addon-testson PRs. hasPrebuildsis derived, not declared — it is true iffbuild.options.ciexists. Don't add it by hand.- Overrides are validated. The action's
overridesinput can only set a field a package already declares — a PR cannot inject new CI behaviour. Keep it that way. - Merge-gated jobs go through
qvac-merge-guard / validate-pronly. Never create a second required check. Use theqv-merge-guard-wireskill /docs/ci/MERGE-GUARD.md. - Never delete/skip/weaken a test. Fix the code or the config.
Recipe A — change an existing package's CI (data-only)
- Edit
packages/<pkg>/project.json→targets.<target>.options.ci. Adjust the existing field (e.g. add a platform row totest:cpp, flipincludeVulkanSdk, change a perf-report pattern). - Nothing else if the field is already consumed by the leaf. Validate (below).
Recipe B — add a NEW options.ci field (data + one leaf step)
- Add the field under the target's
options.ciin the package(s) that need it. Others simply won't have it (matrix row omits it →${{ matrix.<field> }}is empty). - Consume it in the leaf: reference
${{ matrix.<field> }}in the relevant step, or gate a step withif: ${{ matrix.<field> }}. For a whole flag-gated job, add a filtered sublist in thematrixjob'sfilterstep (jqselect(.<field> == true)) and drive the job offfromJSON(needs.matrix.outputs.<field>list). - Do not touch
nx-project-matrix— pass-through is generic.
Recipe C — onboard a new package
- Add
packages/<pkg>/project.jsonwith the targets it needs (build,on-pr,test:cpp,test:integration,benchmark,on-merge) and theiroptions.ci. Copy the closest existing package as a template. - Native addon: set
implicitDependencies: ["inference-addon-cpp", "lint-cpp"](and any real deps) so the graph and affected-detection are correct. - Land
project.jsonon the default branch first (rule 1) — until then, dispatch the leaf withconfig_ref_override/base-refpointed at your branch to test.
Recipe D — generalise a bespoke per-package workflow into a leaf
The consolidation move: fold an on-pr-<pkg>.yml (or prebuilds/cpp/integration/on-merge twin) into the generic leaf.
- Diff the bespoke workflow against a package already folded. What differs is either (a) a value → an
options.cifield, or (b) a genuinely different step → a conditional step in the leaf. - Decide fold vs carve-out:
- Fold when the flow is the leaf's shape with different values/toggles. Express every difference as
options.cifields (Recipe B) and delete the bespoke file. - Carve-out when steps genuinely diverge (bespoke integration/cpp flow, e.g. llm/asr/translation). Set
carveOut: trueon that target'soptions.ci, keep the bespoke reusable, and route to it from the orchestrator via thecarveoutsoutput (if: contains(fromJSON(needs.matrix.outputs.carveouts), '<pkg>')). The package still self-affects.
- Fold when the flow is the leaf's shape with different values/toggles. Express every difference as
- Map, don't reinvent: each bespoke
with:/env/matrix value becomes anoptions.cifield consumed by the existing leaf step. Prefer widening an existing field over adding a near-duplicate. - Delete the legacy file in the same change (or the stacked cleanup PR) so PRs don't run two pipelines. Confirm nothing references it:
git grep <workflow-basename> .github/workflows. - If the folded flow posts the
qvac/prebuild-<pkg>status or gates the merge guard, confirm the producer/trust path (scripts/prebuild-status/) still holds.
Validate before done
node .github/scripts/test/ci-trust-policy.test.mjs— fork-safety + trusted-ref policy (must stay green).node .github/scripts/test/prebuild-status.test.mjs— if you touched prebuild-status trust.actionlint <edited leaves>— only pre-existing shellcheck style is acceptable.pnpm exec nx show projects --affected -t <target> --base=<base> --head=<head>— confirm the package set is what you expect.- Standalone
gh workflow run <leaf>-nx.yml --ref <branch> -f base-ref=<x> -f head-ref=<y>— prove the matrix resolves and the leaf runs. git grep <deleted-workflow-basename> .github/workflowsreturns nothing after a Recipe D deletion.
In this repository56 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .github/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .cursor/rules/agent-integrations.mdcCursor rule
- .cursor/rules/cpp/string-api-conventions.mdcCursor rule
- .cursor/rules/devops/main.mdcCursor rule
- .cursor/rules/no-remote-code-execution.mdcCursor rule
- .cursor/rules/qip-triage.mdcCursor rule
- .cursor/rules/sdk/commit-and-pr-format.mdcCursor rule
- .cursor/rules/sdk/error-handling.mdcCursor rule
- .cursor/rules/sdk/first-class-product-parity.mdcCursor rule
- .cursor/rules/sdk/main.mdcCursor rule
- .cursor/rules/sdk/public-constants-contract.mdcCursor rule
- .cursor/rules/sdk/request-lifecycle-primitives.mdcCursor rule
- .cursor/rules/sdk/sdk-pod-packages.mdcCursor rule
- .cursor/rules/sdk/skill-authoring-guidelines.mdcCursor rule
- cpp-string-api-reviewSkill
- qv-addon-changelogSkill
- qv-addon-pr-createSkill
- qv-addon-release-notesSkill
- qv-agent-stack-syncSkill
- qv-asana-syncSkill
- qv-daily-work-updateSkill
- qv-dev-diary-setupSkill
- qv-dev-diarySkill
- qv-devops-daily-updateSkill
- qv-devops-pr-createSkill
- qv-devops-pr-reviewSkill
- qv-devops-pr-statusSkill
- qv-devops-runner-queueSkill
- qv-devops-why-my-pr-notSkill
- qv-docs-solution-createSkill
- qv-docs-updateSkill
- qv-holepunch-devSkill
- qv-merge-guard-wireSkill
- qv-mobile-test-dispatchSkill
- qv-notice-generateSkill
- qv-pr-mineSkill
- qv-pr-reviewSkill
- qv-pr-testSkill
- qv-qip-createSkill
- qv-qip-reviewSkill
- qv-qip-triageSkill
- qv-quality-reportingSkill
- qv-registry-autobase-patternsSkill
- qv-release-trainSkill
- qv-sdk-backmergeSkill
- qv-sdk-changelogSkill
- qv-sdk-e2e-createSkill
- qv-sdk-inference-versionSkill
- qv-sdk-pr-createSkill
- qv-sdk-pr-statusSkill
- qv-sdk-update-modelsSkill
- qv-skill-listSkill
- setupSkill
- setupSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

