From 2db050125dcd4d2f112cf1d709c17f8548c7f690 Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Sun, 2 Aug 2026 15:45:53 +0200 Subject: [PATCH] chore: adopt the shared skill template Brings .github/ in line with netresearch/.github/templates/skill and adds .github/template.yaml, so the template drift check applies from now on. This repo carried an older generation of the shared workflows: they predate the top-level `permissions: {}` block and, in release.yml, the id-token and attestations scopes that Sigstore signing and the GitHub attestation API require. Every affected file existed here in exactly one revision shared with the other skill repos, so this is a generation gap rather than local customisation. Added: template.yaml labeler.yml check-template-drift.yml labeler.yml scorecard.yml Replaced: zizmor.yml dependabot.yml release.yml security.yml lint.yml auto-merge-deps.yml harness-verify.yml eval-validate.yml Signed-off-by: Sebastian Mendel --- .github/dependabot.yml | 46 +++++++++++++++++++++- .github/labeler.yml | 23 +++++++++++ .github/template.yaml | 20 ++++++++++ .github/workflows/auto-merge-deps.yml | 5 ++- .github/workflows/check-template-drift.yml | 18 +++++++++ .github/workflows/eval-validate.yml | 9 ++++- .github/workflows/harness-verify.yml | 9 ++++- .github/workflows/labeler.yml | 17 ++++++++ .github/workflows/lint.yml | 10 ++++- .github/workflows/release.yml | 12 +++++- .github/workflows/scorecard.yml | 23 +++++++++++ .github/workflows/security.yml | 14 +++++-- .github/zizmor.yml | 5 ++- 13 files changed, 194 insertions(+), 17 deletions(-) create mode 100644 .github/labeler.yml create mode 100644 .github/template.yaml create mode 100644 .github/workflows/check-template-drift.yml create mode 100644 .github/workflows/labeler.yml create mode 100644 .github/workflows/scorecard.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6c5049e..2d559bb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,10 +1,52 @@ +# Managed by netresearch/.github/templates/skill/ +# +# Declares only the ecosystems every skill consumer is guaranteed to have: +# github-actions (CI workflows) and composer (every skill repo ships a +# composer.json for split-licensing / Packagist distribution). +# +# npm and devcontainers are OPT-IN: a repo that actually has package.json +# fixtures (e.g. skills//references/examples/**) or a devcontainer adds +# the block below to its own dependabot.yml and lists `.github/dependabot.yml` +# under `intentional-drift:` in .github/template.yaml so the template sync +# stops managing the file. Declaring an ecosystem without its manifest makes +# the Dependabot run fail with `dependency_file_not_found`. +# +# Opt-in npm (use Dependabot's plural `directories:` to consolidate multiple +# fixture dirs into one grouped PR): +# - package-ecosystem: npm +# directories: +# - /skills//references/examples/ +# schedule: +# interval: weekly +# day: monday +# open-pull-requests-limit: 5 +# groups: +# npm: +# patterns: ['*'] +# cooldown: +# default-days: 7 version: 2 updates: - package-ecosystem: github-actions directory: / schedule: interval: weekly + day: monday + open-pull-requests-limit: 5 groups: github-actions: - patterns: - - "*" + patterns: ['*'] + cooldown: + default-days: 7 + + - package-ecosystem: composer + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 + groups: + composer: + patterns: ['*'] + cooldown: + default-days: 7 diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000..12d2e0b --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,23 @@ +documentation: + - changed-files: + - any-glob-to-any-file: ['**/*.md', 'docs/**/*', '**/SKILL.md', 'README.md'] +ci: + - changed-files: + - any-glob-to-any-file: ['.github/**/*', 'Makefile'] +dependencies: + - changed-files: + - any-glob-to-any-file: + - 'composer.json' + - 'composer.lock' + - 'package.json' + - 'package-lock.json' + - 'bun.lock' + - 'bun.lockb' + - 'yarn.lock' + - '.devcontainer/**/*' +skill: + - changed-files: + - any-glob-to-any-file: ['skills/**/*', '.claude-plugin/**/*', 'plugin.json'] +evals: + - changed-files: + - any-glob-to-any-file: ['**/evals/**/*', '**/eval/**/*', '**/*.eval.yaml', '**/*.eval.yml'] diff --git a/.github/template.yaml b/.github/template.yaml new file mode 100644 index 0000000..53bcc09 --- /dev/null +++ b/.github/template.yaml @@ -0,0 +1,20 @@ +# Managed by netresearch/.github/templates/skill/ +# Drift from the template is blocking CI in this repo (check-template-drift.yml). +# Record explicit exceptions under intentional-drift[] to unblock. +# +# CodeQL: skill repos use GitHub **CodeQL default setup** (a repo setting, +# enabled via Settings > Code security, or `gh api -X PUT +# repos///code-scanning/default-setup -f state=configured`). +# Default setup auto-detects the repo's interpreted languages and conflicts +# with an advanced codeql.yml workflow — so this template intentionally ships +# NO codeql.yml. Scorecard (scorecard.yml) is separate and IS templated. +# +# Common opt-ins for skill repos (list the file here so the template sync +# stops managing it, then customize it in-repo): +# - .github/workflows/validate-agents.yml (only for skills that ship an +# AGENTS.md generator under skills//scripts; the reusable's +# scripts-path input is repo-specific so this is never byte-identical) +# - .github/dependabot.yml (when the repo has npm fixtures/devcontainers +# beyond the guaranteed github-actions + composer ecosystems) +template: skill +intentional-drift: [] diff --git a/.github/workflows/auto-merge-deps.yml b/.github/workflows/auto-merge-deps.yml index d8de1b3..6b6c8ad 100644 --- a/.github/workflows/auto-merge-deps.yml +++ b/.github/workflows/auto-merge-deps.yml @@ -1,7 +1,10 @@ name: Auto-merge dependency PRs on: - pull_request_target: + # auto-merge only calls `gh pr merge` via the reusable with the base-repo + # token; it never checks out or runs PR head code, so pull_request_target + # (required for a write token on Dependabot/Renovate fork PRs) is safe here. + pull_request_target: # zizmor: ignore[dangerous-triggers] permissions: {} diff --git a/.github/workflows/check-template-drift.yml b/.github/workflows/check-template-drift.yml new file mode 100644 index 0000000..d7617f8 --- /dev/null +++ b/.github/workflows/check-template-drift.yml @@ -0,0 +1,18 @@ +name: Template Drift + +on: + pull_request: + branches: [main] + push: + branches: [main] + merge_group: + +permissions: {} + +jobs: + drift: + uses: netresearch/.github/.github/workflows/check-template-drift.yml@main + with: + template: skill + permissions: + contents: read diff --git a/.github/workflows/eval-validate.yml b/.github/workflows/eval-validate.yml index 6f02cd1..54b335c 100644 --- a/.github/workflows/eval-validate.yml +++ b/.github/workflows/eval-validate.yml @@ -1,13 +1,18 @@ name: Eval Validation +# Runs the skill's eval suite via the skill-repo-skill reusable. The reusable +# declares `permissions: contents: read` at top level (read-only validator); +# the calling job mirrors it explicitly. + on: push: branches: [main] pull_request: -permissions: - contents: read +permissions: {} jobs: eval-validate: uses: netresearch/skill-repo-skill/.github/workflows/eval-validate.yml@main + permissions: + contents: read diff --git a/.github/workflows/harness-verify.yml b/.github/workflows/harness-verify.yml index 17668cd..773a929 100644 --- a/.github/workflows/harness-verify.yml +++ b/.github/workflows/harness-verify.yml @@ -1,12 +1,17 @@ name: Harness Verification +# Verifies agent-harness consistency (AGENTS.md index, docs drift) via the +# skill-repo-skill reusable. The reusable declares `permissions: contents: +# read` at top level (read-only validator); the calling job mirrors it. + on: pull_request: branches: [main] -permissions: - contents: read +permissions: {} jobs: harness-verify: uses: netresearch/skill-repo-skill/.github/workflows/harness-verify.yml@main + permissions: + contents: read diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000..f8a5853 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,17 @@ +name: Labeler + +on: + # labeler only applies labels via the reusable using the base-repo token; it + # never checks out or runs PR head code. pull_request_target is required to + # label fork PRs. + pull_request_target: # zizmor: ignore[dangerous-triggers] + types: [opened, synchronize, reopened] + +permissions: {} + +jobs: + labeler: + uses: netresearch/.github/.github/workflows/labeler.yml@main + permissions: + contents: read + pull-requests: write diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fbb14df..976e342 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,14 +1,20 @@ name: Lint +# Skill validation (SKILL.md word cap, plugin.json schema, markdown lint, …) +# via the skill-repo-skill reusable. The reusable declares `permissions: +# contents: read` at top level; the calling job mirrors it explicitly so the +# grant is visible at the call site and independent of the repo default. + on: push: branches: [main] pull_request: -permissions: - contents: read +permissions: {} jobs: validate: name: Skill Validation uses: netresearch/skill-repo-skill/.github/workflows/validate.yml@main + permissions: + contents: read diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d7c4cf..11a604a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,14 +1,22 @@ name: Release +# Skill release pipeline (composer/npm package publish + Sigstore cosign + +# SHA256SUMS attestation) via the skill-repo-skill reusable. The reusable's +# release job declares contents/id-token/attestations: write; the calling job +# grants exactly that union. id-token + attestations are required for the +# OIDC-backed Sigstore signing and the GitHub native attestation API. + on: push: tags: - 'v*' +permissions: {} + jobs: release: uses: netresearch/skill-repo-skill/.github/workflows/release.yml@main permissions: contents: write # release upload - id-token: write # OIDC for sigstore (required by the attest job) - attestations: write # GitHub native attestation API (required by the attest job) + id-token: write # OIDC for sigstore (cosign + attest) + attestations: write # GitHub native attestation API diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..d43143e --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,23 @@ +name: OpenSSF Scorecard + +# Closes the skill-repo security gap: supply-chain posture scoring (branch +# protection, pinned actions, token permissions, …). Runs on default-branch +# push and on a weekly schedule; results upload to the code-scanning dashboard. + +on: + push: + branches: [main] + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: + +permissions: {} + +jobs: + scorecard: + uses: netresearch/.github/.github/workflows/scorecard.yml@main + permissions: + contents: read + security-events: write + id-token: write + actions: read diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index fcf498e..c3e0b7e 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -1,9 +1,15 @@ name: Security -# Aggregated security scans for skill repos: secret scanning (betterleaks), -# workflow static analysis (zizmor), dependency review on PRs, and a composer -# audit (every skill repo ships a composer.json for split-licensing / -# Packagist distribution). +# Aggregated security scans for skill repos: +# gitleaks — secret scanning. The job and the reusable keep the +# historical `gitleaks` name; the scan itself runs +# betterleaks, which is OSS and needs no license. +# zizmor — static analysis of this repo's own workflows. +# dependency-review — on pull requests only. +# composer-audit — `composer audit` AND an Opengrep SAST scan; the called +# reusable runs both unless skip-opengrep is set. Every +# skill repo ships a composer.json for split-licensing / +# Packagist distribution. # # Top-level `permissions: {}` denies everything by default; each reusable # caller job re-declares the exact union its reusable's jobs require, so the diff --git a/.github/zizmor.yml b/.github/zizmor.yml index b9d8464..5ba7884 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -6,8 +6,9 @@ rules: unpinned-uses: config: policies: - # First-party reusable workflows track @main by policy and are - # never SHA-pinned, so fixes propagate to all consumers. + # First-party `uses:` — reusable workflows AND composite actions — + # track @main by policy and are never SHA-pinned, so a fix propagates + # to every consumer without a bump in dozens of repos. "netresearch/*": ref-pin # Everything else must be pinned to a full commit SHA. "*": hash-pin