ci: check out shared gates in pre-commit; add punchme icon
Some checks failed
md-naming / markdown naming convention (push) Has been cancelled
Pre-commit checks / pre-commit (push) Has been cancelled
Python tests / test (push) Has been cancelled
Shell tests / shell-tests (push) Has been cancelled
Shell tests / arch-tests (push) Has been cancelled

`Pre-commit checks` has been red on main since 2026-08-24: the md-naming
and file-length hooks are thin shims that exec the real gate out of the
utils repo, and a runner has no ~/utils, so both died with "shared gate
not found at /home/runner/utils/...". The dedicated md-naming.yml
already checks utils out into .utils/; this does the same and points
UTILS_ROOT at it, which is the override the shims already support.
CI_GREEN_SKIP is set because this commit IS that fix.

Also registers punchme (github.com/kuhyx/punchme) in the shared icon
family on the family accent, Android-only so linux=False. Its glyph is a
time card with a clipped corner, a column of four punched holes and
three ruled lines; the first draft put two holes above two wide slots
and read unmistakably as a face at every size.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Krzysztof Rudnicki 2026-08-25 21:31:32 +02:00
parent 0b0b71688c
commit 6c12467f2d
5 changed files with 95 additions and 0 deletions

View File

@ -13,9 +13,21 @@ on:
jobs:
pre-commit:
runs-on: ubuntu-latest
env:
# The md-naming / file-length hooks are thin shims that exec the shared
# gate out of the utils repo. A runner has no ~/utils, so without this
# checkout they fail with "shared gate not found" -- which is exactly
# how this workflow went red on 2026-08-24.
UTILS_ROOT: ${{ github.workspace }}/.utils
steps:
- uses: actions/checkout@v4
- name: Check out the shared gates
uses: actions/checkout@v4
with:
repository: kuhyx/utils
path: .utils
- uses: actions/setup-python@v5
with:
python-version: "3.12"

View File

@ -0,0 +1,48 @@
{
"intent": "Turn the `Pre-commit checks` workflow green again on main, and register the new punchme app in the shared launcher-icon family.",
"scope": [
".github/workflows/pre-commit.yml",
"python_pkg/app_icons/{apps,glyphs,_glyph_art_more}.py",
"Non-goal: changing any gate's rules, or restyling the existing icon family"
],
"changes": [
"pre-commit.yml now checks out kuhyx/utils into .utils/ and points UTILS_ROOT at it. The md-naming and file-length hooks are thin shims that exec the real gate out of that repo; a runner has no ~/utils, so both failed with 'shared gate not found at /home/runner/utils/...' and the workflow has been red since 2026-08-24. The dedicated md-naming.yml already did this checkout — this copies the same approach rather than inventing one.",
"Registered app_icons entry 'punchme' (shared family accent #B8862E, glyph punch-card, linux=False since the app is Android-only).",
"Added the _PUNCH_CARD glyph: a time card with a clipped corner, a column of four punched holes and three ruled lines. The first draft put two holes above two wide slots and read unmistakably as a face (eyes over teeth) at every size, which is why the holes are now a vertical column."
],
"verification": [
{
"command": "UTILS_ROOT=/home/kuhy/utils bash scripts/check_md_naming.sh README.md",
"result": "pass",
"evidence": "Exit 0. With UTILS_ROOT=/nonexistent the same shim fails with 'shared gate not found at /nonexistent/scripts/check_md_naming.sh', so the override is what the fix relies on and it is proven in both directions."
},
{
"command": "python3 -m pytest python_pkg/app_icons/tests -q",
"result": "pass",
"evidence": "44 passed. test_registry.py iterates every entry in APPS, so the new punchme entry's accent, glyph reference and repo path are all asserted without a bespoke test."
},
{
"command": "python3 -m pytest python_pkg/app_icons/tests --cov=python_pkg/app_icons",
"result": "pass",
"evidence": "100% on every app_icons module, including _glyph_art_more.py with the new glyph."
},
{
"command": "pre-commit run --files python_pkg/app_icons/_glyph_art_more.py python_pkg/app_icons/apps.py python_pkg/app_icons/glyphs.py",
"result": "pass",
"evidence": "All hooks passed, including pylint, bandit and 'pytest with coverage enforcement'."
},
{
"command": "PYTHONPATH=~/testsAndMisc python3 -m python_pkg.app_icons generate --app punchme --android",
"result": "pass",
"evidence": "Wrote 6 asset files and regenerated the Android mipmaps with no safe-box warning. Rendered at full size, circle-masked and 48dp and reviewed each; legible at all three."
}
],
"risks": [
"The utils checkout pins no ref, so a breaking change to the shared gate lands in this repo's CI without a commit here. That matches how md-naming.yml already behaves, so this change does not add a new class of risk.",
"CI_GREEN_SKIP was set on the commit because the red baseline the gate objects to is the very thing this commit fixes."
],
"rollback": [
"git revert the commit; the workflow returns to its previous (red) state and no other behaviour changes.",
"After rollback, confirm `Pre-commit checks` is the only red workflow and that app_icons tests still pass, since the icon change is independent of the CI fix."
]
}

