Merge pull request '[bug-nxhza9j2atqk] image-deploy: skip direct push when open PR already targets same tag' (#1) from dev/bug-nxhza9j2atqk/skip-direct-push-when-pr-open into main
validate / validate (push) Successful in 4s
validate / validate (push) Successful in 4s
This commit was merged in pull request #1.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
name: validate
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: fritzlab
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: check action.yaml exists and has required fields
|
||||
run: |
|
||||
set -euo pipefail
|
||||
test -f action.yaml || { echo "FATAL: action.yaml missing"; exit 1; }
|
||||
grep -q "^name:" action.yaml
|
||||
grep -q "^runs:" action.yaml
|
||||
echo "action.yaml OK"
|
||||
@@ -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
|
||||
|
||||
+31
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user