Auto-merge Copilot Link Fixes #2404
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: Auto-merge Copilot Link Fixes | |
| on: | |
| check_run: | |
| types: [completed] | |
| pull_request_target: | |
| types: [opened, synchronize, ready_for_review] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| auto-merge-link-fix: | |
| runs-on: ubuntu-latest | |
| if: | | |
| (github.event_name == 'check_run' && | |
| contains(github.event.check_run.name, 'netlify') && | |
| github.event.check_run.conclusion == 'success') || | |
| github.event_name == 'pull_request_target' | |
| steps: | |
| - name: Get PR info | |
| id: pr-info | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| if [ "${{ github.event_name }}" == "pull_request_target" ]; then | |
| PR_NUMBER="${{ github.event.pull_request.number }}" | |
| elif [ "${{ github.event_name }}" == "check_run" ]; then | |
| PR_NUMBER=$(echo '${{ toJson(github.event.check_run.pull_requests) }}' | jq -r '.[0].number // empty') | |
| fi | |
| if [ -z "$PR_NUMBER" ]; then | |
| echo "skip=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT | |
| PR_AUTHOR=$(gh pr view $PR_NUMBER --repo kubestellar/docs --json author --jq '.author.login') | |
| if [[ "$PR_AUTHOR" != *"copilot"* ]]; then | |
| echo "skip=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| PR_TITLE=$(gh pr view $PR_NUMBER --repo kubestellar/docs --json title --jq '.title') | |
| # Case-insensitive matching for "link" in title | |
| PR_TITLE_LOWER=${PR_TITLE,,} | |
| if [[ "$PR_TITLE_LOWER" != *"link"* ]]; then | |
| echo "skip=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "skip=false" >> $GITHUB_OUTPUT | |
| - name: Wait for Netlify | |
| if: steps.pr-info.outputs.skip != 'true' | |
| id: netlify | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| PR_NUMBER="${{ steps.pr-info.outputs.pr_number }}" | |
| for i in {1..30}; do | |
| CHECKS=$(gh pr checks $PR_NUMBER --repo kubestellar/docs 2>&1 || true) | |
| if echo "$CHECKS" | grep -q "netlify.*deploy-preview.*pass"; then | |
| echo "preview_url=https://deploy-preview-${PR_NUMBER}--kubestellar-docs.netlify.app" >> $GITHUB_OUTPUT | |
| echo "ready=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| elif echo "$CHECKS" | grep -q "netlify.*deploy-preview.*fail"; then | |
| echo "ready=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| sleep 10 | |
| done | |
| echo "ready=false" >> $GITHUB_OUTPUT | |
| - name: Find broken URLs | |
| if: steps.pr-info.outputs.skip != 'true' && steps.netlify.outputs.ready == 'true' | |
| id: find-urls | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| PR_NUMBER="${{ steps.pr-info.outputs.pr_number }}" | |
| PR_BODY=$(gh pr view $PR_NUMBER --repo kubestellar/docs --json body --jq '.body // ""') | |
| COMMITS=$(gh pr view $PR_NUMBER --repo kubestellar/docs --json commits --jq '.commits[].messageHeadline // ""') | |
| ISSUE_NUMBERS=$(echo "$PR_BODY $COMMITS" | grep -oE '#[0-9]+' | tr -d '#' | sort -u | tr '\n' ' ') | |
| BROKEN_URLS="" | |
| for issue_num in $ISSUE_NUMBERS; do | |
| [ -z "$issue_num" ] && continue | |
| ISSUE_BODY=$(gh issue view $issue_num --repo kubestellar/docs --json body --jq '.body' 2>/dev/null || true) | |
| # Extract all URLs from the issue (not just the first one) | |
| URLS=$(echo "$ISSUE_BODY" | grep -oE 'https://kubestellar\.io/docs/[^ )\]">,;!?:+&]+' | tr '\n' ' ' || true) | |
| [ -n "$URLS" ] && BROKEN_URLS="$BROKEN_URLS $URLS" | |
| done | |
| echo "broken_urls=$BROKEN_URLS" >> $GITHUB_OUTPUT | |
| - name: Verify links fixed | |
| if: steps.pr-info.outputs.skip != 'true' && steps.netlify.outputs.ready == 'true' | |
| id: verify | |
| run: | | |
| PREVIEW_URL="${{ steps.netlify.outputs.preview_url }}" | |
| BROKEN_URLS="${{ steps.find-urls.outputs.broken_urls }}" | |
| # Require at least one broken URL to verify - don't auto-merge if we can't | |
| # confirm a specific fix was made | |
| if [ -z "$BROKEN_URLS" ]; then | |
| echo "No broken URLs found to verify - skipping auto-merge" | |
| echo "verified=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| ALL_FIXED=true | |
| for url in $BROKEN_URLS; do | |
| PREVIEW_PATH=$(echo "$url" | sed 's|https://kubestellar.io||') | |
| TEST_URL="${PREVIEW_URL}${PREVIEW_PATH}" | |
| HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$TEST_URL" --max-time 30 || echo "000") | |
| [ "$HTTP_STATUS" != "200" ] && ALL_FIXED=false && echo "❌ $TEST_URL: $HTTP_STATUS" | |
| [ "$HTTP_STATUS" == "200" ] && echo "✅ $TEST_URL: 200" | |
| done | |
| [ "$ALL_FIXED" == "true" ] && echo "verified=true" >> $GITHUB_OUTPUT || echo "verified=false" >> $GITHUB_OUTPUT | |
| - name: Auto-merge | |
| if: steps.pr-info.outputs.skip != 'true' && steps.netlify.outputs.ready == 'true' && steps.verify.outputs.verified == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.WORKFLOW_SYNC_TOKEN }} | |
| run: | | |
| PR_NUMBER="${{ steps.pr-info.outputs.pr_number }}" | |
| gh pr ready $PR_NUMBER --repo kubestellar/docs 2>/dev/null || true | |
| # Use --admin to bypass DCO requirement since Copilot doesn't sign commits | |
| gh pr merge $PR_NUMBER --repo kubestellar/docs --squash --admin --body "Auto-merged: Copilot link fix verified" | |
| echo "✅ Merged PR #$PR_NUMBER" | |
| - name: Comment if failed | |
| if: steps.pr-info.outputs.skip != 'true' && steps.netlify.outputs.ready == 'true' && steps.verify.outputs.verified == 'false' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh pr comment ${{ steps.pr-info.outputs.pr_number }} --repo kubestellar/docs --body "⚠️ Auto-merge blocked: Links not fully fixed in preview." |