Skip to content

CI Pipeline to verify skill counts match source repos - #3

Merged
mosheabr merged 4 commits into
NVIDIA:mainfrom
shljessie:add-ci-pipeline
Apr 7, 2026
Merged

CI Pipeline to verify skill counts match source repos#3
mosheabr merged 4 commits into
NVIDIA:mainfrom
shljessie:add-ci-pipeline

Conversation

@shljessie

@shljessie shljessie commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a GitHub Actions workflow that checks whether the skill counts listed in the README actually match the skill directories in each source repo
  • Queries each product repo's skills path via the GitHub API and compares the actual number of skill subdirectories against the count claimed in the Available Skills table
  • Outputs a clear drift report table showing expected vs. actual counts per product

Triggers

  • Pull requests to main — ensures README changes don't introduce incorrect counts
  • Daily schedule (08:00 UTC) — catches upstream repos adding/removing skills

@shljessie
shljessie requested a review from mosheabr as a code owner April 6, 2026 19:08
@mosheabr mosheabr self-assigned this Apr 6, 2026

@mosheabr mosheabr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Review: Request Changes

Great idea — automated drift detection is exactly what this catalog needs. A few issues to address before merging:

1. NeMo Evaluator has skills in two paths (will report wrong count)

The workflow only checks packages/nemo-evaluator-launcher/.claude/skills (3 skills) but NeMo Evaluator also has skills at packages/nemo-evaluator/.claude/skills (1 skill: byob). The expected count is 4, but the CI will find 3 and report drift.

Fix: Either add a second entry for the second path, or sum both paths for NeMo Evaluator.

2. sed pattern won't match README labels

The sed command uses labels like Megatron-Core and Megatron-Bridge (with hyphens), but the README uses Megatron Core and Megatron Bridge (with spaces inside **bold** markers). The regex \*\*${label}\*\* won't match.

Fix: Use the display name with spaces in the label field, or adjust the sed pattern.

3. GITHUB_TOKEN may not access private source repos

Several source repos (Model-Optimizer, Megatron-LM, etc.) may be private or have restricted access. The default GITHUB_TOKEN only has permissions for the repo the workflow runs in. The gh api calls to other repos may return 404.

Fix: May need a PAT or GitHub App token with cross-repo read access stored as a repo secret.

4. Permissions are broader than needed for PR checks

permissions: contents: write, pull-requests: write grants write access on every trigger, but PR checks only need read. The write permissions are only needed for the scheduled auto-fix path.

Suggestion: Consider splitting into two jobs — a read-only check job (runs on PRs) and a write job (runs on schedule/dispatch only).


The concept is solid. Issues #1 and #2 will cause false drift reports on day one, so those should be fixed before merge.

Signed-off-by: Seonghee Lee <seongheel@nvidia.com>
Signed-off-by: Seonghee Lee <seongheel@nvidia.com>
Signed-off-by: Seonghee Lee <seongheel@nvidia.com>
Signed-off-by: Seonghee Lee <seongheel@nvidia.com>

@mosheabr mosheabr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Updated Review

Thanks for the fixes — the split permissions, NeMo Evaluator dual-path handling, and private repo token fallback all look good. Three of the four original issues are resolved. ✓

Remaining issue: Product names should not be hyphenated in README

The latest commit changes display names in the README from spaces to hyphens:

  • "Model Optimizer" → "Model-Optimizer"
  • "Megatron Core" → "Megatron-Core"
  • "Megatron Bridge" → "Megatron-Bridge"

This was done to make the sed pattern matching work in the CI, but it introduces inconsistency — every other product uses natural names with spaces (cuOpt, TensorRT-LLM, Nemotron Voice Agent, NeMo Gym, NeMo Evaluator).

The fix-drift job already has the right approach with escaped_label using sed 's/ /[[:space:]]/g'. Apply the same escaping in the check job's label definitions and keep the README display names with spaces.

In short: fix the CI to handle spaces, don't change the README to match the CI.

@shljessie

Copy link
Copy Markdown
Contributor Author

