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
34 changes: 34 additions & 0 deletions .github/workflows/hooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Runs .pre-commit-config.yaml, so the hooks that ci.yml does not run itself -
# bandit, shellcheck, markdownlint, actionlint, betterleaks, uv-lock - gate a
# pull request instead of depending on somebody having installed them. Two of
# them sat red on main unnoticed before this existed.
#
# Its own workflow rather than a job in ci.yml, because ci.yml skips prose-only
# changes and markdownlint is the hook that most needs to see those.
name: Hooks

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
prek:
name: pre-commit hooks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0

- uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
with:
enable-cache: true
# uv itself, the same one ci.yml pins.
version: "0.11.28"

# prek pinned like every other tool here; each hook's own version is
# pinned by its rev in .pre-commit-config.yaml.
- name: Run every hook over every file
run: uvx prek@0.5.4 run --all-files --show-diff-on-failure
1 change: 1 addition & 0 deletions collector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ for f in image/*.sh; do bash -n "$f"; done # The entry points parse
GITHUB_TOKEN=dummy docker compose config --quiet # The compose file parses
docker build -t jq-monitoring:ci . # The image builds
uvx --with mkdocs-material==9.6.14 mkdocs build --strict # The book, broken links fail it
uvx prek@0.5.4 run --all-files # Every hook in .pre-commit-config.yaml
```

CI then starts that image against a throwaway `repos.yml` and checks it serves
Expand Down
7 changes: 5 additions & 2 deletions collector/jq_collector/localgit.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

import logging
import os
import subprocess
import subprocess # nosec B404 - only ever runs git, argv-only; see _git
import time
from typing import TypedDict

Expand All @@ -46,8 +46,11 @@

def _git(path: str, *args: str) -> str | None:
"""Run a read-only git command, returning None if it fails."""
# A fixed argv with no shell, so path and args reach git as arguments and
# never as a command line; `git` is resolved on PATH on purpose, since the
# image and a laptop keep it in different places.
try:
result = subprocess.run(
result = subprocess.run( # nosec B603 B607
["git", "--no-optional-locks", "-C", path, *args],
capture_output=True,
text=True,
Expand Down
5 changes: 3 additions & 2 deletions collector/jq_collector/origin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from __future__ import annotations

import logging
import subprocess
import subprocess # nosec B404 - only ever runs git, argv-only; see read
from dataclasses import dataclass

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -124,8 +124,9 @@ def read(path: str) -> Origin | None:
clones are somebody's live working copies and a monitor has no business
taking a lock in one.
"""
# Fixed argv, no shell, git from PATH - the same reasoning as localgit._git.
try:
result = subprocess.run(
result = subprocess.run( # nosec B603 B607
["git", "--no-optional-locks", "-C", path, "remote", "get-url", "origin"],
capture_output=True,
text=True,
Expand Down
2 changes: 2 additions & 0 deletions image/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ mkdir -p /data/prometheus /data/grafana

# -- shut down together ------------------------------------------------------
pids=()
# Invoked only through the trap below, which shellcheck cannot follow.
# shellcheck disable=SC2329
stop() {
trap - TERM INT
# Signal the group rather than each pid: promtool-style children and
Expand Down
Loading