Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .yamllint.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
extends: default
rules:
line-length: {max: 160}
# Bumped to 280 to accommodate single-line brace-expansion targets in
# checkpoints.yaml (e.g. GH-02 enumerates ~24 LICENSE filenames). The
# checkpoint runner does not unfold YAML folded scalars (`>-`) for
# `target:` fields — its parser is bash regex, not a real YAML parser —
# so these long enumerations cannot be wrapped.
line-length: {max: 360}
truthy: {allowed-values: ['true', 'false', 'on']}
document-start: disable
122 changes: 57 additions & 65 deletions skills/github-project/checkpoints.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,49 @@ mechanical:
severity: error
desc: "README.md must exist"

# Brace expansion covers SPDX-style split-license filenames common in
# multi-licence skill repos plus the GNU COPYING convention. Single line
# because the runner's YAML parser doesn't unfold `>-` folded scalars
# for `target:` fields (it's bash regex, not a real YAML parser).
- id: GH-02
type: file_exists
target: LICENSE
target: "{LICENSE,LICENSE.md,LICENSE.txt,COPYING,COPYING.md,COPYING.txt,LICENSE-MIT,LICENSE-APACHE,LICENSE-APACHE-2.0,LICENSE-BSD,LICENSE-BSD-2-Clause,LICENSE-BSD-3-Clause,LICENSE-CC-BY-SA-4.0,LICENSE-CC0-1.0,LICENSE-GPL,LICENSE-GPL-2.0,LICENSE-GPL-3.0,LICENSE-LGPL,LICENSE-LGPL-3.0,LICENSE-AGPL,LICENSE-AGPL-3.0,LICENSE-MPL,LICENSE-MPL-2.0}"
severity: error
desc: "LICENSE file must exist"
desc: >-
LICENSE file must exist. Accepts split-license naming (LICENSE-MIT,
LICENSE-CC-BY-SA-4.0, etc.) and the GNU COPYING convention.

- id: GH-03
type: file_exists
target: SECURITY.md
severity: warning
desc: "SECURITY.md should exist for vulnerability reporting"
target: "{SECURITY.md,.github/SECURITY.md,docs/SECURITY.md}"
severity: info
desc: "SECURITY.md should exist for vulnerability reporting (satisfied org-wide if the GitHub owner has a `.github` repo providing these files)"

- id: GH-04
type: file_exists
target: CONTRIBUTING.md
severity: warning
desc: "CONTRIBUTING.md should exist"
target: "{CONTRIBUTING.md,.github/CONTRIBUTING.md,docs/CONTRIBUTING.md}"
severity: info
desc: "CONTRIBUTING.md should exist (satisfied org-wide if the GitHub owner has a `.github` repo providing these files)"

- id: GH-05
type: file_exists
target: .github/CODEOWNERS
target: "{.github/CODEOWNERS,CODEOWNERS,docs/CODEOWNERS}"
severity: warning
desc: "CODEOWNERS should exist for review assignments"
desc: >-
CODEOWNERS must exist in the repository itself for GitHub to assign
reviewers (only `.github/`, root, or `docs/` on the default branch are
recognised). Org-wide `.github` does NOT satisfy CODEOWNERS — that
mechanism only provides templates and community-health files, not
review-routing rules.

- id: GH-06
type: command
target: "test -f .github/dependabot.yml || test -f renovate.json || test -f .github/renovate.json || test -f .renovaterc.json || test -f .renovaterc"
type: file_exists
target: "{.github/dependabot.yml,.github/dependabot.yaml,renovate.json,renovate.json5,.github/renovate.json,.github/renovate.json5,.renovaterc.json,.renovaterc.json5,.renovaterc}"
severity: warning
desc: "Dependency update automation should be configured (Dependabot or Renovate)"
desc: >-
Dependency update automation should be configured (Dependabot or
Renovate). Accepts both .yml/.yaml for Dependabot and .json/.json5
for Renovate.