The hyphens are actually correct for these products (Megatron-LM, Megatron-Bridge, Model-Optimizer) so I've updated the README.md to match the official repo names.

This is different from products like "Nemotron Voice Agent" or "NeMo Evaluator" where the display name may use spaces. Not under our org so I'm not sure what the convention is here.

@shljessie
shljessie requested a review from mosheabr April 7, 2026 17:46

@mosheabr mosheabr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving — the CI pipeline logic is solid and addresses the key issues (split permissions, dual-path NeMo Evaluator, private repo token fallback).

Note: The hyphenated product names in README (Model-Optimizer, Megatron-Core, Megatron-Bridge) are inconsistent with other entries that use spaces, but we can fix that in a follow-up. Not blocking.

@mosheabr
mosheabr merged commit b4512d2 into NVIDIA:main Apr 7, 2026
mosheabr added a commit that referenced this pull request May 28, 2026
Restructure to one-entry-per-skill (flat-layout convention adopted
2026-05-28 — skills land at skills/<skill-name>/ top level). Add
links.discussions: false since NVIDIA-AI-IOT/DeepStream_Coding_Agent
has Discussions disabled.

Source repo is fully 5/5 compliant as of Unni's PR #3 today (sig +
skill-card + evals.json + BENCHMARK.md for both deepstream-dev and
deepstream-import-vision-model). DeepStream is the second component
to reach full artifact compliance after Skill Card Generator.

Next sync will land both skills flat at skills/deepstream-dev/ and
skills/deepstream-import-vision-model/.

Signed-off-by: Moshe Abramovitch <moshea@nvidia.com>
mosheabr added a commit that referenced this pull request Jun 4, 2026
#2 (MED) — gh issue create can skip tracker on bad assignee:
  The "Track dropped skills" step has continue-on-error: true, so a
  bad assignee wouldn't kill the whole sync — but it would skip
  tracker creation entirely, defeating the feature. Both branches
  (edit existing / create new) now follow the same tolerant pattern:
  create-without-assignees first, then loop --add-assignee in a
  trim + per-handle warning. A typo in CATALOG_TRACKER_ASSIGNEES no
  longer blocks the tracker from existing.

#3 (LOW) — Hardcoded personal fallback:
  Reworked per Codex's catch that GitHub issue assignees are users,
  not teams — so the earlier "use a team handle" comment was wrong.
  If CATALOG_TRACKER_ASSIGNEES is unset we now skip assignment
  entirely and emit a ::warning title=Drift notifications inactive::.
  No personal fallback; a deactivated handle would silently mute
  notifications. The warning surfaces in the workflow log every run
  until the secret is set.

#4 (LOW / clarification) — Deleted-sig case:
  Added an inline comment in the drift loop noting that an rsync
  that deletes skill.oms.sig alongside content edits registers the
  deletion in `git diff` (sig_changed matches → drift NOT flagged
  here), and the now-sigless skill falls through to the compliance
  step under "missing artifacts: skill.oms.sig". Defense in depth.

#1 (HIGH per Sayali) — README version inconsistency on revert:
  NOT addressed in this commit — verified against
  .github/scripts/regenerate-readme.sh on main: the README table
  is now "Product | Description | Skills" (PR #215, commit 1104de0
  on 2026-06-01 dropped the Source + Version columns). VERSIONS_FILE
  is declared but never consumed, and /tmp/sync-versions.txt is
  vestigial. So the exact "README will lie" risk Sayali raised is
  stale. Plan to send her the context separately and open a small
  follow-up PR to drop the dead sync-versions write + VERSIONS_FILE
  declaration so this trap doesn't catch a future reader.

Signed-off-by: Moshe Abramovitch <moshea@nvidia.com>
mosheabr added a commit that referenced this pull request Jun 8, 2026
#2 (MED) — gh issue create can skip tracker on bad assignee:
  The "Track dropped skills" step has continue-on-error: true, so a
  bad assignee wouldn't kill the whole sync — but it would skip
  tracker creation entirely, defeating the feature. Both branches
  (edit existing / create new) now follow the same tolerant pattern:
  create-without-assignees first, then loop --add-assignee in a
  trim + per-handle warning. A typo in CATALOG_TRACKER_ASSIGNEES no
  longer blocks the tracker from existing.

