mirror of
https://github.com/kuhyx/signal-bot.git
synced 2026-11-10 18:07:29 +01:00
heif-enc resolved and still could not work: Ubuntu splits the HEVC encoder into libheif-plugin-x265, so the binary is installed and answers "No HEVC encoder available". Confirmed the package exists in noble, which is what ubuntu-latest is, rather than guessing at a name for the third time. The step now performs one real encode. Resolving a binary is not the same claim as being able to use it, and this is the third distinct way the same step has failed -- missing tool, missing tool, missing codec -- each of which only surfaced inside a fixture builder several minutes into the run. A probe that encodes fails in the install step, with a message naming the problem. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01416TegJ3sa8xL5qGGgrygP
123 lines
4.7 KiB
YAML
123 lines
4.7 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
check:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# scripts/install_service.sh installs both of these for the host and
|
|
# this file never did, so ./scripts/e2e.sh has failed on every commit
|
|
# for as long as it has existed: tool/e2e_fixtures.py builds its JPEG
|
|
# and MP4 fixtures with ffmpeg, and signal_bot/media_strip.py strips
|
|
# metadata with exiftool. Verified rather than trusted, because an
|
|
# apt exit code is not the same claim as "the binary resolves".
|
|
# Every binary tool/e2e_fixtures.py shells out to, which is the whole
|
|
# list rather than the first one that failed: ffmpeg builds the JPEG
|
|
# and MP4 fixtures, heif-enc the HEIC one, and exiftool is what
|
|
# signal_bot/media_strip.py strips metadata with. scripts/e2e.sh has
|
|
# needed all three since it was written and this file installed none of
|
|
# them, which is why CI has been red on every commit.
|
|
#
|
|
# Verified by resolving each binary, not by trusting apt's exit code --
|
|
# the same distinction install_service.sh makes for the host.
|
|
- name: Install the tools the fixtures are built with
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y ffmpeg libimage-exiftool-perl \
|
|
libheif-examples libheif-plugin-x265
|
|
for tool in ffmpeg exiftool heif-enc; do
|
|
command -v "$tool" || { echo "::error::$tool did not resolve"; exit 1; }
|
|
done
|
|
# Resolving heif-enc is not the same claim as being able to encode:
|
|
# Ubuntu splits the HEVC encoder into its own plugin, so the binary
|
|
# is there and answers "No HEVC encoder available". One real encode
|
|
# fails here, naming the problem, instead of inside a fixture builder.
|
|
ffmpeg -loglevel error -f lavfi -i color=c=red:s=32x32 -frames:v 1 -y /tmp/probe.png
|
|
heif-enc -q 50 /tmp/probe.png -o /tmp/probe.heic
|
|
test -s /tmp/probe.heic || { echo "::error::heif-enc produced nothing"; exit 1; }
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@v5
|
|
|
|
- name: Set up Python
|
|
run: uv python install 3.14
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
uv venv .venv
|
|
uv pip install --python .venv/bin/python -e '.[dev]'
|
|
|
|
# Mirrors the no-noqa pre-commit hook. A suppression must not be able
|
|
# to reach main just because someone committed without hooks installed.
|
|
- name: block suppressions
|
|
run: |
|
|
if grep -rnEi '#\s*(noqa|type:\s*ignore|ruff:\s*noqa)' \
|
|
--include='*.py' signal_bot fake_signal tests; then
|
|
echo '::error::suppressions are not allowed; fix the finding or ask first'
|
|
exit 1
|
|
fi
|
|
|
|
# The name half of this check needs the operator's private data and so
|
|
# can only run locally; the shape half -- phone numbers, uuids, Signal
|
|
# group ids -- works anywhere and is what CI enforces on every push.
|
|
- name: no personal data
|
|
run: ./scripts/check_personal_data.sh --all
|
|
|
|
- name: ruff format
|
|
run: .venv/bin/ruff format --check .
|
|
|
|
- name: ruff check (ALL rules)
|
|
run: .venv/bin/ruff check .
|
|
|
|
- name: mypy --strict
|
|
run: .venv/bin/mypy signal_bot fake_signal
|
|
|
|
- name: shellcheck
|
|
# --severity=style is the floor CI enforces; the local pre-commit hook
|
|
# uses the same flag so a version skew cannot pass locally and fail here.
|
|
run: shellcheck -x --severity=style ./*.sh scripts/*.sh
|
|
|
|
- name: pytest (100% branch coverage)
|
|
run: .venv/bin/python -m pytest -q
|
|
|
|
# The real bot against the fake Signal server. No account, no network.
|
|
- name: end-to-end
|
|
run: ./scripts/e2e.sh
|
|
|
|
# Boot order reversed: the bot starts first and Signal appears later,
|
|
# which is what a reboot looks like and what put the unit in `failed`
|
|
# for eight hours on 2026-08-30.
|
|
- name: cold start
|
|
run: ./scripts/cold_start.sh
|
|
|
|
# The management page. Its own job rather than more steps on `check`: it
|
|
# needs a Node toolchain that the Python job has no use for, and the two
|
|
# halves fail for unrelated reasons.
|
|
web:
|
|
runs-on: ubuntu-latest
|
|
defaults:
|
|
run:
|
|
working-directory: web
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "24.20.0"
|
|
- run: corepack enable
|
|
- name: install (exact pins, from the lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: tsc --noEmit and eslint
|
|
run: pnpm lint
|
|
- name: vitest (100% coverage, no excludes)
|
|
run: pnpm coverage
|