chore(deps): update all non-major dependencies (#245) #1086
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Security | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| schedule: | |
| # Weekly scan every Monday at 02:00 UTC | |
| - cron: "0 2 * * 1" | |
| # Supersede in-flight runs for the same PR; see .claude/CLAUDE.md "Superseding CI runs". | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| # ── Monorepo Structure Maintenance ──────────────────────────────────────────── | |
| # Checks that per-language tooling is fully wired up before per-module jobs run. Covers Go | |
| # (module matrix completeness, .golangci.yml presence) and Python (workspace tool config, | |
| # member glob coverage, requirements_lock.txt freshness). uv is needed for the lock check; | |
| # setup-uv brings it alongside the 3.14 Python interpreter the script targets. | |
| modules-check: | |
| name: Module completeness check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| # renovate: datasource=python-version depName=python | |
| python-version: "3.14" | |
| - run: python3 meta/scripts/check_modules.py | |
| # ── Static Application Security Testing (SAST) ─────────────────────────────── | |
| # Analyses source code for security vulnerabilities — injection flaws, insecure API usage, | |
| # hardcoded secrets — from the source rather than from a resolved dependency set. Two engines run | |
| # here: Semgrep below, and CodeQL after it. Semgrep uses per-language rule packs, passed via | |
| # SEMGREP_RULES; add one per adopted language. The deprecated semgrep/semgrep-action is | |
| # replaced by the upstream-recommended semgrep/semgrep container image running `semgrep ci`, so | |
| # the tool version is SHA-pinned like everything else (the action froze at v0.58.0 — see README's | |
| # "Dependency updates"). | |
| # TEND(lang-expand): add p/<language> to SEMGREP_RULES for each adopted language (semgrep.dev/r | |
| # lists available packs, e.g. p/java, p/typescript, p/rust). | |
| semgrep: | |
| name: Semgrep | |
| runs-on: ubuntu-latest | |
| container: | |
| image: semgrep/semgrep:1.174.0@sha256:f1f7b71861c7b28b6e0f661225a2c4f58a484f5d0f182465c6d6b3b22f972ade | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - run: semgrep ci | |
| env: | |
| SEMGREP_RULES: p/golang p/python p/secrets | |
| # CodeQL, the second SAST engine and the one code scanning's own UI reads. Advanced setup on | |
| # purpose — see .claude/CLAUDE.md "CodeQL runs as advanced setup" for what GitHub's managed | |
| # default setup could not do, and for the repo setting that has to stay off for this to run. | |
| codeql: | |
| name: CodeQL Analysis (${{ matrix.language }}) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| # Uploads the SARIF. The starter workflow's `actions: read` (private repos) and | |
| # `packages: read` (private CodeQL packs) buy nothing here; this repo is public and | |
| # queries come from the default suite. | |
| security-events: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # TEND(lang-expand): one entry per adopted language. `none` extracts without building and | |
| # is what interpreted languages want; a compiled language has no such option and needs its | |
| # toolchain installed below, the way Go does. | |
| include: | |
| - language: actions | |
| build-mode: none | |
| - language: go | |
| build-mode: autobuild | |
| - language: python | |
| build-mode: none | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| # Ahead of init on purpose: the Go autobuilder runs under GOTOOLCHAIN=local, so whatever | |
| # is on PATH when extraction starts is the only toolchain it can use. | |
| # //meta/scripts:test_codeql_toolchain keeps this step, and its position, from being lost. | |
| - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| if: matrix.language == 'go' | |
| with: | |
| go-version-file: go.work | |
| # Globbed, not listed: this job has no module matrix to key off, and a hand-listed | |
| # module would go stale the day a second one lands. | |
| cache-dependency-path: | | |
| go.work.sum | |
| **/go.sum | |
| - uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8 | |
| with: | |
| languages: ${{ matrix.language }} | |
| # No separate autobuild step: that action documents itself as superseded by this input. | |
| build-mode: ${{ matrix.build-mode }} | |
| - uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8 | |
| with: | |
| # The string default setup uploaded under; it is what separates one language's | |
| # results from another's within a tool. | |
| category: "/language:${{ matrix.language }}" | |
| # Fan-in for the ruleset; the pattern's reasoning is at devcontainer.yml's `base-image-all`. | |
| # Strict on `skipped` unlike that one, since nothing gates this matrix. `if: always()` is | |
| # load-bearing: without it a failed matrix skips this job, and a skipped check counts as | |
| # passing. //meta/scripts:test_codeql_toolchain keeps both. | |
| codeql-all: | |
| name: CodeQL Analysis (all languages) | |
| runs-on: ubuntu-latest | |
| needs: [codeql] | |
| if: always() | |
| steps: | |
| - name: Verify all codeql jobs passed | |
| run: | | |
| if [ "${{ needs.codeql.result }}" != "success" ]; then | |
| echo "codeql result: ${{ needs.codeql.result }}" | |
| exit 1 | |
| fi | |
| echo "All codeql jobs passed" | |
| # ── Dependency CVE Scanning ─────────────────────────────────────────────────── | |
| # Per-language scanners that flag known-vulnerable third-party dependencies. The signal model | |
| # differs by language — govulncheck does call-graph reachability (only fires when our code | |
| # reaches the vulnerable symbol); pip-audit is manifest-based (fires on any flagged version in | |
| # the resolved set). Both run once per resolution unit: govulncheck per Go module, pip-audit | |
| # once over the workspace-wide uv resolution (uv enforces single-version-per-package across | |
| # workspace members, so one scan covers every member). | |
| # TEND(lang-expand): add an equivalent per-language scanner as languages are adopted | |
| # (e.g. cargo-audit for Rust, trivy fs --scanners vuln for languages without a dedicated | |
| # reachability tool). | |
| govulncheck: | |
| name: govulncheck (${{ matrix.go_module }}) | |
| runs-on: ubuntu-latest | |
| needs: [modules-check] | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| go_module: | |
| - tools/network_infrastructure_maintenance | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| # The setup/install/run trio below is what golang/govulncheck-action wraps. We inline it: | |
| # the action is a thin composite, and its own pinned actions/checkout + actions/setup-go | |
| # trail current releases far enough to emit Node runtime deprecation warnings in every | |
| # consuming workflow. If this ever outgrows install-and-run, check whether that action has | |
| # started keeping its dependencies current and switch back. | |
| - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| # go.work pins the toolchain so a workspace-level `go X.Y.Z` directive doesn't trip | |
| # GOTOOLCHAIN=local. | |
| go-version-file: go.work | |
| cache-dependency-path: | | |
| go.work.sum | |
| ${{ matrix.go_module }}/go.sum | |
| - run: go install golang.org/x/vuln/cmd/govulncheck@latest | |
| - run: govulncheck -C ${{ matrix.go_module }} ./... | |
| govulncheck-all: | |
| name: govulncheck (all modules) | |
| runs-on: ubuntu-latest | |
| needs: [govulncheck] | |
| if: always() | |
| steps: | |
| - name: Verify all govulncheck jobs passed | |
| run: | | |
| if [ "${{ needs.govulncheck.result }}" != "success" ]; then | |
| echo "govulncheck result: ${{ needs.govulncheck.result }}" | |
| exit 1 | |
| fi | |
| echo "All govulncheck jobs passed" | |
| # Python sibling of govulncheck. pip-audit reads requirements.txt format; we feed it a | |
| # fresh `uv export` of uv.lock (the source of truth) into a tempfile rather than the | |
| # committed requirements_lock.txt, so this scan is decoupled from whether the derived | |
| # file is currently in sync — pre-commit and the Renovate auto-commit workflow each | |
| # police that on their own paths. | |
| pip-audit: | |
| name: pip-audit | |
| runs-on: ubuntu-latest | |
| needs: [modules-check] | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| # renovate: datasource=python-version depName=python | |
| python-version: "3.14" | |
| - name: Export uv.lock to requirements.txt | |
| run: | | |
| uv export --format requirements-txt --no-emit-project \ | |
| --output-file "${RUNNER_TEMP}/requirements.txt" | |
| - name: pip-audit | |
| env: | |
| # renovate: datasource=pypi depName=pip-audit | |
| PIP_AUDIT_VERSION: "2.10.1" | |
| # `--require-hashes` makes pip-audit trust the file as the resolution (implies | |
| # `--no-deps`) AND fail if any line lacks a hash — a regression check against an | |
| # un-hashed export sneaking back in. `--strict` promotes any remaining warning | |
| # class to a failure. | |
| run: uvx "pip-audit@${PIP_AUDIT_VERSION}" --requirement "${RUNNER_TEMP}/requirements.txt" --require-hashes --strict | |
| # ── Supply Chain and Filesystem Scanning ───────────────────────────────────── | |
| # Scans the entire repository for secrets committed to source, dependency CVEs across all | |
| # ecosystems, and license compliance. Language-agnostic — Trivy covers new languages automatically | |
| # as they are added. | |
| trivy: | |
| name: Trivy | |
| runs-on: ubuntu-latest | |
| permissions: | |
| security-events: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 | |
| with: | |
| scan-type: fs | |
| scan-ref: . | |
| format: sarif | |
| output: trivy.sarif | |
| - uses: github/codeql-action/upload-sarif@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8 | |
| if: always() | |
| with: | |
| sarif_file: trivy.sarif | |
| category: trivy |