Skip to content

Sync/upstream 2026 07 #128

Sync/upstream 2026 07

Sync/upstream 2026 07 #128

Workflow file for this run

name: Audit PR
on:
pull_request:
branches:
- main
types: [opened, synchronize, reopened, ready_for_review]
issue_comment:
types: [created]
workflow_dispatch:
permissions:
contents: read
pull-requests: write
issues: write
concurrency:
group: audit-pr-${{ github.event.pull_request.number || github.event.issue.number || github.ref }}
cancel-in-progress: true
jobs:
audit-on-pr:
name: Audit on pull request
if: github.event_name == 'pull_request'
runs-on: [self-hosted, Linux, ARM64, audit-linux]
steps:
- name: Checkout PR head
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Check required tools
run: |
which zip
which jq
which python3
- name: Create source archive
id: archive
shell: bash
run: |
ARCHIVE_NAME="${{ github.event.repository.name }}.zip"
rm -f "/tmp/${ARCHIVE_NAME}"
zip -r "/tmp/${ARCHIVE_NAME}" .
echo "archive_name=${ARCHIVE_NAME}" >> "$GITHUB_OUTPUT"
- name: Submit audit job
id: submit
shell: bash
run: |
RESPONSE=$(curl -s -X POST "${{ vars.AUDIT_SERVICE_URL }}/audit-pr/${{ vars.AUDIT_PR_SKILL }}" \
-H "X-API-Key: ${{ secrets.AUDIT_API_KEY }}" \
-F "file=@/tmp/${{ steps.archive.outputs.archive_name }}" \
-F "from_branch=${{ github.event.pull_request.base.ref }}" \
-F "to_branch=${{ github.event.pull_request.head.ref }}")
echo "Submit response:"
echo "$RESPONSE" | jq .
REPORT_URL=$(echo "$RESPONSE" | jq -r '.report_url // empty')
if [ -z "$REPORT_URL" ]; then
echo "Audit service did not return report_url"
exit 1
fi
echo "report_url=$REPORT_URL" >> "$GITHUB_OUTPUT"
- name: Poll report until ready
id: poll
shell: bash
run: |
REPORT_PATH="${{ steps.submit.outputs.report_url }}"
if [ -z "$REPORT_PATH" ]; then
echo "Missing report_url"
exit 1
fi
echo "Polling report URL: ${{ vars.AUDIT_SERVICE_URL }}${REPORT_PATH}"
for i in $(seq 1 20); do
HTTP_CODE=$(curl -s -o /tmp/audit-report.html -w "%{http_code}" "${{ vars.AUDIT_SERVICE_URL }}${REPORT_PATH}")
echo "Poll #$i HTTP_CODE=$HTTP_CODE"
if [ "$HTTP_CODE" = "200" ] && [ -s /tmp/audit-report.html ]; then
echo "Report is ready"
exit 0
fi
sleep 60
done
echo "Audit report did not become available within timeout"
exit 1
- name: Fetch markdown report
shell: bash
run: |
REPORT_PATH="${{ steps.submit.outputs.report_url }}"
MD_PATH="${REPORT_PATH%audit-report.html}audit-report.md"
echo "Markdown path: ${MD_PATH}"
HTTP_CODE=$(curl -s -o /tmp/audit-report.md -w "%{http_code}" "${{ vars.AUDIT_SERVICE_URL }}${MD_PATH}")
echo "Markdown fetch HTTP_CODE=$HTTP_CODE"
if [ "$HTTP_CODE" != "200" ] || [ ! -s /tmp/audit-report.md ]; then
echo "Failed to fetch markdown report"
exit 1
fi
- name: Normalize markdown for GitHub comment
shell: bash
run: |
python3 <<'PY'
import re
from pathlib import Path
p = Path("/tmp/audit-report.md")
text = p.read_text(encoding="utf-8", errors="ignore")
# 去掉首尾空白,压缩多余空行
text = re.sub(r'\n{3,}', '\n\n', text).strip() + '\n'
# 如果首行已经是一级标题,保留;否则不额外加头
Path("/tmp/audit-report-clean.md").write_text(text, encoding="utf-8")
PY
- name: Comment markdown report to PR
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const reportText = fs.readFileSync('/tmp/audit-report-clean.md', 'utf8').trim();
const limit = 60000;
const chunks = [];
for (let i = 0; i < reportText.length; i += limit) {
chunks.push(reportText.slice(i, i + limit));
}
for (let i = 0; i < chunks.length; i++) {
const body = chunks.length > 1
? `${chunks[i]}\n\n---\nPart ${i + 1}/${chunks.length}`
: chunks[i];
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body
});
}
audit-by-comment:
name: Audit by PR comment
if: >
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '/audit-pr') &&
contains(format(',{0},', vars.AUDIT_ALLOWED_USERS), format(',{0},', github.event.comment.user.login))
runs-on: [self-hosted, Linux, ARM64, audit-linux]
steps:
- name: Get PR info
id: pr
uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
core.setOutput('head_ref', pr.data.head.ref);
core.setOutput('base_ref', pr.data.base.ref);
core.setOutput('head_sha', pr.data.head.sha);
- name: Checkout PR head
uses: actions/checkout@v4
with:
ref: ${{ steps.pr.outputs.head_sha }}
fetch-depth: 0
- name: Check required tools
run: |
which zip
which jq
which python3
- name: Create source archive
id: archive
shell: bash
run: |
ARCHIVE_NAME="${{ github.event.repository.name }}.zip"
rm -f "/tmp/${ARCHIVE_NAME}"
zip -r "/tmp/${ARCHIVE_NAME}" .
echo "archive_name=${ARCHIVE_NAME}" >> "$GITHUB_OUTPUT"
- name: Submit audit job
id: submit
shell: bash
run: |
RESPONSE=$(curl -s -X POST "${{ vars.AUDIT_SERVICE_URL }}/audit-pr/${{ vars.AUDIT_PR_SKILL }}" \
-H "X-API-Key: ${{ secrets.AUDIT_API_KEY }}" \
-F "file=@/tmp/${{ steps.archive.outputs.archive_name }}" \
-F "from_branch=${{ steps.pr.outputs.base_ref }}" \
-F "to_branch=${{ steps.pr.outputs.head_ref }}")
echo "Submit response:"
echo "$RESPONSE" | jq .
REPORT_URL=$(echo "$RESPONSE" | jq -r '.report_url // empty')
if [ -z "$REPORT_URL" ]; then
echo "Audit service did not return report_url"
exit 1
fi
echo "report_url=$REPORT_URL" >> "$GITHUB_OUTPUT"
- name: Poll report until ready
id: poll
shell: bash
run: |
REPORT_PATH="${{ steps.submit.outputs.report_url }}"
if [ -z "$REPORT_PATH" ]; then
echo "Missing report_url"
exit 1
fi
echo "Polling report URL: ${{ vars.AUDIT_SERVICE_URL }}${REPORT_PATH}"
for i in $(seq 1 20); do
HTTP_CODE=$(curl -s -o /tmp/audit-report.html -w "%{http_code}" "${{ vars.AUDIT_SERVICE_URL }}${REPORT_PATH}")
echo "Poll #$i HTTP_CODE=$HTTP_CODE"
if [ "$HTTP_CODE" = "200" ] && [ -s /tmp/audit-report.html ]; then
echo "Report is ready"
exit 0
fi
sleep 60
done
echo "Audit report did not become available within timeout"
exit 1
- name: Fetch markdown report
shell: bash
run: |
REPORT_PATH="${{ steps.submit.outputs.report_url }}"
MD_PATH="${REPORT_PATH%audit-report.html}audit-report.md"
echo "Markdown path: ${MD_PATH}"
HTTP_CODE=$(curl -s -o /tmp/audit-report.md -w "%{http_code}" "${{ vars.AUDIT_SERVICE_URL }}${MD_PATH}")
echo "Markdown fetch HTTP_CODE=$HTTP_CODE"
if [ "$HTTP_CODE" != "200" ] || [ ! -s /tmp/audit-report.md ]; then
echo "Failed to fetch markdown report"
exit 1
fi
- name: Normalize markdown for GitHub comment
shell: bash
run: |
python3 <<'PY'
import re
from pathlib import Path
p = Path("/tmp/audit-report.md")
text = p.read_text(encoding="utf-8", errors="ignore")
text = re.sub(r'\n{3,}', '\n\n', text).strip() + '\n'
Path("/tmp/audit-report-clean.md").write_text(text, encoding="utf-8")
PY
- name: Comment markdown report to PR
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const reportText = fs.readFileSync('/tmp/audit-report-clean.md', 'utf8').trim();
const limit = 60000;
const chunks = [];
for (let i = 0; i < reportText.length; i += limit) {
chunks.push(reportText.slice(i, i + limit));
}
for (let i = 0; i < chunks.length; i++) {
const body = chunks.length > 1
? `${chunks[i]}\n\n---\nPart ${i + 1}/${chunks.length}`
: chunks[i];
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body
});
}