- id: GH-07
type: file_exists
Expand Down Expand Up @@ -88,14 +102,14 @@ mechanical:
# === DEPENDABOT CHECKS ===
- id: GH-13
type: regex
target: .github/dependabot.yml
target: "{.github/dependabot.yml,.github/dependabot.yaml}"
pattern: 'package-ecosystem:\s*"?(composer|gomod|npm|pip)"?'
severity: warning
desc: "Dependabot should monitor language-specific dependencies (composer, gomod, npm, pip)"

- id: GH-14
type: regex
target: .github/dependabot.yml
target: "{.github/dependabot.yml,.github/dependabot.yaml}"
pattern: 'package-ecosystem:\s*"?github-actions"?'
severity: warning
desc: "Dependabot should monitor GitHub Actions"
Expand All @@ -120,14 +134,14 @@ mechanical:
# pattern as ER-19/20 in enterprise-readiness-skill PR #55.
- id: GH-19
type: regex
target: .github/workflows/*.yml
target: ".github/workflows/*.{yml,yaml}"
pattern: 'uses:[[:space:]]*github/codeql-action|uses:[[:space:]]*netresearch/[.]github/[.]github/workflows/codeql[.]yml'
severity: warning
desc: "CodeQL must be wired up (dedicated workflow or reusable-workflow job calling github/codeql-action or netresearch/.github/...codeql.yml)"

- id: GH-20
type: regex
target: .github/workflows/*.yml
target: ".github/workflows/*.{yml,yaml}"
pattern: 'uses:[[:space:]]*ossf/scorecard-action|uses:[[:space:]]*netresearch/[.]github/[.]github/workflows/scorecard[.]yml'
severity: info
desc: >-
Expand All @@ -137,15 +151,15 @@ mechanical:
# === SLSA PROVENANCE ===
- id: GH-21
type: regex_not
target: .github/workflows/*.yml
target: ".github/workflows/*.{yml,yaml}"
pattern: 'slsa-framework/slsa-github-generator'
severity: warning
desc: "Should migrate from slsa-github-generator to actions/attest-build-provenance (cannot be SHA-pinned)"

# === AUTO-MERGE WORKFLOW CHECKS ===
- id: GH-23
type: command
target: "test -f .github/workflows/auto-merge-deps.yml || test -f .github/workflows/auto-merge.yml"
type: file_exists
target: "{.github/workflows/auto-merge-deps.yml,.github/workflows/auto-merge.yml}"
Comment thread
CybotTM marked this conversation as resolved.
Comment thread
CybotTM marked this conversation as resolved.
severity: warning
desc: "Auto-merge workflow should exist for Dependabot/Renovate PRs"

Expand All @@ -167,28 +181,28 @@ mechanical:
# contain the netresearch/... substring identically).
- id: GH-24
type: regex
target: .github/workflows/auto-merge*.yml
target: ".github/workflows/auto-merge*.{yml,yaml}"
pattern: 'netresearch/\.github/\.github/workflows/auto-merge-deps\.yml|on:[[:space:]]*\n[[:space:]]*pull_request_target:'
severity: error
desc: "Auto-merge workflow must delegate to netresearch reusable workflow OR use pull_request_target trigger for bot PR write permissions"

- id: GH-25
type: regex
target: .github/workflows/auto-merge*.yml
target: ".github/workflows/auto-merge*.{yml,yaml}"
pattern: 'netresearch/\.github/\.github/workflows/auto-merge-deps\.yml|github\.event\.pull_request\.user\.login'
severity: warning
desc: "Auto-merge should delegate to reusable workflow OR check github.event.pull_request.user.login (not github.actor which changes on reruns)"

- id: GH-26
type: regex
target: .github/workflows/auto-merge*.yml
target: ".github/workflows/auto-merge*.{yml,yaml}"
pattern: 'netresearch/\.github/\.github/workflows/auto-merge-deps\.yml|--auto'
severity: warning
desc: "Auto-merge should delegate to reusable workflow OR use gh pr merge --auto to respect branch protection and merge queues"

- id: GH-27
type: regex
target: .github/workflows/auto-merge*.yml
target: ".github/workflows/auto-merge*.{yml,yaml}"
pattern: 'netresearch/\.github/\.github/workflows/auto-merge-deps\.yml|gh api.*repos/\$'
severity: info
desc: "Auto-merge should delegate to reusable workflow OR dynamically detect merge strategy from repo settings"
Expand All @@ -212,52 +226,30 @@ mechanical:
reviewDecision)

# === BRANCH PROTECTION AUDIT ===
# GH-30 / GH-31 require GitHub API access (gh CLI + auth) which is outside
# the assessment runner's command allowlist. Declared as type: gh_api so the
# runner skips them with a clear evidence string instead of rejecting them.
# The semantically equivalent LLM-driven audit lives in GH-32 (llm_reviews).
- id: GH-30
type: command
target: |
# Require GitHub CLI and a valid GitHub remote slug
command -v gh >/dev/null 2>&1 || exit 1
REPO_SLUG=$(git config --get remote.origin.url 2>/dev/null | sed -E 's|.*github\.com[:/](.+/[^.]+)(\.git)?$|\1|')
test -n "$REPO_SLUG" || exit 1
DEFAULT_BRANCH=$(gh api "repos/$REPO_SLUG" --jq '.default_branch' 2>/dev/null || echo 'main')
RESULT=$(gh api "repos/$REPO_SLUG/branches/$DEFAULT_BRANCH/protection" --jq '.enforce_admins.enabled' 2>/dev/null || echo '')
if [ "$RESULT" = "true" ]; then
exit 0
fi
# Fallback: check rulesets when classic branch protection is not configured
RULESET_OK=$(gh api "repos/$REPO_SLUG/rulesets" \
--jq 'map(select(.enforcement == "active" and .target == "branch" and ((.bypass_actors // []) | length == 0))) | any' \
2>/dev/null || echo 'false')
test "$RULESET_OK" = "true"
type: gh_api
endpoint: "repos/{owner}/{repo}/branches/{default_branch}/protection"
json_path: ".enforce_admins.enabled"
severity: error
desc: "enforce_admins must be true on default branch — without it admins can bypass required status checks and review requirements"
desc: >-
enforce_admins must be true on default branch — without it admins can
bypass required status checks and review requirements (audited by
GH-32 llm_review; runner skips because gh API access requires auth).

- id: GH-31
type: command
target: |
# Require GitHub CLI and a valid GitHub remote slug
command -v gh >/dev/null 2>&1 || exit 1
REPO_SLUG=$(git config --get remote.origin.url 2>/dev/null | sed -E 's|.*github\.com[:/](.+/[^.]+)(\.git)?$|\1|')
test -n "$REPO_SLUG" || exit 1
DEFAULT_BRANCH=$(gh api "repos/$REPO_SLUG" --jq '.default_branch' 2>/dev/null || echo 'main')
RESULT=$(gh api "repos/$REPO_SLUG/branches/$DEFAULT_BRANCH/protection" --jq '.required_conversation_resolution.enabled' 2>/dev/null || echo '')
if [ "$RESULT" = "true" ]; then
exit 0
fi
# Fallback: check rulesets for review thread resolution
JQ_FILTER='map(select(
.enforcement == "active" and .target == "branch"
and ((.bypass_actors // []) | length == 0)
and any(.rules[]?;
.type == "pull_request" and
(.parameters.required_review_thread_resolution // false)
)
)) | any'
RULESET_OK=$(gh api "repos/$REPO_SLUG/rulesets" \
--jq "$JQ_FILTER" 2>/dev/null || echo 'false')
test "$RULESET_OK" = "true"
type: gh_api
endpoint: "repos/{owner}/{repo}/branches/{default_branch}/protection"
json_path: ".required_conversation_resolution.enabled"
severity: error
desc: "required_conversation_resolution must be enabled — combined with enforce_admins, ensures unresolved review threads block ALL merges including admins"
desc: >-
required_conversation_resolution must be enabled — combined with
enforce_admins, ensures unresolved review threads block ALL merges
including admins (audited by GH-32 llm_review; runner skips because
gh API access requires auth).

llm_reviews:
# === BRANCH PROTECTION + MERGE QUEUE COMPATIBILITY ===
Expand Down
Loading