|
30 | 30 | SKIP_SSH_KEYSCAN_OPTION="$(plugin_read_config SKIP_SSH_KEYSCAN "false")" |
31 | 31 | CLEAN_CHECKOUT_OPTION="$(plugin_read_config CLEAN_CHECKOUT "false")" |
32 | 32 |
|
| 33 | +MERGE_REF_RETRY_ATTEMPTS="$(plugin_read_config MERGE_REF_RETRY_ATTEMPTS "3")" |
| 34 | + |
33 | 35 | if [[ "${CLEAN_CHECKOUT_OPTION}" = "true" ]]; then |
34 | 36 | log_warning "clean_checkout is enabled - this will destroy any local changes and reset the repository state" |
35 | 37 | fi |
|
98 | 100 |
|
99 | 101 | FETCH_FLAGS+=(--depth 1 origin) |
100 | 102 |
|
| 103 | +FETCH_OUTPUT="" |
| 104 | + |
| 105 | +is_missing_merge_ref_error() { |
| 106 | + local merge_ref="refs/pull/${BUILDKITE_PULL_REQUEST}/merge" |
| 107 | + [[ "${FETCH_OUTPUT}" == *"couldn't find remote ref ${merge_ref}"* ]] \ |
| 108 | + || [[ "${FETCH_OUTPUT}" == *"not our ref ${merge_ref}"* ]] |
| 109 | +} |
| 110 | + |
| 111 | +# Try to fetch merge ref. Returns 0 on success, 1 if merge ref is missing (retry), |
| 112 | +# otherwise logs and exits with git's status. |
| 113 | +try_fetch_merge_ref() { |
| 114 | + local merge_ref="$1" |
| 115 | + if FETCH_OUTPUT=$(git fetch "${FETCH_FLAGS[@]}" "${merge_ref}" 2>&1); then |
| 116 | + [[ -n "${FETCH_OUTPUT}" ]] && printf '%s\n' "${FETCH_OUTPUT}" |
| 117 | + return 0 |
| 118 | + else |
| 119 | + local status=$? |
| 120 | + [[ -n "${FETCH_OUTPUT}" ]] && printf '%s\n' "${FETCH_OUTPUT}" >&2 |
| 121 | + if is_missing_merge_ref_error; then |
| 122 | + return 1 |
| 123 | + else |
| 124 | + log_error "Failed to fetch merge ref for PR #${BUILDKITE_PULL_REQUEST} from origin" |
| 125 | + exit "${status}" |
| 126 | + fi |
| 127 | + fi |
| 128 | +} |
| 129 | + |
101 | 130 | # Determine if we should use the pull request merge refspec |
102 | 131 | USE_MERGE_REFSPEC="false" |
103 | 132 | if [[ "${BUILDKITE_PULL_REQUEST_USING_MERGE_REFSPEC:-false}" = "true" ]] \ |
104 | 133 | && [[ -n "${BUILDKITE_PULL_REQUEST:-}" ]] \ |
105 | 134 | && [[ "${BUILDKITE_PULL_REQUEST}" != "false" ]]; then |
106 | 135 | USE_MERGE_REFSPEC="true" |
107 | | - FETCH_FLAGS+=("refs/pull/${BUILDKITE_PULL_REQUEST}/merge") |
108 | | -elif [[ ${BUILDKITE_COMMIT} = "HEAD" ]]; then |
109 | | - FETCH_FLAGS+=("${BUILDKITE_BRANCH}") |
110 | | -else |
111 | | - FETCH_FLAGS+=("${BUILDKITE_COMMIT}") |
112 | | -fi |
| 136 | + MERGE_REF="refs/pull/${BUILDKITE_PULL_REQUEST}/merge" |
113 | 137 |
|
114 | | -if [[ "${USE_MERGE_REFSPEC}" = "true" ]]; then |
115 | 138 | log_info "Fetching merge ref for PR #${BUILDKITE_PULL_REQUEST} from origin" |
116 | | -else |
117 | | - log_info "Fetching ${BUILDKITE_COMMIT} from origin" |
| 139 | + |
| 140 | + fetch_succeeded=false |
| 141 | + for ((attempt = 1; attempt <= MERGE_REF_RETRY_ATTEMPTS; attempt++)); do |
| 142 | + if try_fetch_merge_ref "${MERGE_REF}"; then |
| 143 | + fetch_succeeded=true |
| 144 | + break |
| 145 | + fi |
| 146 | + |
| 147 | + if [[ "${attempt}" -lt "${MERGE_REF_RETRY_ATTEMPTS}" ]]; then |
| 148 | + if [[ "${attempt}" -eq 1 ]]; then |
| 149 | + log_warning "Merge ref ${MERGE_REF} was not available yet; retrying in 2s" |
| 150 | + sleep 2 |
| 151 | + else |
| 152 | + log_warning "Merge ref ${MERGE_REF} was not available yet; retrying in 5s" |
| 153 | + sleep 5 |
| 154 | + fi |
| 155 | + fi |
| 156 | + done |
| 157 | + |
| 158 | + if [[ "${fetch_succeeded}" != "true" ]]; then |
| 159 | + if [[ "${BUILDKITE_COMMIT}" = "HEAD" ]]; then |
| 160 | + log_warning "Merge ref ${MERGE_REF} was still unavailable; falling back to branch ${BUILDKITE_BRANCH}" |
| 161 | + else |
| 162 | + log_warning "Merge ref ${MERGE_REF} was still unavailable; falling back to ${BUILDKITE_COMMIT}" |
| 163 | + fi |
| 164 | + USE_MERGE_REFSPEC="false" |
| 165 | + fi |
118 | 166 | fi |
119 | | -if ! git fetch "${FETCH_FLAGS[@]}"; then |
120 | | - log_error "Failed to fetch ${BUILDKITE_COMMIT} from origin" |
121 | | - exit 1 |
| 167 | + |
| 168 | +if [[ "${USE_MERGE_REFSPEC}" != "true" ]]; then |
| 169 | + if [[ ${BUILDKITE_COMMIT} = "HEAD" ]]; then |
| 170 | + FETCH_FLAGS+=("${BUILDKITE_BRANCH}") |
| 171 | + else |
| 172 | + FETCH_FLAGS+=("${BUILDKITE_COMMIT}") |
| 173 | + fi |
| 174 | + |
| 175 | + log_info "Fetching ${BUILDKITE_COMMIT} from origin" |
| 176 | + if ! git fetch "${FETCH_FLAGS[@]}"; then |
| 177 | + log_error "Failed to fetch ${BUILDKITE_COMMIT} from origin" |
| 178 | + exit 1 |
| 179 | + fi |
122 | 180 | fi |
123 | 181 | log_success "Fetch completed successfully" |
124 | 182 |
|
|
144 | 202 | exit 1 |
145 | 203 | fi |
146 | 204 | fi |
147 | | - |
148 | 205 | log_success "Sparse checkout completed successfully" |
0 commit comments