Three rounds of fixes to this kit, and each round found the previous round's blind spot: a check that examined nothing, then a check that examined everything with a pattern that could not match, then a flag that made one rule skip binary files without a word. None of them were visible from a green run, and each was found by a sibling plugin rather than by anything here. So the battery stops being a shell loop somebody retypes and becomes a script CI runs. 26 assertions: 13 credential shapes that must be flagged, 6 lookalikes that must stay quiet, the direct-access count, the four text-domain verdicts, the annotated path being a real file, and a plugin.conf with its floors stripped failing to load. 🔴 It asserts on the thing that has CONSEQUENCES — the exit status of the script CI runs, and the specific failure message. Never a filename, a count, or a log line that merely sits near the signal. The previous ad-hoc battery asserted "the fixture's filename appears in the output", which passes on grep's own `binary file matches` diagnostic, because that diagnostic prints the filename in exactly the place a real failure would. A sibling plugin recorded two binary cases as PASS on that basis. The probe had the same defect as the check it was testing. The self-test was then checked to go red: making the AKIA pattern inert fails exactly one assertion, naming the shape. Its first run failed an assertion, and the fixture was at fault rather than the product. This script sources ci/lib.sh, so the floors are in the environment and a plain subshell inherits them — ci_load_conf then passed over a plugin.conf that does not define them. Fixed with an explicit unset, and the reason is inline so nobody weakens the assertion instead. A failing probe is evidence about the probe until you have looked at it. Wired into the static job in BOTH workflow roots, byte-identical: .gitea hides .github completely rather than merging it, so a step added to one root only would not run on Gitea and would look exactly like a runner that had not picked the job up. ci/workflows-in-sync.sh passes. Excluded from the release zip, and it plants nothing in the real tree — the fixtures go into a throwaway copy under mktemp, several being credential-shaped by definition. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
67 lines
2.2 KiB
YAML
67 lines
2.2 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
# No `concurrency:` block here, and that is not an oversight. Measured on Gitea
|
|
# 1.27.2, adding one produces no run at all — not a failed run, not a cancelled
|
|
# one: nothing to click on, which looks exactly like a runner that has not
|
|
# picked the job up, so you wait, and waiting never fixes it.
|
|
#
|
|
# This file is kept byte-identical in .github/workflows and .gitea/workflows.
|
|
# ci/workflows-in-sync.sh fails if the two drift apart, because a workflow that
|
|
# lives only in .github/ does not run on Gitea at all.
|
|
|
|
jobs:
|
|
static:
|
|
name: Static checks
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Workflows in sync
|
|
run: ci/workflows-in-sync.sh
|
|
|
|
- name: Lint, hygiene, versions and compatibility headers
|
|
run: ci/static.sh
|
|
|
|
# Runs static.sh again against planted fixtures and asserts it goes RED.
|
|
# Every check in ci/ has been silently hollow at least once — reporting
|
|
# success having examined nothing, then examining everything with a
|
|
# pattern that could not match. Neither is visible from a green run, so
|
|
# the only defence is a thing that must be found.
|
|
- name: The checks can actually fail
|
|
run: ci/selftest.sh
|
|
|
|
- name: The release zip is buildable and complete
|
|
run: ci/build-zip.sh
|
|
|
|
site:
|
|
name: WordPress ${{ matrix.wp }} + WooCommerce ${{ matrix.wc }} on PHP ${{ matrix.php }}
|
|
runs-on: ubuntu-latest
|
|
|
|
# One cell per push: what a shop that keeps up to date is running today.
|
|
# The wider matrix — the oldest PHP the header promises, the next
|
|
# WordPress, the next WooCommerce — runs weekly in compat.yml, so a single
|
|
# self-hosted runner is not asked to do all of it on every commit.
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { wp: latest, wc: latest, php: '8.3' }
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install into a throwaway shop and run the tests
|
|
env:
|
|
WP_VERSION: ${{ matrix.wp }}
|
|
WC_VERSION: ${{ matrix.wc }}
|
|
PHP_VERSION: ${{ matrix.php }}
|
|
run: ci/site-test.sh
|