Skip to content
Draft
95 changes: 95 additions & 0 deletions .github/workflows/qgs-ai-summary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: qgs-ai-summary

# Post a concise, human-readable summary of the real changes to QGIS .qgs
# project files on a PR. scripts/qgs-diff.py builds a churn-free diff of the
# changed files; GitHub Models turns it into per-file bullet points; the result
# is posted as a single self-updating PR comment. Nothing derived is committed.

on:
pull_request:
paths:
- '**/*.qgs'

permissions:
contents: read
pull-requests: write
models: read


concurrency:
group: qgs-ai-summary-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
summarise:
runs-on: ubuntu-latest
env:
MODEL: openai/gpt-4.1
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0

- name: Build churn-free diff
id: diff
run: |
python3 scripts/qgs-diff.py diff --base "${{ github.base_ref }}" > diff.txt
[ -s diff.txt ] && echo "changed=1" >> "$GITHUB_OUTPUT" || echo "changed=0" >> "$GITHUB_OUTPUT"

- name: Summarise with GitHub Models
id: ai
if: steps.diff.outputs.changed == '1'
uses: actions/ai-inference@v2
with:
model: ${{ env.MODEL }}
max-completion-tokens: 3000
prompt-file: diff.txt
system-prompt: |
You are reviewing changes to QGIS .qgs project files for a pull
request. You are given a unified diff per file; QGIS session churn
has already been stripped, so ignore residual noise (reordered
attributes, internal ids, emptied values).

Write a concise GitHub-flavored-markdown summary:
- Group by file under a "### <path>" heading matching the diff.
- Short bullets, substantive changes only: layers added / removed /
renamed / reordered, symbology, labelling, scale ranges, print
layouts, project CRS, variables, map themes, expressions, data
sources. Name the actual layers, properties and values.
- Do not restate raw XML, omit unchanged files, never invent changes.
- Output only the per-file sections, no preamble or conclusion.

- name: Post sticky PR comment
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
PR: ${{ github.event.pull_request.number }}
CHANGED: ${{ steps.diff.outputs.changed }}
AI_RESPONSE: ${{ steps.ai.outputs.response }}
MODEL: ${{ env.MODEL }}
run: |
set -euo pipefail
MARKER='<!-- qgs-ai-summary -->'
{
echo "$MARKER"
echo "## 🗺️ QGIS project change summary"
echo
if [ "$CHANGED" = "1" ]; then
printf '%s\n' "$AI_RESPONSE"
echo
echo "<sub>Generated by \`$MODEL\` via GitHub Models from a churn-free diff - verify against the file diff.</sub>"
else
echo "_No substantive QGIS project changes detected - only QGIS session churn._"
fi
} > comment.md

id=$(gh api "repos/$REPO/issues/$PR/comments" --paginate \
--jq ".[] | select(.body | contains(\"$MARKER\")) | .id" | head -n1)
if [ -n "$id" ]; then
gh api -X PATCH "repos/$REPO/issues/comments/$id" -F body=@comment.md >/dev/null
echo "updated comment $id"
else
gh api -X POST "repos/$REPO/issues/$PR/comments" -F body=@comment.md >/dev/null
echo "created comment"
fi
Loading
Loading