Lint / JS (eslint) (push) Successful in 9s
Lint / Shell (shellcheck) (push) Successful in 10s
Lint / No Hookshot webhook IDs in README (push) Successful in 5s
Lint / No secrets in webhook configs (push) Successful in 5s
Lint / Landing page is rendered (matrix (push) Successful in 6s
Lint / Python (ruff) (push) Successful in 10s
Lint / Secret scan (gitleaks) (push) Successful in 7s
Lint / Shell (shellcheck) (pull_request) Successful in 12s
Lint / JS (eslint) (pull_request) Successful in 10s
Lint / No Hookshot webhook IDs in README (pull_request) Successful in 12s
Lint / Python deps (pip-audit) (push) Successful in 56s
Lint / No secrets in webhook configs (pull_request) Successful in 6s
Lint / Landing page is rendered (matrix (pull_request) Successful in 5s
Lint / Python (ruff) (pull_request) Successful in 6s
Lint / Secret scan (gitleaks) (pull_request) Successful in 7s
Lint / Python deps (pip-audit) (pull_request) Successful in 39s
- The README's webhook table listed every Hookshot webhook's full UUID. The UUID is the webhook's only secret and this repo is public, so anyone could post into Spam and Stuff. Shorten them to 8 characters and add CI (readme-no-webhook-ids) rejecting full UUIDs in README.md. They remain in git history until rotated. - Hookshot is now 7.5.0: how it's built (pnpm 7.4.1+, Node 22 limit of 7.6.0) and how to swap a new build in. - Planned lk-jwt-service 0.9.0 / LiveKit 1.13.11 upgrade: the LiveKit webhook delegated leave needs, the prometheus config key, and restart caveats, from local testing. - Graceful restart: describe the fixed check (#54). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
139 lines
4.8 KiB
YAML
139 lines
4.8 KiB
YAML
name: Lint
|
|
|
|
on:
|
|
push:
|
|
branches: ["**"]
|
|
pull_request:
|
|
branches: ["**"]
|
|
|
|
jobs:
|
|
shell-lint:
|
|
name: Shell (shellcheck)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Install shellcheck
|
|
run: apt-get update -qq && apt-get install -y -qq shellcheck
|
|
|
|
- name: Run shellcheck
|
|
run: find . -name "*.sh" -exec shellcheck {} +
|
|
|
|
js-lint:
|
|
name: JS (eslint)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Install ESLint
|
|
run: npm install --save-dev eslint@8
|
|
|
|
- name: Run ESLint
|
|
run: npx eslint --ext .js hookshot/
|
|
|
|
readme-no-webhook-ids:
|
|
name: No Hookshot webhook IDs in README
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
# A Hookshot webhook URL's UUID is its only secret, and this repo is public.
|
|
- name: Reject full UUIDs
|
|
run: |
|
|
if grep -nE '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}' README.md; then
|
|
echo "::error::README.md contains a full UUID. Webhook IDs are secrets: list only the first 8 characters."
|
|
exit 1
|
|
fi
|
|
|
|
hooks-no-secrets:
|
|
name: No secrets in webhook configs
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
# deploy/hooks-*.json are public; their secrets come from
|
|
# /etc/webhook/secrets.env on each LXC via `{{ getenv "..." }}`.
|
|
- name: Reject literal secrets
|
|
run: |
|
|
if grep -nE '[0-9a-fA-F]{32,}' deploy/hooks-*.json; then
|
|
echo "::error::A literal secret/token is committed in deploy/hooks-*.json. Use {{ getenv \"NAME\" | js }} and put the value in /etc/webhook/secrets.env on the LXC."
|
|
exit 1
|
|
fi
|
|
|
|
landing-fresh:
|
|
name: Landing page is rendered (matrix #11)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
# index.html's feature groups, comparison table and inlined CSS are
|
|
# generated from landing/data/*.json + landing/style.css. Fail if someone
|
|
# edited the data without re-running the renderer (or edited the output).
|
|
- name: Check landing/index.html matches its sources
|
|
run: python3 landing/build.py --check
|
|
|
|
python-lint:
|
|
name: Python (ruff)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Install ruff
|
|
run: |
|
|
curl -sSL https://github.com/astral-sh/ruff/releases/download/0.8.6/ruff-x86_64-unknown-linux-gnu.tar.gz \
|
|
| tar -xz --strip-components=1
|
|
mv ruff /usr/local/bin/ruff
|
|
|
|
- name: Check syntax errors
|
|
run: ruff check matrixbot/ --select E9,F63,F7,F82 --output-format=github
|
|
|
|
- name: Run full lint
|
|
run: ruff check matrixbot/ --output-format=github
|
|
|
|
python-audit:
|
|
name: Python deps (pip-audit)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Install Python 3.13 and pip-audit
|
|
run: |
|
|
# Debian Bullseye only ships Python 3.9; use a prebuilt standalone binary.
|
|
# 3.13 matches the bot's runtime on LXC 151 (Debian trixie).
|
|
curl -sSL "https://github.com/astral-sh/python-build-standalone/releases/download/20250317/cpython-3.13.2+20250317-x86_64-unknown-linux-gnu-install_only.tar.gz" \
|
|
| tar -xz -C /opt
|
|
# Install bot deps + pip-audit into the same env; --local below avoids
|
|
# pip-audit creating an internal venv (ensurepip fails on standalone builds)
|
|
/opt/python/bin/pip install --upgrade pip setuptools
|
|
/opt/python/bin/pip install --upgrade pip-audit -r matrixbot/requirements.txt
|
|
|
|
- name: Audit matrixbot dependencies
|
|
# --local scans the env without spawning a venv (required for standalone Python)
|
|
# CVE-2026-3219 is in pip itself, not our code — ignore it explicitly.
|
|
run: /opt/python/bin/pip-audit --local --ignore-vuln CVE-2026-3219
|
|
|
|
secret-scan:
|
|
name: Secret scan (gitleaks)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Install gitleaks
|
|
run: |
|
|
curl -sSL --retry 3 --retry-delay 5 --max-time 120 \
|
|
https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz \
|
|
| tar -xz gitleaks
|
|
mv gitleaks /usr/local/bin/gitleaks
|
|
|
|
- name: Scan for secrets
|
|
run: |
|
|
# Scan application code directories — deploy/ is excluded because
|
|
# it contains intentional Gitea webhook HMAC secrets in hooks-lxc*.json
|
|
for dir in matrixbot/ hookshot/ .gitea/ systemd/ cinny/ landing/ discord-bridge/; do
|
|
[ -d "$dir" ] || continue
|
|
gitleaks detect --source "$dir" --no-git --config .gitleaks.toml \
|
|
--redact --exit-code 1
|
|
done
|