mirror of
https://github.com/nubenetes/awesome-kubernetes.git
synced 2026-07-12 09:51:00 +00:00
ci: harden develop write-path against races & make PR Guardian advisory
Root cause of the recurring README-sync failure: 05.1 modified README.md in earlier steps then ran `git pull`, which aborts on a dirty tree whenever a concurrent bot commit advanced develop first. Rewrote its commit step as a fetch → reset --hard → regenerate → commit → push retry loop (README is a pure function of inventory, so a hard reset never loses data and eliminates the merge-conflict / --ours/--theirs class entirely). Also: - 03.1/03.2/03.3: wrap the single-shot pull --rebase && push in a 5x retry loop. - 07.1 PR Guardian: continue-on-error (advisory; keeps the comment, drops the blocking red ❌ on AI false positives) + PR-scoped concurrency. - 07.2 Markdown Linter: PR/branch-scoped concurrency with cancel-in-progress. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -66,8 +66,12 @@ jobs:
|
||||
echo "No changes in inventory to commit."
|
||||
else
|
||||
git commit -m "chore: update inventory stars and licenses [skip ci]"
|
||||
git pull origin develop --rebase
|
||||
git push origin develop
|
||||
# Retry rebase+push to survive concurrent bot pushes to develop.
|
||||
for i in {1..5}; do
|
||||
git pull origin develop --rebase && git push origin develop && exit 0
|
||||
echo "Push attempt $i/5 rejected — retrying..."; sleep $((i * 3))
|
||||
done
|
||||
echo "::error::Inventory metadata push failed after 5 attempts."; exit 1
|
||||
fi
|
||||
|
||||
- name: Persist Incremental Inventory to Cache
|
||||
|
||||
8
.github/workflows/03.2.agentic_v2_ai.yml
vendored
8
.github/workflows/03.2.agentic_v2_ai.yml
vendored
@@ -80,8 +80,12 @@ jobs:
|
||||
echo "No changes in AI analysis to commit."
|
||||
else
|
||||
git commit -m "chore: update inventory AI analysis"
|
||||
git pull origin develop --rebase
|
||||
git push origin develop
|
||||
# Retry rebase+push to survive concurrent bot pushes to develop.
|
||||
for i in {1..5}; do
|
||||
git pull origin develop --rebase && git push origin develop && exit 0
|
||||
echo "Push attempt $i/5 rejected — retrying..."; sleep $((i * 3))
|
||||
done
|
||||
echo "::error::Inventory AI-analysis push failed after 5 attempts."; exit 1
|
||||
fi
|
||||
|
||||
- name: Persist Incremental Inventory to Cache
|
||||
|
||||
8
.github/workflows/03.3.agentic_v2_videos.yml
vendored
8
.github/workflows/03.3.agentic_v2_videos.yml
vendored
@@ -90,8 +90,12 @@ jobs:
|
||||
echo "No automated changes to commit."
|
||||
else
|
||||
git commit -m "docs: update Video Hub with high-fidelity metadata"
|
||||
git pull origin develop --rebase
|
||||
git push origin develop
|
||||
# Retry rebase+push to survive concurrent bot pushes to develop.
|
||||
for i in {1..5}; do
|
||||
git pull origin develop --rebase && git push origin develop && exit 0
|
||||
echo "Push attempt $i/5 rejected — retrying..."; sleep $((i * 3))
|
||||
done
|
||||
echo "::error::Video Hub push failed after 5 attempts."; exit 1
|
||||
fi
|
||||
|
||||
- name: Persist Incremental Inventory Cache
|
||||
|
||||
51
.github/workflows/05.1.readme_sync.yml
vendored
51
.github/workflows/05.1.readme_sync.yml
vendored
@@ -59,38 +59,33 @@ jobs:
|
||||
git config --global user.name "Nubenetes Bot"
|
||||
git config --global user.email "bot@nubenetes.com"
|
||||
export PYTHONPATH=$PYTHONPATH:.
|
||||
# Pull latest before committing to shrink the conflict window
|
||||
git pull --no-rebase origin develop
|
||||
# Re-run updater so metrics reflect the latest remote state
|
||||
python src/readme_updater.py
|
||||
python src/safety_readme.py
|
||||
git add README.md
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes in README.md to commit."
|
||||
exit 0
|
||||
fi
|
||||
git commit -m "docs: automated README metric synchronization [skip ci]"
|
||||
# Push-first loop: try push, then merge-pull on rejection (not rebase)
|
||||
# Using merge avoids --ours/--theirs confusion that plagued the rebase approach
|
||||
# README.md is a *pure function* of the inventory, so we never need to
|
||||
# preserve a local README state: each attempt hard-resets to the freshest
|
||||
# remote tip, regenerates, commits and pushes. This eliminates the two
|
||||
# failure classes that previously broke this job:
|
||||
# 1. Dirty-tree abort — the earlier steps modify README.md, then
|
||||
# `git pull` aborted with "local changes would be overwritten by merge".
|
||||
# 2. Merge/rebase --ours/--theirs confusion under concurrent bot pushes.
|
||||
# A push can now only be rejected if the remote advanced between reset and
|
||||
# push; we simply retry from the new tip. No conflict resolution required.
|
||||
for i in {1..5}; do
|
||||
echo "Push attempt $i/5..."
|
||||
echo "README sync attempt $i/5..."
|
||||
git fetch origin develop
|
||||
git reset --hard origin/develop
|
||||
python src/readme_updater.py
|
||||
python src/safety_readme.py
|
||||
git add README.md
|
||||
if git diff --staged --quiet; then
|
||||
echo "README already in sync with inventory. Nothing to commit."
|
||||
exit 0
|
||||
fi
|
||||
git commit -m "docs: automated README metric synchronization [skip ci]"
|
||||
if git push origin develop; then
|
||||
echo "Push succeeded on attempt $i."
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i rejected — integrating remote changes via merge..."
|
||||
git fetch origin develop
|
||||
if ! git merge --no-edit -X ours origin/develop; then
|
||||
# Merge could not auto-resolve; keep bot's README and continue
|
||||
git checkout --ours README.md
|
||||
git add README.md
|
||||
GIT_EDITOR=true git merge --continue
|
||||
fi
|
||||
# Re-compute metrics on the merged state (idempotent)
|
||||
python src/readme_updater.py
|
||||
python src/safety_readme.py
|
||||
git add README.md
|
||||
git diff --staged --quiet || git commit --amend --no-edit
|
||||
echo "Attempt $i rejected — remote advanced, retrying from fresh tip..."
|
||||
sleep $((i * 3))
|
||||
done
|
||||
git push origin develop
|
||||
echo "::error::README sync failed after 5 attempts (persistent write contention on develop)."
|
||||
exit 1
|
||||
|
||||
10
.github/workflows/07.1.pr_guardian.yml
vendored
10
.github/workflows/07.1.pr_guardian.yml
vendored
@@ -10,6 +10,11 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
# Cancel superseded Guardian runs when a PR is updated (saves CI minutes + Gemini calls).
|
||||
concurrency:
|
||||
group: pr-guardian-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
agentic-presubmit:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -35,6 +40,11 @@ jobs:
|
||||
pip install --no-cache-dir pydantic PyGithub httpx fake-useragent pytz python-dotenv pyyaml tenacity
|
||||
|
||||
- name: Run PR Guardian Analysis
|
||||
# Advisory gate: the Guardian is an AI heuristic that can misattribute
|
||||
# pre-existing lines or mischaracterize a PR. It always posts its findings
|
||||
# as a PR comment, but a non-zero exit must NOT show the PR as a blocking
|
||||
# red ❌. continue-on-error keeps the check green while preserving the comment.
|
||||
continue-on-error: true
|
||||
env:
|
||||
GEMINI_API_KEY_1: ${{ secrets.GEMINI_API_KEY_1 }}
|
||||
GEMINI_API_KEY_2: ${{ secrets.GEMINI_API_KEY_2 }}
|
||||
|
||||
5
.github/workflows/07.2.markdown_linter.yml
vendored
5
.github/workflows/07.2.markdown_linter.yml
vendored
@@ -10,6 +10,11 @@ on:
|
||||
paths:
|
||||
- '**/*.md'
|
||||
|
||||
# Supersede in-flight lint runs for the same PR/branch on new commits.
|
||||
concurrency:
|
||||
group: md-linter-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
Reference in New Issue
Block a user