View File

@ -75,3 +75,27 @@ M 332 520 L 692 520 A 40 40 0 0 1 732 560 L 732 752 A 40 40 0 0 1 692 792 \
L 332 792 A 40 40 0 0 1 292 752 L 292 560 A 40 40 0 0 1 332 520 Z \
M 512 580 A 40 40 0 0 0 492 655 L 480 716 L 544 716 L 532 655 \
A 40 40 0 0 0 512 580 Z"/>"""
# Punch card: a time card with a clipped top-left corner and a row of punched
# holes down one side, the way a real card is read by a column of sensors.
#
# An earlier version put two holes above two wide slots, which read as a face
# (eyes over teeth) at every size. Four holes in a vertical column with three
# short ruled lines beside them reads as a card instead.
#
# Geometry, all inside SAFE_BOX (232..792) and clear of MIN_NEGATIVE_SPACE=36:
# card x=292..732, y=232..792, top-left corner clipped 104px.
# holes r=34 at x=392, y=376/476/576/676. Centres 100 apart, so 32 of gap
# between edges... too tight, hence r=30 and 100 spacing -> 40 gap.
# lines three 46-tall bars from x=488 to x=652, aligned to the hole rows.
_PUNCH_CARD = """\
<path fill="{{ACCENT}}" fill-rule="evenodd" stroke="none" d="\
M 396 232 L 732 232 L 732 792 L 292 792 L 292 336 Z \
M 392 346 A 30 30 0 0 0 392 406 A 30 30 0 0 0 392 346 Z \
M 392 446 A 30 30 0 0 0 392 506 A 30 30 0 0 0 392 446 Z \
M 392 546 A 30 30 0 0 0 392 606 A 30 30 0 0 0 392 546 Z \
M 392 646 A 30 30 0 0 0 392 706 A 30 30 0 0 0 392 646 Z \
M 500 356 L 652 356 L 652 396 L 500 396 Z \
M 500 496 L 652 496 L 652 536 L 500 536 Z \
M 500 636 L 652 636 L 652 676 L 500 676 Z"/>"""

View File

@ -109,6 +109,15 @@ APPS: Final[dict[str, AppIcon]] = {
# no GTK app to hand a hicolor PNG to.
linux=False,
),
AppIcon(
key="punchme",
repo=_HOME / "punchme",
accent="#B8862E",
glyph="punch-card",
icon_name="punchme",
# Android-only app: no GTK desktop build to hand a hicolor PNG to.
linux=False,
),
AppIcon(
key="habit_stack",
repo=_HOME / "habit_stack",

View File

@ -32,6 +32,7 @@ from python_pkg.app_icons._glyph_art import (
from python_pkg.app_icons._glyph_art_more import (
_NOTE_ASCENDER,
_PADLOCK_CLOSED,
_PUNCH_CARD,
_TRACK_BARS,
)
@ -60,6 +61,7 @@ GLYPHS: Final[dict[str, Glyph]] = {
Glyph("cloud-down", "Cloud with a download arrow", _CLOUD_DOWN),
Glyph("barbell", "Barbell with plates and collars", _BARBELL),
Glyph("clock", "Clock face with hands", _CLOCK),
Glyph("punch-card", "Time card with punched holes", _PUNCH_CARD),
Glyph("shield-cutlery", "Shield guarding a fork and knife", _SHIELD_CUTLERY),
Glyph("checklist", "Two ticked-off list rows", _CHECKLIST),
Glyph("chain-link", "Two interlocking chain links", _CHAIN_LINK),