Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/actions/git-fetch-retry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# git-fetch-retry

Composite action wrapping `git fetch` with HTTP/1.1 and bounded exponential
backoff. Durable follow-up to the runner-side global git config; use where a job
needs an `--unshallow` or extra fetch that has been observed to flake with
`curl 56` / `curl 92 HTTP/2 stream CANCEL` on the self-hosted Linux runners.

## Use

```yaml
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: ./.github/actions/git-fetch-retry
with:
args: "--unshallow"
retries: "5"
```

## Runner-side config (applied out-of-band on 198-1/-2/-3)

```
git config --global http.version HTTP/1.1
git config --global http.postBuffer 524288000
git config --global http.lowSpeedLimit 1000
git config --global http.lowSpeedTime 300
```

Revert (per host): `for k in version postBuffer lowSpeedLimit lowSpeedTime; do git config --global --unset http.$k; done`
37 changes: 37 additions & 0 deletions .github/actions/git-fetch-retry/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: "git-fetch-retry"
description: "Resilient git fetch/unshallow: pins HTTP/1.1 and retries with bounded exponential backoff. Guards against intermittent self-hosted egress faults (curl 56 Recv failure / curl 92 HTTP/2 stream CANCEL) seen during actions/checkout --unshallow on c2pool-linux-198-*."
inputs:
args:
description: "Arguments passed verbatim to 'git fetch' (e.g. '--unshallow', 'origin master')."
required: false
default: "--unshallow"
retries:
description: "Maximum attempts before the step fails."
required: false
default: "5"
initial-delay:
description: "Seconds to wait before the first retry; doubles each attempt."
required: false
default: "5"
runs:
using: "composite"
steps:
- shell: bash
run: |
set -uo pipefail
# Belt-and-suspenders: also pin at job scope in case a runner lost the global config.
git config --global http.version HTTP/1.1
git config --global http.postBuffer 524288000
git config --global http.lowSpeedLimit 1000
git config --global http.lowSpeedTime 300
n=0; max="${{ inputs.retries }}"; delay="${{ inputs.initial-delay }}"
until git fetch ${{ inputs.args }}; do
n=$((n+1))
if [ "$n" -ge "$max" ]; then
echo "::error::git fetch ${{ inputs.args }} failed after ${max} attempts"
exit 1
fi
echo "::warning::git fetch attempt ${n}/${max} failed (transient egress); retrying in ${delay}s"
sleep "${delay}"
delay=$((delay*2))
done
Loading