#3 (LOW) — Hardcoded personal fallback:
  Reworked per Codex's catch that GitHub issue assignees are users,
  not teams — so the earlier "use a team handle" comment was wrong.
  If CATALOG_TRACKER_ASSIGNEES is unset we now skip assignment
  entirely and emit a ::warning title=Drift notifications inactive::.
  No personal fallback; a deactivated handle would silently mute
  notifications. The warning surfaces in the workflow log every run
  until the secret is set.

#4 (LOW / clarification) — Deleted-sig case:
  Added an inline comment in the drift loop noting that an rsync
  that deletes skill.oms.sig alongside content edits registers the
  deletion in `git diff` (sig_changed matches → drift NOT flagged
  here), and the now-sigless skill falls through to the compliance
  step under "missing artifacts: skill.oms.sig". Defense in depth.

#1 (HIGH per Sayali) — README version inconsistency on revert:
  NOT addressed in this commit — verified against
  .github/scripts/regenerate-readme.sh on main: the README table
  is now "Product | Description | Skills" (PR #215, commit 1104de0
  on 2026-06-01 dropped the Source + Version columns). VERSIONS_FILE
  is declared but never consumed, and /tmp/sync-versions.txt is
  vestigial. So the exact "README will lie" risk Sayali raised is
  stale. Plan to send her the context separately and open a small
  follow-up PR to drop the dead sync-versions write + VERSIONS_FILE
  declaration so this trap doesn't catch a future reader.

Signed-off-by: Moshe Abramovitch <moshea@nvidia.com>
mosheabr added a commit that referenced this pull request Jun 8, 2026
#2 (MED) — gh issue create can skip tracker on bad assignee:
  The "Track dropped skills" step has continue-on-error: true, so a
  bad assignee wouldn't kill the whole sync — but it would skip
  tracker creation entirely, defeating the feature. Both branches
  (edit existing / create new) now follow the same tolerant pattern:
  create-without-assignees first, then loop --add-assignee in a
  trim + per-handle warning. A typo in CATALOG_TRACKER_ASSIGNEES no
  longer blocks the tracker from existing.

#3 (LOW) — Hardcoded personal fallback:
  Reworked per Codex's catch that GitHub issue assignees are users,
  not teams — so the earlier "use a team handle" comment was wrong.
  If CATALOG_TRACKER_ASSIGNEES is unset we now skip assignment
  entirely and emit a ::warning title=Drift notifications inactive::.
  No personal fallback; a deactivated handle would silently mute
  notifications. The warning surfaces in the workflow log every run
  until the secret is set.

#4 (LOW / clarification) — Deleted-sig case:
  Added an inline comment in the drift loop noting that an rsync
  that deletes skill.oms.sig alongside content edits registers the
  deletion in `git diff` (sig_changed matches → drift NOT flagged
  here), and the now-sigless skill falls through to the compliance
  step under "missing artifacts: skill.oms.sig". Defense in depth.

#1 (HIGH per Sayali) — README version inconsistency on revert:
  NOT addressed in this commit — verified against
  .github/scripts/regenerate-readme.sh on main: the README table
  is now "Product | Description | Skills" (PR #215, commit 1104de0
  on 2026-06-01 dropped the Source + Version columns). VERSIONS_FILE
  is declared but never consumed, and /tmp/sync-versions.txt is
  vestigial. So the exact "README will lie" risk Sayali raised is
  stale. Plan to send her the context separately and open a small
  follow-up PR to drop the dead sync-versions write + VERSIONS_FILE
  declaration so this trap doesn't catch a future reader.

Signed-off-by: Moshe Abramovitch <moshea@nvidia.com>
sayalinvidia pushed a commit that referenced this pull request Jul 15, 2026
…er issue

Two gaps let internally inconsistent skills publish and sit unnoticed:

