Skip to content

fork-ci: ci-demand follow-ups (cache write failure shown, BOM, NaN date, tests) - #141

Draft
scuttletoby wants to merge 1 commit into
mainfrom
fork/ci-demand-fu
Draft

scuttletoby wants to merge 1 commit into
mainfrom
fork/ci-demand-fu

Conversation

@scuttletoby

@scuttletoby scuttletoby commented Nov 15, 2026 •

Copy link
Copy Markdown
Owner

Fixes #120
Fixes #121
Fixes #122
Fixes #123
Fixes #124

Follow-ups from the quick-check review of #113 (#113 (comment)), all in fork-ci/actions/ci-demand/.

What changes

Tests

python3 -I -B fork-ci/actions/ci-demand/ci_demand.test.py (GitHub faked, no token, empty gh config): 41 tests, all pass (36 before). Red first: before the fix, the new or extended tests for #120, #122 and #123 failed (2 failures, 2 errors).

Mutation check (each change applied alone, then the suite run): all 8 are caught. These are: no private refusal, reserve fallback 0, gh without encoding='utf-8', the config without an encoding, the config as plain utf-8 (BOM), no isfinite, no cache_write_failed in the JSON, and the "run again" hint shown even after a failed write.

The reviewer's own round-2 test file: the cache-write and BOM tests pass. Its NaN test expects 2 requests, but it puts NaN into every cache file, including the 4 jobs pages. With the agreed fix, all 6 count as damaged, so 6 requests is right; the folded test checks that.

State question

"What happens when this runs again, stops half-way, or meets existing/old/empty/corrupt state?"

  • Runs again: pages saved by a working cache are read back as before. When the cache could not be written, the result now says so instead of promising a resume.
  • Stops half-way: unchanged (exit 3, INCOMPLETE). The resume hint is shown only when something could have been saved.
  • Existing/old state: cache files of earlier runs of this version stay valid (same format, no FORMAT bump). A file with a NaN or -Infinity date, which only hand damage can cause, is fetched again once and then saved correctly. An existing config with a BOM now works. A config without one reads as before.
  • Empty/corrupt: an empty cache folder works as before. Corrupt files are fetched again, never a crash. A folder that cannot be made private is still refused before any request (now tested).

General vs project

All general: the tool, its tests and its README name no project. Project facts stay where they were: the repository (--repo or ciDemand.repo in the project's own config) and the cache folder the caller picks.

🤖 Generated with Claude Code

…te, tests)

- A cache that cannot be written is in the result: `cache_write_failed` in
  --json and in the first line; a stop then does not say "run again with
  the same --cache" (nothing was saved) but "fix --cache first".
- The config file is read as utf-8-sig, so a BOM is fine.
- A cache date that is NaN or -Infinity counts as damaged and the page is
  fetched again (json.load reads both).
- New tests for four lines no test caught: the "cannot be made private"
  refusal, the 1000 reserve when X-RateLimit-Limit is missing, and UTF-8
  for gh output and the config file (the script run in the C locale with
  UTF-8 mode off). The fake gh now writes UTF-8 bytes, like the real one,
  and can leave a header out.
- README: the cache folder must allow private permissions on Linux and
  macOS (FAT, WSL /mnt/c are refused), and the new result field.

Fixes #120
Fixes #121
Fixes #122
Fixes #123
Fixes #124

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment