chore: apply PR 2897 review fixes

This commit is contained in:
Alexandre
2026-07-23 13:11:48 +02:00
parent c7f5a9a292
commit 55c9f56a2a

View File

@@ -0,0 +1,272 @@
# yamllint disable rule:line-length
---
name: Apply PR 2897 review fixes
on:
push:
branches:
- agent/ai-issue-triage-fixes
paths:
- .github/workflows/pr2897_fix_review_comments.yml
permissions:
contents: write
jobs:
apply:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Apply reviewed fixes
run: |
set -euo pipefail
python3 <<'PY'
from pathlib import Path
def replace_exact(text: str, old: str, new: str, *, count: int = 1) -> str:
actual = text.count(old)
if actual < count:
raise SystemExit(f"Expected at least {count} occurrence(s), found {actual}: {old[:80]!r}")
return text.replace(old, new, count)
validator_path = Path('.github/scripts/validate_ai_patch.sh')
validator = validator_path.read_text()
validator = replace_exact(
validator,
'''}
mapfile -t changed_files < <(
git diff --cached --name-only --diff-filter=ACMRDTUXB "$base_ref" -- |
sed '/^$/d'
)
''',
'''}
version_is_greater() {
local old_version="$1"
local new_version="$2"
ruby -e '\''
require "rubygems"
old_version = Gem::Version.new(ARGV.fetch(0))
new_version = Gem::Version.new(ARGV.fetch(1))
exit(new_version > old_version ? 0 : 1)
'\'' "$old_version" "$new_version"
}
mapfile -d '\''\0'\'' -t changed_files < <(
git diff --cached --no-renames --name-only -z \\
--diff-filter=ACMRDTUXB "$base_ref" --
)
''')
validator = replace_exact(
validator,
'git diff --cached --numstat "$base_ref" -- |',
'git diff --cached --no-renames --numstat "$base_ref" -- |')
validator = replace_exact(
validator,
''' if ! printf '%s\\n' "${changed_files[@]}" | grep -Fxq "$addon/CHANGELOG.md"; then
echo "Changed add-on '$addon' must update CHANGELOG.md." >&2
exit 1
fi
''',
''' changelog_changed=false
for file in "${changed_files[@]}"; do
if [[ "$file" == "$addon/CHANGELOG.md" ]]; then
changelog_changed=true
break
fi
done
if [[ "$changelog_changed" != true ]]; then
echo "Changed add-on '$addon' must update CHANGELOG.md." >&2
exit 1
fi
''')
validator = replace_exact(
validator,
''' if [[ -z "$new_version" || "$old_version" == "$new_version" ]]; then
echo "Changed add-on '$addon' must change its version value." >&2
exit 1
fi
''',
''' if [[ -z "$old_version" || -z "$new_version" ]]; then
echo "Changed add-on '$addon' must have readable old and new version values." >&2
exit 1
fi
if ! version_is_greater "$old_version" "$new_version"; then
echo "Changed add-on '$addon' must increase its version value ($old_version -> $new_version)." >&2
exit 1
fi
''')
validator_path.write_text(validator)
workflow_path = Path('.github/workflows/on_issues_ai.yml')
workflow = workflow_path.read_text()
workflow = replace_exact(
workflow,
''' - name: Checkout repository
uses: actions/checkout@v7
''',
''' - name: Checkout repository
uses: actions/checkout@v7
with:
persist-credentials: false
''',
count=2)
workflow = replace_exact(
workflow,
''' category="$(jq -r '.category' "$RUNNER_TEMP/triage.json")"
addon="$(jq -r '.addon // ""' "$RUNNER_TEMP/triage.json")"
existing_addon=false
if [[ -n "$addon" && "$addon" != */* && "$addon" != "." && "$addon" != ".." ]] &&
[[ -f "$addon/config.yaml" || -f "$addon/config.json" ]]; then
existing_addon=true
fi
echo "addon=$addon" >> "$GITHUB_OUTPUT"
echo "category=$category" >> "$GITHUB_OUTPUT"
echo "confidence=$(jq -r '.confidence' "$RUNNER_TEMP/triage.json")" >> "$GITHUB_OUTPUT"
echo "existing_addon=$existing_addon" >> "$GITHUB_OUTPUT"
echo "risk=$(jq -r '.risk' "$RUNNER_TEMP/triage.json")" >> "$GITHUB_OUTPUT"
''',
''' category="$(jq -r '.category' "$RUNNER_TEMP/triage.json")"
addon="$(jq -r '.addon // ""' "$RUNNER_TEMP/triage.json")"
confidence="$(jq -r '.confidence' "$RUNNER_TEMP/triage.json")"
risk="$(jq -r '.risk' "$RUNNER_TEMP/triage.json")"
case "$category" in
question | missing_information | bug | improvement | new_addon_request | unsupported | spam) ;;
*) echo "Invalid triage category: $category" >&2; exit 1 ;;
esac
case "$risk" in
low | medium | high) ;;
*) echo "Invalid triage risk: $risk" >&2; exit 1 ;;
esac
existing_addon=false
if [[ -n "$addon" ]] &&
jq -e --arg addon "$addon" 'index($addon) != null' <<< "$addon_catalog" > /dev/null; then
existing_addon=true
else
addon=""
fi
write_output() {
local name="$1"
local value="$2"
if [[ "$value" == *$'\\n'* || "$value" == *$'\\r'* ]]; then
echo "Refusing multiline GitHub output '$name'." >&2
exit 1
fi
printf '%s=%s\\n' "$name" "$value" >> "$GITHUB_OUTPUT"
}
write_output addon "$addon"
write_output category "$category"
write_output confidence "$confidence"
write_output existing_addon "$existing_addon"
write_output risk "$risk"
''')
workflow = replace_exact(workflow, ' allow-users: "*"\n', '')
workflow_path.write_text(workflow)
readme_path = Path('.github/ai/README.md')
readme = readme_path.read_text()
readme = replace_exact(
readme,
'''The validator independently rejects new top-level add-on directories and Codex
never merges pull requests.
''',
'''The validator independently rejects new top-level add-on directories and Codex
never merges pull requests. The Codex Action keeps its default authorization, so only
users with repository write access can trigger its execution; external issue authors
cannot run it merely by opening an issue.
''')
readme_path.write_text(readme)
PY
- name: Validate scripts and workflow
run: |
set -euo pipefail
bash -n .github/scripts/validate_ai_patch.sh
jq empty .github/ai/triage-schema.json
ruby -e 'require "yaml"; YAML.safe_load(File.read(ARGV.fetch(0)), aliases: true)' .github/workflows/on_issues_ai.yml
ruby <<'RUBY'
require "yaml"
workflow = YAML.safe_load(File.read('.github/workflows/on_issues_ai.yml'), aliases: true)
workflow.fetch('jobs').each do |job_name, job|
job.fetch('steps', []).each_with_index do |step, index|
next unless step['run']
path = "/tmp/#{job_name}-#{index}.sh"
File.write(path, step['run'])
abort "bash syntax failed for #{job_name} step #{index}" unless system('bash', '-n', path)
end
end
RUBY
- name: Test validator security cases
run: |
set -euo pipefail
work="$RUNNER_TEMP/validator-tests"
mkdir -p "$work"
cp .github/scripts/validate_ai_patch.sh "$work/validator.sh"
cd "$work"
git init -q
git config user.name test
git config user.email test@example.com
mkdir -p .github/ai addon
printf 'protected\n' > .github/ai/README.md
printf 'version: 1.2.0\n' > addon/config.yaml
printf '# Changelog\n' > addon/CHANGELOG.md
printf '#!/bin/sh\necho old\n' > addon/file.sh
git add -A
git commit -qm base
base=HEAD
printf '#!/bin/sh\necho new\n' > addon/file.sh
printf '# Changelog\n- change\n' > addon/CHANGELOG.md
printf 'version: 1.2.1\n' > addon/config.yaml
git add -A
AI_REQUEST_CATEGORY=bug bash ./validator.sh "$base" > /dev/null
git reset --hard -q HEAD
printf '#!/bin/sh\necho new\n' > addon/file.sh
printf '# Changelog\n- change\n' > addon/CHANGELOG.md
printf 'version: 1.1.9\n' > addon/config.yaml
git add -A
! AI_REQUEST_CATEGORY=bug bash ./validator.sh "$base" > downgrade.log 2>&1
grep -q 'must increase' downgrade.log
git reset --hard -q HEAD
git mv .github/ai/README.md addon/AI_README.md
printf '# Changelog\n- change\n' > addon/CHANGELOG.md
printf 'version: 1.2.1\n' > addon/config.yaml
git add -A
! AI_REQUEST_CATEGORY=bug bash ./validator.sh "$base" > rename.log 2>&1
grep -q 'Disallowed path changed by AI: .github/ai/README.md' rename.log
git reset --hard -q HEAD
bad=$'.github/bad\nname'
printf 'x\n' > "$bad"
git add -A
! AI_REQUEST_CATEGORY=bug bash ./validator.sh "$base" > newline.log 2>&1
grep -q 'Disallowed path changed by AI: .github/bad' newline.log
- name: Commit fixes and remove helper
run: |
set -euo pipefail
rm -f .github/workflows/pr2897_fix_review_comments.yml
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .github/ai/README.md \
.github/scripts/validate_ai_patch.sh \
.github/workflows/on_issues_ai.yml \
.github/workflows/pr2897_fix_review_comments.yml
git commit -m "fix: address AI workflow review findings"
git push origin HEAD:agent/ai-issue-triage-fixes