Skip to content

fix(sync): bounded retry on force-with-lease rejection in commit_and_push_translations_branch - #70

Merged
wpak-ai merged 4 commits into
cppalliance:masterfrom
timon0305:fix/force-with-lease-retry-63
Jul 31, 2026
Merged

fix(sync): bounded retry on force-with-lease rejection in commit_and_push_translations_branch#70
wpak-ai merged 4 commits into
cppalliance:masterfrom
timon0305:fix/force-with-lease-retry-63

Conversation

@timon0305

@timon0305 timon0305 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Closes #63

Problem

commit_and_push_translations_branch (.github/workflows/assets/lib.sh) pushed translation branches with a single git push --force-with-lease. When the lease was rejected because the remote advanced concurrently, it failed fast with the existing phase_err, so a transient concurrent advance during the daily scheduled run failed the whole run even though fetching and re-attempting would succeed.

What changed

  • On a rejected force-with-lease, retry up to 3 attempts, running git fetch for the branch between attempts so the local ref reflects the advanced remote before re-attempting.
  • After the final attempt still fails, surface the existing rejection error unchanged (fail closed).
  • The bats fail-fast test is replaced by two: the push succeeds after a transient rejection, and still fails (with the unchanged error) after the retries are exhausted. install_git_push_pre_hook gained an optional injection cap to simulate a transient rejection.

Full bats suite passes locally (132).

Note: because each retry fetches before re-pushing, the retry refreshes the lease and overwrites the concurrent advance. That is intended here since these local-<lang> branches are bot-regenerated each run.

Summary by CodeRabbit

  • Bug Fixes
    • Improved translation branch updates to safely handle concurrent remote changes with up to three retries.
    • Remote state is refreshed between attempts to help prevent overwriting newer changes.
    • Operations now fail promptly with clearer errors when required Git capabilities are unavailable or fetching fails.
    • Retry failures now report the final remote revision and push status for easier diagnosis.
  • Tests
    • Expanded coverage for concurrent updates, fetch failures, retry exhaustion, and unsupported Git features.

commit_and_push_translations_branch pushed translation branches with a single
git push --force-with-lease and failed fast when the lease was rejected by a
concurrent advance, failing the whole daily run on a transient race.

Retry the push up to 3 times, running git fetch for the branch between attempts
so the local ref reflects the advanced remote before re-attempting, and surface
the existing rejection error unchanged once the attempts are exhausted (fail
closed). The bats fixture gains an optional injection cap so a test can simulate
a transient rejection; the fail-fast test is replaced by two covering retry-then-
succeed and fail-after-exhaustion.
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 80fd593a-1a02-4a77-a303-74c47559d55c

📥 Commits

Reviewing files that changed from the base of the PR and between 3e3946f and d0598e4.

📒 Files selected for processing (4)
  • .github/workflows/assets/lib.sh
  • .github/workflows/sync-translation.yml
  • tests/helpers/git_fixtures.bash
  • tests/test_lib.bats
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/assets/lib.sh
  • tests/test_lib.bats

📝 Walkthrough

Walkthrough

The translation branch push now requires force-if-includes, retries rejected protected pushes up to three times with branch fetches between attempts, and reports fetch failures separately. Fixtures and tests cover concurrency, retry exhaustion, fetch failures, and unsupported Git versions.

Changes

Translation push safety

Layer / File(s) Summary
Protected bounded push flow
.github/workflows/assets/lib.sh, .github/workflows/sync-translation.yml
Adds Git capability probes, combines force-if-includes with force-with-lease, retries rejected pushes after branch fetches, and routes translation updates through the shared helper.
Controlled concurrent advance fixtures
tests/helpers/git_fixtures.bash
Limits injected remote advances, records injection attempts, supports branch-fetch failures, cleans hook state, and simulates missing push options.
Concurrency and capability validation
tests/test_lib.bats
Verifies concurrent commits remain at the remote tip, retry exhaustion reports the final failure, fetch errors retain their cause, and unsupported Git versions produce clear errors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant commit_and_push_translations_branch
  participant GitRemote
  participant ConcurrentWriter
  commit_and_push_translations_branch->>commit_and_push_translations_branch: detect force-if-includes support
  commit_and_push_translations_branch->>GitRemote: protected force push
  ConcurrentWriter->>GitRemote: advance branch
  GitRemote-->>commit_and_push_translations_branch: lease rejection
  commit_and_push_translations_branch->>GitRemote: fetch origin/branch
  commit_and_push_translations_branch->>GitRemote: retry protected force push
  GitRemote-->>commit_and_push_translations_branch: success or final rejection
Loading

