Auto Copilot Autofix (High & Medium Only) #7
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 Copilot Autofix (High & Medium Only) | |
| on: | |
| workflow_dispatch: | |
| workflow_run: | |
| workflows: ["CodeQL Advanced"] | |
| types: [completed] | |
| jobs: | |
| auto-fix: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| security-events: read | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Trigger Autofix for High & Medium alerts | |
| env: | |
| GH_TOKEN: ${{ secrets.AUTOFIX_TOKEN }} | |
| OWNER: ${{ github.repository_owner }} | |
| REPO: ${{ github.event.repository.name }} | |
| run: | | |
| DEFAULT_BRANCH=$(gh api /repos/$OWNER/$REPO --jq '.default_branch') | |
| echo "Default branch: $DEFAULT_BRANCH" | |
| # 用 security_severity_level 过滤,对应界面上的 Critical/High/Medium | |
| for SEC_LEVEL in "critical" "high" "medium"; do | |
| echo "====== Processing security_severity_level: $SEC_LEVEL ======" | |
| # ← 关键改动:换成 security_severity_level 参数 | |
| ALERTS=$(gh api \ | |
| "/repos/$OWNER/$REPO/code-scanning/alerts?security_severity_level=$SEC_LEVEL&state=open&per_page=100" \ | |
| --jq '[.[] | .number]') | |
| COUNT=$(echo $ALERTS | jq 'length') | |
| echo "Found $COUNT alerts with security_severity_level: $SEC_LEVEL" | |
| if [ "$COUNT" -eq 0 ]; then | |
| continue | |
| fi | |
| for NUMBER in $(echo $ALERTS | jq -r '.[]'); do | |
| echo "--- Alert #$NUMBER ($SEC_LEVEL) ---" | |
| EXISTING=$(gh api \ | |
| /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix \ | |
| --jq '.status' 2>/dev/null || echo "none") | |
| if [ "$EXISTING" = "success" ]; then | |
| echo "✅ Fix already exists, committing directly..." | |
| else | |
| echo "⏳ Generating fix..." | |
| gh api -X POST \ | |
| /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix || { | |
| echo "⚠️ Failed to trigger autofix for #$NUMBER, skipping" | |
| continue | |
| } | |
| for i in 1 2 3; do | |
| sleep 30 | |
| EXISTING=$(gh api \ | |
| /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix \ | |
| --jq '.status' 2>/dev/null || echo "none") | |
| echo " Attempt $i: status = $EXISTING" | |
| [ "$EXISTING" = "success" ] && break | |
| done | |
| fi | |
| if [ "$EXISTING" = "success" ]; then | |
| BRANCH="autofix/${SEC_LEVEL}/alert-${NUMBER}" | |
| SHA=$(gh api /repos/$OWNER/$REPO/git/refs/heads/$DEFAULT_BRANCH \ | |
| --jq '.object.sha') | |
| gh api -X POST /repos/$OWNER/$REPO/git/refs \ | |
| -f ref="refs/heads/$BRANCH" \ | |
| -f sha="$SHA" 2>/dev/null && \ | |
| echo "🌿 Created branch: $BRANCH" || \ | |
| echo "🌿 Branch already exists: $BRANCH" | |
| gh api -X POST \ | |
| /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix/commits \ | |
| -f target_ref="$BRANCH" || { | |
| echo "❌ Failed to commit fix for alert #$NUMBER" | |
| continue | |
| } | |
| echo "✅ Committed fix to branch: $BRANCH" | |
| ALERT_TITLE=$(gh api \ | |
| /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER \ | |
| --jq '.rule.description') | |
| gh pr create \ | |
| --repo "$OWNER/$REPO" \ | |
| --base "$DEFAULT_BRANCH" \ | |
| --head "$BRANCH" \ | |
| --draft \ | |
| --title "[Autofix][$SEC_LEVEL] Alert #$NUMBER: $ALERT_TITLE" \ | |
| --body "## 🤖 Copilot Autofix 自动修复 | |
| **Alert ID:** #$NUMBER | |
| **Security Severity:** $SEC_LEVEL | |
| **Rule:** $ALERT_TITLE | |
| 此 PR 由 Copilot Autofix 自动生成,请审核后再 merge。 | |
| - [ ] 确认修复逻辑正确 | |
| - [ ] 确认没有引入新问题 | |
| - [ ] CI 测试通过" && \ | |
| echo "🎉 PR created for alert #$NUMBER" || \ | |
| echo "⚠️ PR already exists for alert #$NUMBER" | |
| else | |
| echo "⚠️ Autofix not available for alert #$NUMBER (status: $EXISTING), skipping" | |
| fi | |
| done | |
| done |