This repository was archived by the owner on Mar 23, 2026. It is now read-only.
Added Security Review #33
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Sync Cursor Rules (Production) | |
| on: | |
| push: | |
| branches: | |
| - main | |
| # Uncomment these lines to only run when rules actually change | |
| paths: | |
| - '.cursor/rules/**' | |
| - '.cursor/commands/**' | |
| - '.cursor/worktrees.json' | |
| - '.github/workflows/**' | |
| - 'scripts/**' | |
| workflow_dispatch: | |
| jobs: | |
| # ------------------------------------------------------------------ | |
| # JOB 1: THE WORKER | |
| # ------------------------------------------------------------------ | |
| sync-configuration: | |
| name: Sync ➔ ${{ matrix.repo }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| repo: | |
| # KillzoneGaming | |
| - 'KillzoneGaming/kzg-servers-connect' | |
| - 'KillzoneGaming/kzg-workshop-map-puller' | |
| - 'KillzoneGaming/kzg-website-nextjs' | |
| - 'KillzoneGaming/kzg-discord-oidc-worker' | |
| - 'KillzoneGaming/kzg-vip-confirmation-email-worker' | |
| - 'KillzoneGaming/kzg-discord-servers-webhook' | |
| - 'KillzoneGaming/kzg-surf-maps-discord-bot' | |
| - 'KillzoneGaming/kzg-discord-banner-changer' | |
| - 'KillzoneGaming/kzg-rules-website-next' | |
| steps: | |
| - name: 📥 Checkout Source | |
| uses: actions/checkout@v4 | |
| with: | |
| path: source_repo | |
| - name: 🎯 Checkout Target | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ matrix.repo }} | |
| token: ${{ secrets.GH_PAT_SYNC }} | |
| path: target_repo | |
| fetch-depth: 0 | |
| - name: ⚙️ Detect Default Branch | |
| working-directory: target_repo | |
| id: branch_info | |
| run: | | |
| DEFAULT_BRANCH=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5) | |
| echo "branch=$DEFAULT_BRANCH" >> $GITHUB_OUTPUT | |
| git checkout $DEFAULT_BRANCH | |
| - name: 🔄 Sync Files | |
| run: | | |
| echo "🚀 SYNCING TO: ${{ matrix.repo }}" | |
| mkdir -p target_repo/.cursor | |
| rm -rf target_repo/.cursor/rules | |
| if [ -d "source_repo/.cursor/rules" ]; then | |
| cp -rv source_repo/.cursor/rules target_repo/.cursor/ | |
| fi | |
| rm -rf target_repo/.cursor/commands | |
| if [ -d "source_repo/.cursor/commands" ]; then | |
| cp -rv source_repo/.cursor/commands target_repo/.cursor/ | |
| fi | |
| if [ -f "source_repo/.cursor/worktrees.json" ]; then | |
| cp -v source_repo/.cursor/worktrees.json target_repo/.cursor/worktrees.json | |
| fi | |
| # Sync to .agent/rules | |
| mkdir -p target_repo/.agent | |
| rm -rf target_repo/.agent/rules | |
| if [ -d "source_repo/.cursor/rules" ]; then | |
| cp -rv source_repo/.cursor/rules target_repo/.agent/ | |
| fi | |
| - name: 💾 Review & Push | |
| working-directory: target_repo | |
| run: | | |
| TARGET_BRANCH=${{ steps.branch_info.outputs.branch }} | |
| git config user.name "mynameistito" | |
| git config user.email "github@mynameistito.com" | |
| git add .cursor | |
| git add .agent | |
| STATUS=$(git status -s) | |
| if [[ -n "$STATUS" ]]; then | |
| # Generate formatted file list | |
| CHANGES=$(echo "$STATUS" | awk '{ | |
| status=$1; | |
| file=$2; | |
| if (status=="A" || status=="??") symbol="+"; | |
| else if (status=="D") symbol="-"; | |
| else if (status=="M") symbol="~"; | |
| else symbol=status; | |
| printf "%s %s, ", symbol, file; | |
| }' | sed 's/, $//') | |
| git commit -m "chore(cursor): sync shared rules - Changes: $CHANGES [skip ci]" | |
| git pull --rebase origin $TARGET_BRANCH | |
| git push origin $TARGET_BRANCH | |
| else | |
| echo "✨ NO CHANGES" | |
| fi | |
| # 📝 Report Failure | |
| - name: Report Failure | |
| if: failure() | |
| run: | | |
| SAFE_NAME=$(echo "${{ matrix.repo }}" | tr '/' '-') | |
| echo "${{ matrix.repo }}" > "failed_$SAFE_NAME.txt" | |
| - name: Upload Artifact | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: failure-${{ strategy.job-index }} | |
| path: failed_*.txt | |
| retention-days: 1 | |
| # ------------------------------------------------------------------ | |
| # JOB 2: THE REPORTER (Failures Only) | |
| # ------------------------------------------------------------------ | |
| notify-discord: | |
| needs: [sync-configuration, update-readme] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Download Failure Reports | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: failure-* | |
| merge-multiple: true | |
| path: failures | |
| - name: 🚨 Check Status & Ping | |
| env: | |
| DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} | |
| run: | | |
| LOG_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| # 1. Check if failures exist. If EMPTY, exit silently. | |
| if [ ! -d "failures" ] || [ -z "$(ls -A failures)" ]; then | |
| echo "✅ No failures found. Silent success." | |
| exit 0 | |
| fi | |
| # 2. If we are here, something failed. | |
| echo "❌ Failures detected. Sending Alert..." | |
| LIST_STRING="" | |
| for f in failures/*.txt; do | |
| REPO_NAME=$(cat "$f") | |
| LIST_STRING="$LIST_STRING\\n- \`$REPO_NAME\`" | |
| done | |
| # 3. Send Ping to Discord (User ID: 611746802122620937) | |
| cat <<EOF > discord_payload.json | |
| { | |
| "username": "Cursor Sync Bot", | |
| "content": "⚠️ <@611746802122620937> **Sync Failed!** Issues detected:", | |
| "embeds": [ | |
| { | |
| "description": "$LIST_STRING", | |
| "color": 15548997, | |
| "fields": [ | |
| { | |
| "name": "Troubleshooting", | |
| "value": "[👉 Click here to view Logs]($LOG_URL)" | |
| } | |
| ] | |
| } | |
| ] | |
| } | |
| EOF | |
| curl -H "Content-Type: application/json" -X POST -d @discord_payload.json "$DISCORD_WEBHOOK" | |
| # ------------------------------------------------------------------ | |
| # JOB 3: UPDATE README STRUCTURE | |
| # ------------------------------------------------------------------ | |
| update-readme: | |
| name: Update README Structure | |
| needs: sync-configuration | |
| runs-on: ubuntu-latest | |
| if: success() | |
| steps: | |
| - name: 📥 Checkout Source | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GH_PAT_SYNC }} | |
| - name: 🌳 Install Tree | |
| run: sudo apt-get install -y tree | |
| - name: 🔄 Update Structure | |
| run: | | |
| chmod +x scripts/update-structure.sh | |
| ./scripts/update-structure.sh | |
| chmod +x scripts/update-repos.sh | |
| ./scripts/update-repos.sh | |
| - name: 💾 Commit Changes | |
| run: | | |
| git config user.name "mynameistito" | |
| git config user.email "github@mynameistito.com" | |
| # Check specifically for README changes, ignoring script permission changes | |
| if [[ -n $(git status -s README.md) ]]; then | |
| git add README.md | |
| git commit -m "docs: update project structure [skip ci]" | |
| git push | |
| else | |
| echo "✨ No changes to README structure" | |
| fi | |
| # 📝 Report Failure | |
| - name: Report Failure | |
| if: failure() | |
| run: | | |
| echo "README Structure Update" > "failed_readme_update.txt" | |
| - name: Upload Artifact | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: failure-readme | |
| path: failed_*.txt | |
| retention-days: 1 |