clone test repo CI job retry loop silently never retries (bash brace expansion in alpine sh)

Summary

The clone test repo job's retry loop in .gitlab/ci/build.gitlab-ci.yml never actually retries, because {1..3} brace expansion is a bash-ism that doesn't work in the job's actual shell (alpine:latest's default /bin/sh, BusyBox ash). On any transient network failure, the job fails immediately after a single attempt instead of retrying up to 3 times as intended.

Location

.gitlab/ci/build.gitlab-ci.yml, job clone test repo:

clone test repo:
  ...
  image: alpine:latest
  script:
    - apk add git
    - mkdir tmp
    - succeed=0
    - for i in {1..3}; do git clone https://gitlab.com/gitlab-org/ci-cd/gitlab-runner-pipeline-tests/gitlab-test tmp/gitlab-test && succeed=1 && break; echo "retrying"; done
    - '[[ "$succeed" -eq 1 ]]'

Root cause

{1..3} brace expansion is a bash extension, not POSIX sh syntax. Since the job image is alpine:latest and script steps run under /bin/sh (BusyBox ash), {1..3} is never expanded — $i is literally the string {1..3}, so the for loop body executes exactly once regardless of how many failures occur. The retry logic is a silent no-op.

Separately, [[ "$succeed" -eq 1 ]] is also a bashism ([[ ]] isn't supported in ash), though in this case it happens to still work because ash falls back to treating it as an external/builtin [[ command in some BusyBox configurations — worth double-checking as part of any fix, since it's the same class of bug.

Reproduction

$ docker run --rm alpine:latest sh -c '
for i in {1..3}; do
  echo "iteration: i=$i"
  false && break
  echo "retrying"
done
'
iteration: i={1..3}
retrying

The loop runs once, with $i literally set to {1..3}, instead of iterating 3 times.

Real-world impact

Observed directly in CI: job https://gitlab.com/gitlab-org/gitlab-runner/-/jobs/15192866876 (on !6924, unrelated MR) hit a transient ~2 minute network timeout connecting to gitlab.com:443 during git clone. The trace shows exactly one Cloning into '...' attempt before the job failed — consistent with the retry loop only ever running once. Had the retry logic worked as intended, this transient network blip likely would have been absorbed by a second or third attempt instead of failing the whole job (and cascading into skipping most of the rest of that pipeline's test stage jobs, since clone test repo is a dependency).

Suggested fix

Replace the bash-only construct with a POSIX-compatible loop, e.g.:

succeed=0
i=1
while [ "$i" -le 3 ]; do
  git clone https://gitlab.com/gitlab-org/ci-cd/gitlab-runner-pipeline-tests/gitlab-test tmp/gitlab-test && succeed=1 && break
  echo "retrying"
  i=$((i + 1))
done
[ "$succeed" -eq 1 ]

Priority

Low — this doesn't block MRs under normal conditions (the underlying network issue is itself rare), but it does mean the one mitigation this job has for transient network flakiness has been silently non-functional, making the job more fragile than intended whenever gitlab.com connectivity hiccups occur.