Suggested reviewers: wpak-ai, whisper67265

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the bounded retry behavior for force-with-lease rejection in the affected helper.
Linked Issues check ✅ Passed The changes implement bounded retries, branch fetches, final rejection handling, and test coverage required by issue [#63].
Out of Scope Changes check ✅ Passed The capability probes, sync-local routing, force-if-includes support, and tests directly support the stated retry and push-safety objectives.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Comment thread .github/workflows/assets/lib.sh
The bounded retry fetched then re-pushed with --force-with-lease, which after
the fetch could overwrite a concurrent commit that was never integrated. Add
--force-if-includes (Git 2.30+) so the retry still rejects an unintegrated
remote advance: a spurious rejection retries to success, a real concurrent
commit fails closed instead of being silently overwritten.

Guard force-if-includes support with a clear "requires Git 2.30+" error, and
cover it plus the not-overwritten behavior with bats tests.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/assets/lib.sh:
- Line 217: Update the retry loop using local variables push_rc, remote_sha,
attempt, and max_attempts so each git fetch failure is detected and handled
immediately instead of discarded. Do not continue attempting pushes without a
refreshed tracking ref; preserve the fetch failure status/details for the final
diagnostic rather than reporting it as a concurrent-advance rejection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 49f5b6a4-1118-4a7f-8c01-dc35607b3f65

📥 Commits

Reviewing files that changed from the base of the PR and between 99b07b8 and fd116e8.

📒 Files selected for processing (3)
  • .github/workflows/assets/lib.sh
  • tests/helpers/git_fixtures.bash
  • tests/test_lib.bats
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/helpers/git_fixtures.bash

Comment thread .github/workflows/assets/lib.sh Outdated
The retry loop discarded git fetch failures, so an auth/network fetch failure
left the tracking ref stale and was misreported as a concurrent-advance
rejection. Surface the real cause and return the fetch exit code instead. Cover
it with a bats test via an opt-in fetch-failure flag on the push hook.
@timon0305
timon0305 requested a review from whisper67265 July 30, 2026 15:51
@whisper67265
whisper67265 requested a review from wpak-ai July 30, 2026 17:21

@wpak-ai wpak-ai left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. tests/helpers/git_fixtures.bash:171-176, tests/test_lib.bats:476 - make the install_git_without_force_if_includes shim exit 129 like real git push -h, and run the capability-probe tests under set -o pipefail

  2. .github/workflows/sync-translation.yml:142, .github/workflows/assets/lib.sh:215 - have the sync-local job call commit_and_push_translations_branch, which it already has in scope via the lib.sh source at line 112, instead of open-coding a bare git push --force-with-lease origin "HEAD:$branch"

Comment thread .github/workflows/assets/lib.sh
Comment thread .github/workflows/assets/lib.sh
Comment thread tests/helpers/git_fixtures.bash Outdated
Comment thread tests/test_lib.bats Outdated
@timon0305

Copy link
Copy Markdown
Contributor Author
  • tests/helpers/git_fixtures.bash:171-176, tests/test_lib.bats:476 - make the install_git_without_force_if_includes shim exit 129 like real git push -h, and run the capability-probe tests under set -o pipefail
  • .github/workflows/sync-translation.yml:142, .github/workflows/assets/lib.sh:215 - have the sync-local job call commit_and_push_translations_branch, which it already has in scope via the lib.sh source at line 112, instead of open-coding a bare git push --force-with-lease origin "HEAD:$branch"

Both fixed. Capability probes: git push -h exits 129, so under pipefail the piped grep reported "not supported" even when the flag was present. Now they capture the help text first and grep it separately; made the shims exit 129 to match real git, ran the probe tests under pipefail, and added a positive probe test. sync-local now goes through commit_and_push_translations_branch instead of a bare git push --force-with-lease, so it gets the same bounded retry and --force-if-includes safety.

@timon0305
timon0305 requested a review from wpak-ai July 31, 2026 05:19
… the helper

Address review feedback on the force-with-lease retry:

- The force-with-lease/force-if-includes probes piped `git push -h` (exit 129)
  into grep, which under `set -o pipefail` (the workflows enable it) reported
  "not supported" even when the flag was present. Compute the probe from a
  captured `git push -h 2>&1 || true` variable via a shared git_push_help_mentions
  helper (no pipe). Test shims exit 129 like real git, the unsupported probes run
  under pipefail, and a positive test asserts both probes pass under pipefail.
- The sync-local job now calls commit_and_push_translations_branch instead of a
  bare `git push --force-with-lease`, so it gets the same retry + force-if-includes.
- Reword the injection-arg doc, capture stderr in the not-overwritten test, and
  dedup the two capability shims into install_git_without_flag.
@wpak-ai
wpak-ai merged commit 01fa10d into cppalliance:master Jul 31, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bounded retry on force-with-lease rejection in commit_and_push_translations_branch

3 participants