Skip to content

infra[notask]: consolidate 14 on-merge-<pkg>.yml native-addon publish workflows into on-merge-nx.yml - #3829

Draft
sidj-thr wants to merge 2 commits into
feature-on-pr-nxfrom
feature-on-merge-nx
Draft

infra[notask]: consolidate 14 on-merge-<pkg>.yml native-addon publish workflows into on-merge-nx.yml#3829
sidj-thr wants to merge 2 commits into
feature-on-pr-nxfrom
feature-on-merge-nx

Conversation

@sidj-thr

Copy link
Copy Markdown
Contributor

🎯 What problem does this PR solve?

  • 14 near-identical on-merge-<pkg>.yml native-addon publish workflows (asr-ggml, audiogen-ggml, bci-whispercpp, classification-ggml, decoder-audio, diffusion-cpp, embed-llamacpp, fabric, llm-llamacpp, ocr-ggml, onnx, translation-nmtcpp, tts-ggml, vla-ggml) duplicate the same release-merge-guard / prebuild / GPR / npm / create-tag job graph, each 180-580 lines, with real but scattered per-package divergence (build step, name-transform, token, repo_name/tag scheme, prebuild presence, post-publish test gating).

  • All 14 fold in — no carve-outs. Even the packages with real divergence (fabric's inline publish-logic + local npm composite, decoder-audio's total absence of prebuilds + pre-publish test gate, vla-ggml's stale slug/dir mismatch) reduce to config flags once normalized onto the shared qvac-actions and the existing nx leaves.

📝 How does it solves it?

  • Adds a single generic on-merge-nx.yml. dorny/paths-filter selects the changed package(s) on push (one package per changed dir, no nx-affected — that pulls in transitive dependents, which is wrong for publish). Per-package config (build step / name-transform / token / repo_name / test-gate mode) lives in a new on-merge carrier target on each package's project.json, read at runtime — safe because on-merge runs post-merge on its own ref, no fork-PR head/base split.

  • Prebuild and pre/post-publish tests route through the existing prebuilds-nx.yml / integration-test-nx.yml / integration-mobile-test-nx.yml leaves via a new explicit packages input on nx-project-matrix — when supplied, it bypasses nx show projects --affected entirely and builds the matrix from exactly those packages. Default [] is a no-op for every existing caller (on-pr-nx, the 4 leaves' own workflow_dispatch).

  • Release-branch identity gate (detect step): a release-* branch is named release-<package>-x.y.z and must publish exactly that package. Hard-fails on any mismatch — wrong package, extra package, zero packages, malformed branch name, unknown package dir — before anything builds. This closes a real gap in the existing release-merge-guard (kept unchanged): that guard's package-identity check is a warning only, it hard-fails on version/changelog instead, so a same-versioned sibling package with its own CHANGELOG touched in a later push on the same release branch could otherwise pass the guard and publish under someone else's release line. Verified against real release-branch history across the org repo — every package's current-convention release branches use the full package directory name (a couple of packages, e.g. vla-ggml, have older short-alias branches like release-vla-*, but those are strictly lower-versioned/stale; the highest-version branch for every package already uses the full dir name), so no alias-resolution layer is needed.

  • Post-build gate (OR over GPR/npm publish result, gating post-publish tests) is a single non-matrixed job — matrix-job outputs don't propagate reliably to dependent jobs in GitHub Actions, only a plain job's do.

  • Applies the same base: ${{ github.ref_name }} fix to the already-open trigger-reusable-lib.yml (infra[notask]: consolidate plain-shape library publish workflows #3748) and the same identity gate there — both had the same latent bug (dorny defaults to diffing against the default branch when base isn't set, and the same release-branch loophole applied).

  • Out of scope: on-merge-model-fit.yml (not a native-addon package).

🧪 How was it tested?

  • actionlint clean on the new workflow and every modified leaf/action (only pre-existing shellcheck style/info findings and the known composite-action false-positive syntax-check noise).
  • Local parity simulation: the detect step's package-row compute logic run directly against all 14 real project.json files — every row matches the intended config table exactly (build step, name-transform, token, repo_name/useVTag, test-gate mode).
  • Live diagnostic runs on a scoped tmp-* branch (dorny base fix required a real push-delta to exercise correctly — verified empirically, not just by inspection):
    • Single-package run (asr-ggml): detect selected exactly one package; Prebuild (asr-ggml) compiled all platform legs for real via prebuilds-nx.yml with the explicit packages input; Publish GPR (asr-ggml) succeeded for real; Publish NPM (asr-ggml) was reached and correctly skipped (release-gated, not a release-* branch) — proved npm cannot fire off a non-release branch.
    • Two-package run (asr-ggml + onnx): detect selected exactly the two changed packages, each fanned out to its own independent Prebuild/Publish GPR/Publish NPM job set (matrix-per-package, no cross-package coupling on selection). onnx's prebuild failed on its own pre-existing vcpkg build issue (unrelated to this change — asr-ggml's prebuild, on the identical code path, succeeded cleanly); this surfaced a real finding, since fixed: publish-gpr gates on the aggregate prebuild job result across the whole matrix, so one package's prebuild failure blocks GPR publish for every package in that push, not just the failing one — same behavior as the pre-consolidation legacy files would show if they shared a job, and accepted as correct (fail-safe) rather than reworked into fully independent per-package pipelines.
    • Identity gate unit-tested against 8 scenarios run locally (legit single-package push, the exact loophole — legit push to the branch's package followed by an illegitimate push to a different package on the same release branch — two-package push, zero-package push, hyphenated dir names, nonexistent package dir, malformed version suffix, non-release branch), all correct.
    • Every live/local test run was cancelled or cleaned up before reaching a real npm publish or git tag; no package version was actually published to npm and no release tag was created during testing.
  • nx show projects --affected against the diff base returns [] (config/workflow-only change).

🔐 Action pinning

  • dorny/paths-filter: fbd0ab8f3e69293af611ebaee6363fc25e6d187d # 4.0.1 (repo-standard pin, already used elsewhere)
  • tetherto/qvac-actions/npm-publish-logic, npm-dist-tag-determination, publish-library-to-npm: bbb0740e2a16b94371c7439e0e06945c5b68e759 # 0.3.0
  • actions/checkout, actions/setup-node, actions/download-artifact: unchanged repo-standard pins carried over from the files being replaced

🛡️ Permissions changes

Per-job permissions are carried over unchanged from the 14 deleted-in-spirit (not literally deleted this pass — additive) workflows; no new grant introduced.

  • Scope: job publish-gprcontents: read, packages: write
  • Scope: job publish-npmcontents: write, packages: write, id-token: write (OIDC)
  • Scope: prebuild / pre-publish-* / post-publish-* jobs — pass through whatever the called leaf (prebuilds-nx.yml, integration-test-nx.yml, integration-mobile-test-nx.yml) already declares, unchanged

@github-actions

Copy link
Copy Markdown
Contributor

License compliance — findings detected (warn-only)

Critical: 0 · High: 7 · Medium: 0

Dependency License Scope Severity Outcome
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd (none detected) runtime High blocks
actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c (none detected) runtime High blocks
actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f (none detected) runtime High blocks
dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d (none detected) runtime High blocks
tetherto/qvac-actions/npm-dist-tag-determination@bbb0740e2a16b94371c7439e0e06945c5b68e759 (none detected) runtime High blocks
tetherto/qvac-actions/npm-publish-logic@bbb0740e2a16b94371c7439e0e06945c5b68e759 (none detected) runtime High blocks
tetherto/qvac-actions/publish-library-to-npm@bbb0740e2a16b94371c7439e0e06945c5b68e759 (none detected) runtime High blocks

How to resolve a blocking finding:

  • Remove or replace the disallowed dependency, or
  • If the license is genuinely acceptable, run the compliance SKILL and record the decision in .github/license-allowlist.yml (CODEOWNERS-reviewed), or
  • For a one-off, a maintainer can apply the license-override label (High findings only; Critical cannot be overridden).

Warn-only (shadow) mode — this check does not block merges yet.

Updated automatically by the canonical license compliance workflow.

NOTICE presence (advisory)

Missing NOTICE (advisory, does not block):

  • ./.github/actions/release-merge-guard
  • ./packages/vla-ggml/sim/server
  • ./packages/asr-ggml/benchmarks/server
  • ./packages/embed-llamacpp/benchmarks/performance
  • ./packages/embed-llamacpp/benchmarks/server
  • ./packages/llm-llamacpp/benchmarks/performance
  • ./packages/llm-llamacpp/benchmarks/server
  • ./packages/ggml-coload-smoke
  • ./packages/sdk/e2e
  • ./packages/fabric/test/integration
  • ./docs/website

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Workflow security (shadow mode)

zizmor found 1146 finding(s) in .github/ (highest severity: high). This check is warn-only and does not block the merge.

Findings are annotated inline on the changed files and listed in the job summary.

Reproduce locally:

pipx run zizmor==1.27.0 --offline .github/

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