diff --git a/README.md b/README.md index 6ded8ab..8ccec50 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,12 @@ the GitOps target so ArgoCD can sync it. 3. Run `kustomize build .` to validate the manifests still render. **Fails the workflow if validation breaks** — apps repo is left untouched. 4. If no diff (apps repo already on this tag): exit 0 silently. -5. Otherwise commit + push to `main`. On push rejection (concurrent CI race), +5. Query the Gitea API for open PRs in the apps repo. If any open PR modifies + the same `kustomization.yaml` and its patch contains the target tag, exit 0 + — the PR is the intended control gate and the direct push is skipped. Fails + open on API errors (push proceeds) to avoid blocking deploys during an + outage. +6. Otherwise commit + push to `main`. On push rejection (concurrent CI race), `git pull --rebase` and retry up to 3 times with linear backoff. ## Notes diff --git a/action.yaml b/action.yaml index 5fdf517..9a0b97c 100644 --- a/action.yaml +++ b/action.yaml @@ -67,6 +67,37 @@ runs: exit 0 fi + # Detect an open PR already targeting the same image:tag in the same + # kustomization.yaml. If one is open, defer to it so the review gate + # is the actual control path — not a race with the direct push. + GITEA_HOST="${APPS_REPO%%/*}" + GITEA_REPO_PATH="${APPS_REPO#*/}" + GITEA_API="https://${GITEA_HOST}/api/v1" + KUSTOMIZATION_FILE="${PATH_IN_REPO}/kustomization.yaml" + + BLOCKING_PR="" + PR_NUMS=$(curl -sf -H "Authorization: token ${TOKEN}" \ + "${GITEA_API}/repos/${GITEA_REPO_PATH}/pulls?state=open&limit=50" \ + | jq -r '.[].number' 2>/dev/null || true) + + for pr_num in $PR_NUMS; do + FILES_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \ + "${GITEA_API}/repos/${GITEA_REPO_PATH}/pulls/${pr_num}/files" || echo "[]") + if echo "$FILES_JSON" | jq -e \ + --arg f "$KUSTOMIZATION_FILE" \ + --arg t "$TAG" \ + 'any(.[]; .filename == $f and (.patch // "" | contains($t)))' \ + > /dev/null 2>&1; then + BLOCKING_PR="$pr_num" + break + fi + done + + if [ -n "$BLOCKING_PR" ]; then + echo "PR #${BLOCKING_PR} is open and already targets ${NAME}:${TAG} in ${KUSTOMIZATION_FILE}; deferring to PR" + exit 0 + fi + git -C "$WORK" add "${PATH_IN_REPO}/kustomization.yaml" git -C "$WORK" commit -m "$MSG"