Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: labelle-org/labelle-web
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.6.4
Choose a base ref
...
head repository: labelle-org/labelle-web
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.6.5
Choose a head ref
  • 15 commits
  • 9 files changed
  • 2 contributors

Commits on May 18, 2026

  1. ci(pr-image): sweep predecessor image on each push

    Each PR push tags both `:pr-<N>` and `:<short-sha>`. When the next
    push lands, `:pr-<N>` moves to the new version but the prior version
    keeps its SHA tag — and the on-close cleanup only deletes whatever is
    tagged `:pr-<N>` at close time. The result was N versions per PR
    accumulating in GHCR (one per commit).
    
    Capture the version IDs currently tagged `:pr-<N>` before the build,
    then delete them after the push succeeds. GHCR now holds exactly one
    image per active PR; the on-close cleanup still handles the final one.
    
    No version bump — workflow file doesn't ship in the image.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 18, 2026
    Configuration menu
    Copy the full SHA
    44e19d4 View commit details
    Browse the repository at this point in the history
  2. ci(pr-image): address Copilot review feedback on predecessor sweep

    Three fixes from PR #32 review, applied to both the build-time sweep
    and the on-close cleanup since they share the same pattern:
    
    1. Null-safe the tags filter (`(.metadata.container.tags // [])`)
       so a future GHCR API change that returns null instead of `[]`
       for untagged versions doesn't error out the whole query.
    
    2. Stop swallowing real failures with `|| true`. Only HTTP 404 is
       expected (brand-new PR with no image yet, or PR closed before
       any successful build); auth/permission/rate-limit errors now
       fail the job rather than silently leaving orphans behind.
    
    3. Re-query post-push and delete only versions that were tagged
       `:pr-<N>` pre-build AND are no longer tagged post-push. Without
       this, a workflow re-run on the same commit (manifest digest
       unchanged → tag stays on the existing version ID) would delete
       the only image for the PR.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 18, 2026
    Configuration menu
    Copy the full SHA
    14ecd17 View commit details
    Browse the repository at this point in the history
  3. ci(pr-image): sweep child manifests alongside parent (closes #33)

    Both the build-time predecessor sweep and the on-close cleanup were
    deleting only the parent OCI image index — GHCR doesn't cascade-delete
    the per-arch image manifests and provenance attestation manifests it
    references, so every multi-arch build leaked ~4 untagged versions.
    
    Extracted the manifest-walk + delete logic into
    `.github/scripts/sweep-ghcr-versions.sh`, shared by both call sites.
    For each parent version: look up its digest in a snapshot of the
    versions API, fetch the manifest from the GHCR registry, map child
    digests back to version IDs, and delete children + parent in one
    pass. Single-arch manifests (no `.manifests` array) and registry
    404s on the manifest fetch degrade gracefully to parent-only delete
    with a warning; any other registry error fails the job.
    
    The on-close cleanup job gains a sparse-checkout of `.github/scripts`
    so the script is available there too.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 18, 2026
    Configuration menu
    Copy the full SHA
    61b6fb5 View commit details
    Browse the repository at this point in the history
  4. ci(pr-image): fix empty-IDS gate and cleanup checkout for stacked PRs

    Two more Copilot findings on the sweep workflow:
    
    1. The `ids` step output was being written via `echo "$IDS"` even
       when IDS is empty, leaving a stray newline in the output value.
       That makes `steps.predecessors.outputs.ids != ''` truthy on a
       brand-new PR's first build, so the delete step runs and its
       unguarded versions API call 404s. Fix: write `ids=` when IDS is
       empty so the gate behaves as intended.
    
    2. The on-close cleanup checkout used `pull_request.base.ref`, which
       on a stacked PR points at another feature branch that may not
       contain the sweep script yet. Use `github.sha` instead so the
       script always matches the workflow we're executing.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 18, 2026
    Configuration menu
    Copy the full SHA
    1eb4c28 View commit details
    Browse the repository at this point in the history
  5. Merge pull request #32 from szrudi/ci/cleanup-pr-image-predecessors

    ci(pr-image): sweep predecessor image on each push
    szrudi authored May 18, 2026
    Configuration menu
    Copy the full SHA
    ee677a8 View commit details
    Browse the repository at this point in the history

Commits on May 22, 2026

  1. fix(usb-power): handle missing uhubctl without 500-spam

    Local dev outside Docker doesn't have uhubctl on PATH. Without it,
    every /api/power/status poll raised FileNotFoundError out of
    find_or_recall_printer_port() — *before* the endpoint's try/except
    caught it — and the frontend retried, producing a wall of tracebacks
    on every page open.
    
    Now:
    - _run() logs a single WARNING the first time uhubctl isn't found,
      then re-raises FileNotFoundError unchanged
    - find_printer_port() catches FileNotFoundError and returns None, so
      _printer_port_or_404 returns a clean 404 "Printer not detected"
    
    The frontend already treats 404 as "hide the power-toggle UI" (see
    PowerToggle.tsx:6-10), so this works without any client change.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    605cb09 View commit details
    Browse the repository at this point in the history
  2. fix(usb-power): bypass port cache when uhubctl is missing (review)

    Address Copilot review on #36:
    
    If state.json from a prior run on a uhubctl-equipped host has saved
    _last_known_port, the previous version of find_or_recall_printer_port
    would fall back to the cached port even when uhubctl had been removed.
    The endpoint would then proceed to get_port_status()/power_*, which
    also shell out via _run() → another FileNotFoundError → 500 with
    traceback. Same symptom this PR aims to eliminate.
    
    - find_printer_port now propagates FileNotFoundError (no longer hides
      it as None). Cleaner contract: the function does what it says.
    - find_or_recall_printer_port catches FileNotFoundError → returns
      None, explicitly bypassing _last_known_port. /api/power/* then
      renders the same clean 404 as the no-cache path.
    - Regression test test_find_or_recall_bypasses_cache_when_uhubctl_missing
      exercises the previously-broken scenario.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    473ee9a View commit details
    Browse the repository at this point in the history
  3. fix(usb-power): generalize uhubctl-missing warning wording (review)

    Address Copilot review: the previous message said "uhubctl not found on
    PATH", which is misleading when UHUBCTL_BIN is set to an explicit path
    that doesn't exist (no PATH lookup happens in that case). The new
    wording is true for both scenarios and points at the env var as an
    alternative remedy.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    28b8b4f View commit details
    Browse the repository at this point in the history
  4. docs(usb-power): explain unlocked _uhubctl_missing_logged race trade-off

    Copilot flagged the missing lock on the log-once latch. The race is
    real but benign (microsecond window, self-limiting, max N duplicate
    log lines per process lifetime) — same character of trade-off as the
    existing unlocked _last_known_port. Document the choice in-place so
    future readers don't have to re-derive it.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    c15bf9c View commit details
    Browse the repository at this point in the history
  5. fix(printer-service): swallow DeviceManagerNoDevices traceback in lis…

    …t_printers
    
    list_printers() catches all scan exceptions and dumps a full traceback,
    but labelle raises DeviceManagerNoDevices as its normal "no DYMO
    plugged in" signal — so every /api/printers call on a host without a
    printer was logging a 5-line stack trace.
    
    Catch DeviceManagerNoDevices specifically and surface it as a single
    INFO line per scan. Other unexpected exceptions still print a
    traceback so genuine USB-stack failures don't get swallowed silently.
    
    No latch: scans are user-triggered (page load / manual refresh), not
    polled, and plug/unplug should be observable in the log.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    213e656 View commit details
    Browse the repository at this point in the history
  6. fix(server): configure root logging at INFO so service messages are v…

    …isible
    
    Adding logger.info() in printer_service was effectively dead code in
    production: Python's default root logger threshold is WARNING, so INFO
    was silently dropped. Tests passed because pytest's caplog captures at
    any level via propagation, regardless of root level — a misleading
    green light.
    
    Set logging.basicConfig in app.py before any module-level logger fires.
    Default level INFO so service diagnostics show up; honor LOG_LEVEL env
    var so production can dial it up or down.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    d7a99ff View commit details
    Browse the repository at this point in the history
  7. fix(server): tune log defaults — WARNING in prod, DEBUG via .env.exam…

    …ple in dev
    
    Earlier commit defaulted to INFO; the user point is that production
    should be quieter and dev should be even chattier. Net result:
    
    - app.py default LOG_LEVEL = WARNING (production-safe — operators only
      see things worth looking at, no noise from "no DYMO detected" INFO
      on every page load).
    - .env.example sets LOG_LEVEL=DEBUG so `npm run dev` is verbose via the
      template that fresh contributors copy.
    
    Also picks up Copilot's docstring nit: find_printer_port now says "the
    uhubctl executable can't be found", matching the more general warning
    wording instead of the over-narrow "isn't on PATH".
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    a2cf3ed View commit details
    Browse the repository at this point in the history
  8. fix(server): defensive LOG_LEVEL parsing so bad input doesn't crash s…

    …tartup
    
    Copilot review: passing an unrecognized string (typo like INFOO, or
    numeric like "20") to logging.basicConfig(level=...) raises ValueError
    at import time, preventing the server from starting. Easy to introduce
    in production via a misedit of .env.
    
    Resolve LOG_LEVEL via getattr with an isinstance(int) check; fall back
    to WARNING when the value doesn't resolve to a logging level constant.
    After logging is configured, surface the bad input as a single WARNING
    so operators see it without the server failing.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    438bd14 View commit details
    Browse the repository at this point in the history
  9. chore: bump to 1.6.5

    PATCH bump: server-side dev-console cleanups (missing-uhubctl 500-spam
    gone, DeviceManagerNoDevices traceback gone, defensive LOG_LEVEL
    parsing). No user-visible behavior change for the happy path.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    szrudi and claude committed May 22, 2026
    Configuration menu
    Copy the full SHA
    58e314a View commit details
    Browse the repository at this point in the history
  10. Merge pull request #36 from szrudi/fix/uhubctl-missing-graceful

    fix(server): handle missing uhubctl + missing DYMO without traceback spam
    szrudi authored May 22, 2026
    Configuration menu
    Copy the full SHA
    a2c46c2 View commit details
    Browse the repository at this point in the history
Loading