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
28 changes: 28 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# CodeQL on this repository's own Python and Actions sources. Self-application:
# ci-workflows ships this capability to the estate, so it must consume it too.
# Self-references stay relative; only external consumers pin by full SHA.
name: codeql

on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "0 5 * * 1"

permissions: {}

concurrency:
group: codeql-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
codeql:
permissions:
actions: read # read workflow run metadata for the actions analysis
contents: read
security-events: write # upload CodeQL SARIF to the Security tab
uses: ./.github/workflows/public-codeql.yml
with:
languages: '["python","actions"]'
17 changes: 17 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Dependency Review — pull_request only, free on public repositories.
name: dependency-review

on:
pull_request:
branches: [main]

permissions: {}

jobs:
dependency-review:
permissions:
contents: read
pull-requests: write # post the dependency review summary on the PR
uses: ./.github/workflows/public-dependency-review.yml
with:
fail_on_severity: moderate
21 changes: 21 additions & 0 deletions .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Gitleaks over this repository's own history. Named gitleaks.yml because
# secret-scan.yml is the reusable definition itself.
name: gitleaks

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions: {}

concurrency:
group: gitleaks-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
gitleaks:
permissions:
contents: read
uses: ./.github/workflows/secret-scan.yml
19 changes: 19 additions & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# OSSF Scorecard — push-to-default + weekly schedule only. The Scorecard action
# supports only push and schedule on the default branch.
name: scorecard

on:
push:
branches: [main]
schedule:
- cron: "31 2 * * 1"

permissions: {}

jobs:
scorecard:
permissions:
id-token: write # OIDC token for Scorecard provenance checks
contents: read
actions: read # inspect workflow definitions for the scoring checks
uses: ./.github/workflows/public-scorecard-json.yml
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@

## [Unreleased]

### Added

- **Self-application of the public OSS security suite.** This repository shipped
CodeQL, OSSF Scorecard, Dependency Review, and gitleaks to the estate while
consuming none of them itself; it self-applied only `actionlint`, `zizmor`,
and `release-supply-chain`. New self workflows `codeql.yml`, `gitleaks.yml`,
`dependency-review.yml`, and `scorecard.yml` call the matching reusables
through relative refs, with triggers taken from this repository's own
`examples/public-oss/` shapes.

### Fixed

- **`SELF_WORKFLOWS` was duplicated as a literal in three places.**
`_workflow_yaml.py` held the named constant while `validate_catalog.py` and
`generate_docs.py` each hardcoded `{"ci.yml", "release.yml"}` again. Both now
import it. With the constant honoured in only one of the three,
`validate_all.py` passed while `docs/generated/workflow-inventory.md` listed
the new self workflows as `MISSING` instead of `internal` — a green gate over
wrong generated output.

## [0.12.0] - 2026-07-21

### Changed
Expand Down
4 changes: 4 additions & 0 deletions docs/generated/workflow-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@
| `.github/workflows/benchmark-compare.yml` | `benchmark-compare` | ga |
| `.github/workflows/benchmark.yml` | `benchmark` | ga |
| `.github/workflows/ci.yml` | internal | internal |
| `.github/workflows/codeql.yml` | internal | internal |
| `.github/workflows/container-ci.yml` | `container-scan-trivy` | ga |
| `.github/workflows/coverage-gate.yml` | `coverage-gate` | ga |
| `.github/workflows/cpp-ci.yml` | `cpp-ci` | ga |
| `.github/workflows/cross-platform-smoke.yml` | `cross-platform-smoke` | ga |
| `.github/workflows/dart-flutter-ci.yml` | `dart-flutter-ci` | ga |
| `.github/workflows/dependency-review.yml` | internal | internal |
| `.github/workflows/docs-ci.yml` | `docs-ci` | ga |
| `.github/workflows/docs-quality.yml` | `docs-quality` | ga |
| `.github/workflows/dotnet-ci.yml` | `dotnet-ci` | ga |
| `.github/workflows/fuzzing.yml` | `fuzzing` | ga |
| `.github/workflows/gitleaks.yml` | internal | internal |
| `.github/workflows/go-ci.yml` | `go-ci` | ga |
| `.github/workflows/grype-scan.yml` | `grype-sca` | ga |
| `.github/workflows/hadolint-ci.yml` | `hadolint-dockerfile` | ga |
Expand All @@ -39,6 +42,7 @@
| `.github/workflows/release-supply-chain.yml` | `artifact-attestations`, `sbom-generation`, `slsa-build-provenance`, `release-supply-chain` | ga |
| `.github/workflows/release.yml` | internal | internal |
| `.github/workflows/rust-ci.yml` | `rust-ci` | ga |
| `.github/workflows/scorecard.yml` | internal | internal |
| `.github/workflows/secret-scan.yml` | `gitleaks-secret-scan` | ga |
| `.github/workflows/semgrep-ci.yml` | `semgrep-sast` | ga |
| `.github/workflows/sql-ci.yml` | `sql-ci` | ga |
Expand Down
13 changes: 11 additions & 2 deletions scripts/_workflow_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@
REPO_ROOT = Path(__file__).resolve().parent.parent
WORKFLOWS_DIR = REPO_ROOT / ".github" / "workflows"

# Self workflows are not reusable (they are not `on: workflow_call`).
SELF_WORKFLOWS = {"ci.yml", "release.yml"}
# Self workflows are not reusable (they are not `on: workflow_call`). They are
# this repository applying its own catalog to itself, so they carry no catalog,
# runtime-coverage, or generated-inventory entry.
SELF_WORKFLOWS = {
"ci.yml",
"codeql.yml",
"dependency-review.yml",
"gitleaks.yml",
"release.yml",
"scorecard.yml",
}


def workflow_files() -> list[Path]:
Expand Down
4 changes: 3 additions & 1 deletion scripts/generate_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import yaml

from _workflow_yaml import SELF_WORKFLOWS

REPO_ROOT = Path(__file__).resolve().parent.parent
CATALOG = REPO_ROOT / "catalog" / "capabilities.yml"
WORKFLOWS_DIR = REPO_ROOT / ".github" / "workflows"
Expand Down Expand Up @@ -83,7 +85,7 @@ def workflow_inventory(caps: list[dict[str, Any]]) -> str:
]
for path in sorted(WORKFLOWS_DIR.glob("*.yml")):
rel = f".github/workflows/{path.name}"
if path.name in {"ci.yml", "release.yml"}:
if path.name in SELF_WORKFLOWS:
ids = "internal"
statuses = "internal"
else:
Expand Down
4 changes: 3 additions & 1 deletion scripts/validate_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import yaml

from _workflow_yaml import SELF_WORKFLOWS

REPO_ROOT = Path(__file__).resolve().parent.parent
CATALOG_DIR = REPO_ROOT / "catalog"
WORKFLOWS_DIR = REPO_ROOT / ".github" / "workflows"
Expand Down Expand Up @@ -121,7 +123,7 @@ def check() -> list[str]:
workflow_files = {
f".github/workflows/{path.name}"
for path in WORKFLOWS_DIR.glob("*.yml")
if path.name not in {"ci.yml", "release.yml"}
if path.name not in SELF_WORKFLOWS
}
missing_workflows = workflow_files - workflows_in_catalog
if missing_workflows:
Expand Down
Loading