Node CI gold-standard checks — GitHub Actions workflow with lint/test jobs.
Ports the intent of the Python checks.ci to a node project: a CI workflow
that lints, type-checks, tests across a node-version matrix, and audits
dependencies. Reads .github/workflows/*.yml as text (the same lenient
substring approach the Python checks use — no YAML parse needed).
check_ci_dependabot(project)
Check: automated dependency updates are configured (dependabot/renovate).
Node analog of the Python ci.dependabot check.
Source code in packages/axm-init/src/axm_init/checks/node/ci.py
| Python |
|---|
| def check_ci_dependabot(project: Path) -> CheckResult:
"""Check: automated dependency updates are configured (dependabot/renovate).
Node analog of the Python ``ci.dependabot`` check.
"""
candidates = (
project / ".github" / "dependabot.yml",
project / ".github" / "dependabot.yaml",
project / "renovate.json",
project / ".github" / "renovate.json",
)
if any(p.is_file() for p in candidates):
return CheckResult(
name="ci.dependabot",
category="ci",
passed=True,
weight=2,
message="Automated dependency updates configured",
details=[],
fix="",
)
return CheckResult(
name="ci.dependabot",
category="ci",
passed=False,
weight=2,
message="No dependabot/renovate config",
details=[],
fix="Add .github/dependabot.yml (or renovate.json) for the npm ecosystem.",
)
|
check_ci_lint_job(project)
Check: CI runs lint / type-check.
Source code in packages/axm-init/src/axm_init/checks/node/ci.py
| Python |
|---|
| def check_ci_lint_job(project: Path) -> CheckResult:
"""Check: CI runs lint / type-check."""
content = _read_ci(project) or ""
lowered = content.lower()
if "lint" in lowered or "eslint" in lowered or "tsc" in lowered:
return CheckResult(
name="ci.ci_lint_job",
category="ci",
passed=True,
weight=3,
message="Lint job present",
details=[],
fix="",
)
return CheckResult(
name="ci.ci_lint_job",
category="ci",
passed=False,
weight=3,
message="No lint job in CI",
details=["CI should run eslint / tsc"],
fix="Add a lint job running `npm run lint` and `npm run typecheck`.",
)
|
check_ci_publish(project)
Check: a publish/release workflow with npm provenance.
Node analog of the Python ci.trusted_publishing check — a workflow that
publishes to npm, ideally with provenance (--provenance / id-token).
Source code in packages/axm-init/src/axm_init/checks/node/ci.py
| Python |
|---|
| def check_ci_publish(project: Path) -> CheckResult:
"""Check: a publish/release workflow with npm provenance.
Node analog of the Python ``ci.trusted_publishing`` check — a workflow that
publishes to npm, ideally with provenance (``--provenance`` / ``id-token``).
"""
content = _read_ci(project) or ""
lowered = content.lower()
has_publish = "npm publish" in lowered or "changeset" in lowered
if has_publish and ("provenance" in lowered or "id-token" in lowered):
return CheckResult(
name="ci.trusted_publishing",
category="ci",
passed=True,
weight=2,
message="Publish workflow with provenance",
details=[],
fix="",
)
return CheckResult(
name="ci.trusted_publishing",
category="ci",
passed=False,
weight=2,
message="No npm publish workflow with provenance",
details=["Publish to npm with provenance (id-token: write)"],
fix="Add a release workflow running `npm publish --provenance`.",
)
|
check_ci_security_job(project)
Check: CI runs a dependency-audit / security step.
Source code in packages/axm-init/src/axm_init/checks/node/ci.py
| Python |
|---|
| def check_ci_security_job(project: Path) -> CheckResult:
"""Check: CI runs a dependency-audit / security step."""
content = _read_ci(project) or ""
lowered = content.lower()
if "audit" in lowered or "codeql" in lowered or "security" in lowered:
return CheckResult(
name="ci.ci_security_job",
category="ci",
passed=True,
weight=2,
message="Security job present",
details=[],
fix="",
)
return CheckResult(
name="ci.ci_security_job",
category="ci",
passed=False,
weight=2,
message="No security/audit job in CI",
details=["CI should run `npm audit` or CodeQL"],
fix="Add a job running `npm audit --audit-level high`.",
)
|
check_ci_test_job(project)
Check: CI runs tests across a node-version matrix.
Source code in packages/axm-init/src/axm_init/checks/node/ci.py
| Python |
|---|
| def check_ci_test_job(project: Path) -> CheckResult:
"""Check: CI runs tests across a node-version matrix."""
content = _read_ci(project) or ""
lowered = content.lower()
has_test = "test" in lowered or "vitest" in lowered
has_matrix = "node-version" in lowered or "matrix" in lowered
if has_test and has_matrix:
return CheckResult(
name="ci.ci_test_job",
category="ci",
passed=True,
weight=3,
message="Matrix test job present",
details=[],
fix="",
)
return CheckResult(
name="ci.ci_test_job",
category="ci",
passed=False,
weight=3,
message="No matrix test job in CI",
details=["CI must run tests with a strategy.matrix.node-version"],
fix="Add a test job with strategy.matrix.node-version running `npm test`.",
)
|
check_ci_workflow_exists(project)
Check: a GitHub Actions workflow exists.
Source code in packages/axm-init/src/axm_init/checks/node/ci.py
| Python |
|---|
| def check_ci_workflow_exists(project: Path) -> CheckResult:
"""Check: a GitHub Actions workflow exists."""
if _read_ci(project) is not None:
return CheckResult(
name="ci.ci_workflow_exists",
category="ci",
passed=True,
weight=4,
message="CI workflow found",
details=[],
fix="",
)
return CheckResult(
name="ci.ci_workflow_exists",
category="ci",
passed=False,
weight=4,
message="CI workflow not found",
details=["Expected: .github/workflows/*.yml"],
fix="Create .github/workflows/ci.yml with lint, test, and audit jobs.",
)
|