1. The sync's drift detection only caught content changed WITHOUT a sig
   refresh. When content and signature changed together it trusted the
   pair blindly — and bot sync PRs run no CI, so nothing downstream
   verified them either. Seven skills published with content that fails
   signature verification this way. Defense #3 now digest-verifies every
   rsynced skill whose signature changed, and holds (revert/drop) any
   whose incoming content does not match its own incoming signature,
   with a 'sig mismatch' category in the PR body and tracker issue.

2. The daily full-catalog integrity sweep failed silently for a week —
   scheduled workflow failures alert no one. The sweep now maintains a
   rolling tracker issue (label: integrity-failure) with the finding
   list and owner recovery steps, and auto-closes it when a sweep
   passes.

Signed-off-by: Moshe Abramovitch <moshea@nvidia.com>
melo-gonzo pushed a commit to melo-gonzo/NVIDIAskills that referenced this pull request Aug 5, 2026
NVIDIA#2 (MED) — gh issue create can skip tracker on bad assignee:
  The "Track dropped skills" step has continue-on-error: true, so a
  bad assignee wouldn't kill the whole sync — but it would skip
  tracker creation entirely, defeating the feature. Both branches
  (edit existing / create new) now follow the same tolerant pattern:
  create-without-assignees first, then loop --add-assignee in a
  trim + per-handle warning. A typo in CATALOG_TRACKER_ASSIGNEES no
  longer blocks the tracker from existing.

NVIDIA#3 (LOW) — Hardcoded personal fallback:
  Reworked per Codex's catch that GitHub issue assignees are users,
  not teams — so the earlier "use a team handle" comment was wrong.
  If CATALOG_TRACKER_ASSIGNEES is unset we now skip assignment
  entirely and emit a ::warning title=Drift notifications inactive::.
  No personal fallback; a deactivated handle would silently mute
  notifications. The warning surfaces in the workflow log every run
  until the secret is set.

NVIDIA#4 (LOW / clarification) — Deleted-sig case:
  Added an inline comment in the drift loop noting that an rsync
  that deletes skill.oms.sig alongside content edits registers the
  deletion in `git diff` (sig_changed matches → drift NOT flagged
  here), and the now-sigless skill falls through to the compliance
  step under "missing artifacts: skill.oms.sig". Defense in depth.

NVIDIA#1 (HIGH per Sayali) — README version inconsistency on revert:
  NOT addressed in this commit — verified against
  .github/scripts/regenerate-readme.sh on main: the README table
  is now "Product | Description | Skills" (PR NVIDIA#215, commit 1104de0
  on 2026-06-01 dropped the Source + Version columns). VERSIONS_FILE
  is declared but never consumed, and /tmp/sync-versions.txt is
  vestigial. So the exact "README will lie" risk Sayali raised is
  stale. Plan to send her the context separately and open a small
  follow-up PR to drop the dead sync-versions write + VERSIONS_FILE
  declaration so this trap doesn't catch a future reader.

Signed-off-by: Moshe Abramovitch <moshea@nvidia.com>
Signed-off-by: Carmelo Gonzales <43048528+melo-gonzo@users.noreply.github.com>
melo-gonzo pushed a commit to melo-gonzo/NVIDIAskills that referenced this pull request Aug 5, 2026
…er issue

Two gaps let internally inconsistent skills publish and sit unnoticed:

1. The sync's drift detection only caught content changed WITHOUT a sig
   refresh. When content and signature changed together it trusted the
   pair blindly — and bot sync PRs run no CI, so nothing downstream
   verified them either. Seven skills published with content that fails
   signature verification this way. Defense NVIDIA#3 now digest-verifies every
   rsynced skill whose signature changed, and holds (revert/drop) any
   whose incoming content does not match its own incoming signature,
   with a 'sig mismatch' category in the PR body and tracker issue.

2. The daily full-catalog integrity sweep failed silently for a week —
   scheduled workflow failures alert no one. The sweep now maintains a
   rolling tracker issue (label: integrity-failure) with the finding
   list and owner recovery steps, and auto-closes it when a sweep
   passes.

Signed-off-by: Moshe Abramovitch <moshea@nvidia.com>
Signed-off-by: Carmelo Gonzales <43048528+melo-gonzo@users.noreply.github.com>
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.

2 participants