From f1702eb9947df93eda84e49c6e0d04d788cfea01 Mon Sep 17 00:00:00 2001 From: m3tm3re Date: Wed, 4 Feb 2026 19:09:06 +0100 Subject: [PATCH] fix(ci): add file locking to prevent rebase race conditions --- .gitea/workflows/nix-update.yml | 79 +++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/.gitea/workflows/nix-update.yml b/.gitea/workflows/nix-update.yml index c03c42f..61b0174 100644 --- a/.gitea/workflows/nix-update.yml +++ b/.gitea/workflows/nix-update.yml @@ -330,29 +330,70 @@ jobs: fi fi - echo "::group::Git Operations" - echo "Current commit: $(git rev-parse HEAD)" - echo "Pending commits: $(git rev-list --count origin/master..HEAD)" + LOCKFILE="/tmp/$USER/nix-update-git-lock" - echo "" - echo "Pulling latest changes (rebase)..." - if git pull --rebase origin master; then - echo "✅ Rebase successful" - else - echo "⚠️ Rebase failed, attempting force push..." - git reset --hard origin/master - git push --force-with-lease origin master - echo "✓ Force push completed" - exit 0 + trap 'rm -f "$LOCKFILE"; exit' EXIT INT TERM + + if [ -f "$LOCKFILE" ]; then + echo "🔍 Found existing lock file, checking if stale..." + STALE_LOCK_PID=$(cat "$LOCKFILE" 2>/dev/null || echo "") + if [ -n "$STALE_LOCK_PID" ] && ! kill -0 "$STALE_LOCK_PID" 2>/dev/null; then + echo "🗑️ Stale lock detected (PID $STALE_LOCK_PID no longer running), removing..." + rm -f "$LOCKFILE" + fi fi - echo "" - echo "Pushing changes to master..." - git push origin master + ( + flock -x 200 || exit 1 - echo "" - echo "✅ Successfully pushed updates for: $PACKAGES" - echo "::endgroup::" + echo $$ > "$LOCKFILE" + + MY_PID=$$ + echo "🔒 Lock acquired by PID $MY_PID" + + echo "::group::Git Operations" + echo "Current commit: $(git rev-parse HEAD)" + echo "Pending commits: $(git rev-list --count origin/master..HEAD)" + + git rebase --abort 2>/dev/null || true + + if [ -n "$(git status --porcelain)" ]; then + echo "" + echo "⚠️ Unstaged changes detected, auto-committing..." + git add . + git commit -m "chore: auto-commit before rebase [skip ci]" + echo "✅ Unstaged changes committed" + fi + + echo "" + echo "Pulling latest changes (autostash + rebase)..." + if git pull --autostash --rebase origin master; then + echo "✅ Rebase successful" + else + echo "⚠️ Rebase failed, attempting merge (-Xtheirs)..." + git rebase --abort 2>/dev/null || true + + if git merge -Xtheirs origin/master; then + echo "✅ Merge successful (-Xtheirs strategy)" + else + echo "⚠️ Merge failed, attempting force push..." + git reset --hard origin/master + git push --force-with-lease origin master + echo "✅ Force push completed" + exit 0 + fi + fi + + echo "" + echo "Pushing changes to master..." + git push origin master + + echo "" + echo "✅ Successfully pushed updates for: $PACKAGES" + echo "🔒 Lock released by PID $MY_PID" + echo "::endgroup::" + + ) 200>"$LOCKFILE" - name: Upload Build Logs if: failure()