krz/domain-dig

an ios app for DNS & SSL analysis

clone: git clone https://gitbay.org/krz/domain-dig.git

9201ef0008db5c45b33e75e674febe0cd4d4f0d5

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-08-22T19:25:40Z

Remove the GitHub Actions build workflow

Deletes .github/workflows/build.yml. The accessibility audit it ran was failing
on unattributed findings that do not reproduce locally on the same simulator and
OS, and the job is no longer wanted.

Worth recording what goes with it: the workflow was the only check that built a
clean checkout of the merge result. DomainDig.xcodeproj is hand-edited and uses
file-system-synchronized groups, so a folder missing from a commit still builds
locally and breaks only for someone else, and the pre-push hook runs against the
working tree where such a file is still present. Nothing covers that now.

Docs/ACCESSIBILITY.txt described the local/CI split as two halves that each
covered what the other could not, so it is updated rather than left claiming a
job that no longer exists.
 .github/workflows/build.yml | 127 --------------------------------------------
 Docs/ACCESSIBILITY.txt      |  30 +++++------
 2 files changed, 15 insertions(+), 142 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index 4f09d50..0000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,127 +0,0 @@
-name: Build
-
-# Compile gate and accessibility audit for the GitHub mirror. builds.sr.ht is the
-# primary remote for this project but has no macOS images, so xcodebuild cannot
-# run there; this job builds and tests on a GitHub-hosted macOS runner instead.
-#
-# This runs `xcodebuild test`, which also compiles the app, the widget, and the
-# share extension (the DomainDig scheme's build action pulls both in as
-# dependencies). The scheme has two test targets: DomainDigUITests — an
-# accessibility audit suite; see DomainDigUITests/AccessibilityAuditHarness.swift
-# — and DomainDigTests — unit coverage of the deterministic core (report builder,
-# exporter, diff, portability dedup).
-#
-# WHAT THIS JOB IS FOR, given the audit also runs locally:
-# a clean checkout of the merge result. A local hook runs against the working
-# tree and therefore cannot catch a file that was never committed — the failure
-# mode that matters most here, since DomainDig.xcodeproj is hand-edited and uses
-# file-system-synchronized groups where a whole missing folder still builds fine
-# locally. This job is the only place that check exists; sr.ht cannot run it.
-#
-# DELIBERATELY ONE JOB, NEWEST RUNTIME ONLY. Audit coverage is not nested across
-# OS versions, so the oldest supported OS genuinely needs its own run — but the
-# macos-26 image ships only iOS 26.x runtimes, so CI *cannot* provide it. Asking
-# for two jobs here bought two near-identical 26.x runs at double the macOS
-# minutes. Floor coverage lives in Scripts/audit-a11y.sh, run from a machine that
-# actually has an 18.x runtime installed, and is wired to the pre-push hook in
-# .githooks/. See Docs/ACCESSIBILITY.md for the split.
-#
-# The audit REPORTS but does not FAIL by default. It surfaces violations that
-# exist today, so gating on it would block every unrelated PR until the
-# accessibility pass in issue #21 completes. Findings land in the job log and in
-# the uploaded .xcresult bundle, tagged [report] or [FAIL]. Enforcement is a
-# committed constant: widen `AccessibilityAuditHarness.enforcedAuditTypes` as
-# each phase clears a category. (Env vars were tried first — neither a plain
-# xcodebuild env var nor a TEST_RUNNER_-prefixed build setting reaches the UI
-# test process.)
-#
-# pull_request only, plus manual dispatch. GitHub builds the merge result (PR
-# merged into main), so a green PR validates exactly what will land on main.
-# Note: this repo currently also pushes directly to main for releases, and those
-# pushes are NOT gated here — add a `push: { branches: [main] }` trigger below if
-# you want direct-to-main commits covered too.
-#
-# paths-ignore skips prose-only changes. Both globs are single-star, so they
-# match the repo root and Docs/ but nothing deeper — a .md that ever lands inside
-# a source directory still builds.
-on:
-  pull_request:
-    paths-ignore: ['*.md', 'Docs/*.md']
-  workflow_dispatch:
-
-# The job only reads code; drop the default read-write GITHUB_TOKEN scope.
-permissions:
-  contents: read
-
-concurrency:
-  group: build-${{ github.ref }}
-  cancel-in-progress: true
-
-jobs:
-  test:
-    name: xcodebuild test
-    # macos-latest still points at macOS 15, which lacks the iOS 26+ SDK this app
-    # is built against.
-    runs-on: macos-26
-
-    steps:
-      - uses: actions/checkout@v7
-
-      - name: Show toolchain
-        run: |
-          xcodebuild -version
-          swift --version
-
-      - name: Select simulator
-        id: sim
-        run: |
-          set -euo pipefail
-
-          # Newest available iPhone runtime. No deployment-target filtering is
-          # needed for "newest" — it is always at or above the floor. The
-          # previous selector took the first iPhone from ANY runtime, which on a
-          # machine with an older runtime installed could pick a simulator below
-          # the deployment target, where the app cannot install.
-          selected=$(xcrun simctl list devices available --json \
-            | jq -c '
-                [ .devices | to_entries[]
-                  | (.key | capture("SimRuntime\\.iOS-(?<maj>[0-9]+)-(?<min>[0-9]+)$")) as $v
-                  | (($v.maj | tonumber) * 1000 + ($v.min | tonumber)) as $rank
-                  | .value[]
-                  | select(.name | startswith("iPhone"))
-                  | { rank: $rank, udid: .udid, name: .name, os: "\($v.maj).\($v.min)" }
-                ]
-                | sort_by(.rank, .name)
-                | last
-              ')
-
-          if [ -z "$selected" ] || [ "$selected" = "null" ]; then
-            echo "::error::No iPhone simulator available on this image"
-            xcrun simctl list devices available >&2
-            exit 1
-          fi
-
-          label=$(echo "$selected" | jq -r '"\(.name) (iOS \(.os))"')
-          echo "Selected $label"
-          echo "udid=$(echo "$selected" | jq -r .udid)" >> "$GITHUB_OUTPUT"
-          echo "label=$label" >> "$GITHUB_OUTPUT"
-
-      - name: Test on ${{ steps.sim.outputs.label }}
-        run: |
-          set -o pipefail
-          xcodebuild test \
-            -project DomainDig.xcodeproj \
-            -scheme DomainDig \
-            -destination "id=${{ steps.sim.outputs.udid }}" \
-            -resultBundlePath TestResults.xcresult \
-            CODE_SIGNING_ALLOWED=NO
-
-      - name: Upload results
-        # Always upload: on success the bundle carries the accessibility burndown
-        # list, which is the reason this suite exists.
-        if: always()
-        uses: actions/upload-artifact@v4
-        with:
-          name: test-results
-          path: TestResults.xcresult
-          retention-days: 7
diff --git a/Docs/ACCESSIBILITY.txt b/Docs/ACCESSIBILITY.txt
index 6e82055..a2fb3f2 100644
--- a/Docs/ACCESSIBILITY.txt
+++ b/Docs/ACCESSIBILITY.txt
@@ -115,8 +115,8 @@ headers above. Everything the app actually controls passes in both schemes.
 With phases 1–5 landed, `AccessibilityAuditHarness.enforcedAuditTypes` enforces
 **`.textClipped`, `.dynamicType`, `.hitRegion`, `.elementDetection`,
 `.sufficientElementDescription`, `.trait`** on the empty-state test suite. A
-named finding in any of these fails CI — regressions in five phases of work are
-now gated, not merely reported.
+named finding in any of these fails the test run — regressions in five phases of
+work are still gated locally and at the pre-push hook, not merely reported.
 
 Three deliberate carve-outs, each with its evidence:
 
@@ -143,7 +143,7 @@ Environment variables do not work: neither a plain `xcodebuild` env var nor a
 silently did nothing. And a committed value makes "when did clipping become
 enforced?" answerable with `git blame` instead of CI tribal knowledge.
 
-## Why coverage is split between local and CI
+## Why the floor runtime needs its own run
 
 **Audit coverage is not nested across OS versions.** Each runtime reports
 findings the others miss, in *both* directions. Measured on this project:
@@ -158,18 +158,18 @@ Neither runtime is a superset, so the oldest supported OS needs its own run.
 This also rules out committing per-screen baseline counts as a regression guard:
 no single number is correct on both.
 
-The catch is that **GitHub's `macos-26` image ships only iOS 26.x simulator
-runtimes.** It cannot test the 17.6 floor at all. A two-job CI matrix was tried
-and produced two near-identical 26.x runs at double the macOS minutes.
-
-So the work is split by what each side can uniquely do:
-
-| | Runtime | Uniquely provides |
-| --- | --- | --- |
-| **CI** (`.github/workflows/build.yml`) | newest available | A clean checkout of the merge result — catches a file that was never committed, which a local run cannot. Matters here because `DomainDig.xcodeproj` is hand-edited and uses file-system-synchronized groups, where a whole missing folder still builds locally. |
-| **Local** (`Scripts/audit-a11y.sh`) | oldest supported + newest | Real floor coverage, on a machine that actually has an 18.x runtime installed. |
-
-Together they cover both ends; neither duplicates the other.
+The audit therefore runs locally, across both ends, via
+`Scripts/audit-a11y.sh` — on a machine that actually has an 18.x runtime
+installed. It is wired to the pre-push hook in `.githooks/`.
+
+There is no CI job. The GitHub Actions workflow that used to run this suite on
+the newest runtime has been removed, and with it the one check that no local run
+can reproduce: **a clean checkout of the merge result.** That mattered here
+because `DomainDig.xcodeproj` is hand-edited and uses file-system-synchronized
+groups, where a whole missing folder still builds fine locally and breaks only
+for someone else. A local hook runs against the working tree, so it cannot catch
+a file that was never committed. Nothing covers that now — verify a fresh clone
+by hand before a release.
 
 ## Running it