ci: bound and retry the Gitee mirror push

Gitee's SSH gateway intermittently accepts the connection and key, then never
answers the initial git-receive-pack and drops the session ~100s later with
"the remote end hung up upon initial contact". The same failure mode shows up
sporadically since 2026-10-02 and spiked on 2026-10-07 (9 of 14 runs failed).

Bound each push attempt with `timeout`, retry up to six times with exponential
backoff, and add ssh connect/keepalive timeouts. Serialize runs (a push to main
and a tag on the same commit used to race for Gitee's per-repo push lock), cap
the job at 30 minutes, and allow manual workflow_dispatch reruns.
This commit is contained in:
Ryan Yin committed 2026-10-07 19:02:46 +08:00
1 parent 8f065f24bc
commit 94312fc2e5
1 file changed
+34 -2
+34 -2
View File
@@ -5,13 +5,21 @@ on:
- main - main
tags: tags:
- "*" - "*"
workflow_dispatch:
permissions: permissions:
contents: read contents: read
# A push to main and a tag on the same commit each trigger a run. Queue them so
# two runs never race for Gitee's per-repo push lock.
concurrency:
group: mirror-to-gitee
cancel-in-progress: false
jobs: jobs:
mirror: mirror:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 30
steps: steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5 - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
with: with:
@@ -38,6 +46,30 @@ jobs:
echo "$INPUT_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa echo "$INPUT_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa
export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$HOME/.ssh/known_hosts" export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$HOME/.ssh/known_hosts -o ConnectTimeout=20 -o ServerAliveInterval=20 -o ServerAliveCountMax=3"
git remote add mirror "$INPUT_TARGET_REPO_URL" git remote add mirror "$INPUT_TARGET_REPO_URL"
git push --tags --force --prune mirror "refs/remotes/origin/*:refs/heads/*"
# Gitee's SSH gateway intermittently accepts the connection and key,
# then never answers the initial git-receive-pack and drops the
# session about 100s later ("the remote end hung up upon initial
# contact"). Bound each attempt so a stuck session cannot hang the
# job, and retry with backoff.
attempts=6
for attempt in $(seq 1 "$attempts"); do
echo "::group::Mirror attempt $attempt/$attempts"
if timeout --kill-after=15s 120s \
git push --tags --force --prune mirror "refs/remotes/origin/*:refs/heads/*"; then
echo "::endgroup::"
echo "Mirrored to Gitee on attempt $attempt"
exit 0
fi
echo "::endgroup::"
if [ "$attempt" -lt "$attempts" ]; then
delay=$((15 * 2 ** (attempt - 1)))
echo "Attempt $attempt failed; retrying in ${delay}s"
sleep "$delay"
fi
done
echo "::error::failed to mirror to Gitee after $attempts attempts" >&2
exit 1