test: the release scripts' stand-in gh is safe when two calls run at once (flaky JSONDecodeError) #2130

Merged
NotRexed merged 1 commit from test/fake-gh-atomic into main 2026-11-11 04:32:06 +00:00
NotRexed commented 2026-11-11 04:27:43 +00:00 (Migrated from github.com)

tests/test_release_scripts.py fails now and then on Linux, as it did on main at 364d1994 and on #2127. The failing test is test_tag_pushed_by_hand_gets_its_release_and_sums; the stand-in gh hits json.decoder.JSONDecodeError: Expecting value: line 1 column 1 when it reads its state file.

The cause: scripts/release_files.sh check runs two gh calls at the same time (cmp -s <(sums "$id") <(uploaded "$id")). Every stand-in call appends itself to calls and rewrites the state file with open(STATE, "w"). So one call can read the file while the other has just truncated it.

The stand-in now:

  • holds an exclusive fcntl lock for the whole call, so calls take turns and no entry in calls is lost;
  • writes its state to a temporary file and moves it into place with os.replace.

The test is the only thing changed; the release scripts stay as they are. It needs jq and only runs on Linux, so this was not run locally; CI checks it.

🤖 Generated with Claude Code

`tests/test_release_scripts.py` fails now and then on Linux, as it did on main at 364d1994 and on #2127. The failing test is `test_tag_pushed_by_hand_gets_its_release_and_sums`; the stand-in `gh` hits `json.decoder.JSONDecodeError: Expecting value: line 1 column 1` when it reads its state file. The cause: `scripts/release_files.sh check` runs two `gh` calls at the same time (`cmp -s <(sums "$id") <(uploaded "$id")`). Every stand-in call appends itself to `calls` and rewrites the state file with `open(STATE, "w")`. So one call can read the file while the other has just truncated it. The stand-in now: - holds an exclusive `fcntl` lock for the whole call, so calls take turns and no entry in `calls` is lost; - writes its state to a temporary file and moves it into place with `os.replace`. The test is the only thing changed; the release scripts stay as they are. It needs `jq` and only runs on Linux, so this was not run locally; CI checks it. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Commenting is not possible because the repository is archived.
No description provided.