[ci] Add /apply-gist workflow for updating expected app size files#25974
[ci] Add /apply-gist workflow for updating expected app size files#25974rolfbjarne wants to merge 3 commits into
Conversation
When the AppSizeTest fails in CI: 1. The Azure DevOps pipeline creates a GitHub gist with the updated expected files and posts a PR comment with the gist URL. 2. A maintainer can comment '/apply-gist <url>' on the PR to trigger a GitHub Actions workflow that downloads the gist files and commits them to the PR branch. Security: - Only comments from users with write access are honored - Only gists from approved owners are accepted (currently vs-mobiletools-engineering-service2) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
This PR adds a CI-assisted flow to update AppSizeTest expected files by publishing the updated .txt files to a GitHub gist and providing a /apply-gist <url> slash-command that applies those files back onto the PR branch automatically.
Changes:
- Extend the Azure DevOps test pipeline to create a gist containing updated expected app size files and comment on the PR with an
/apply-gistcommand. - Add a new GitHub Actions workflow (
Apply Gist) that validates the commenter + gist owner, downloads gist files, and commits them totests/dotnet/UnitTests/expected/.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| tools/devops/automation/templates/tests/run-tests.yml | Adds an ADO step to gist-upload updated expected files and comment on the PR with the apply command. |
| .github/workflows/apply-gist.yml | New workflow that responds to /apply-gist comments and applies gist contents to expected app size files. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
🚀 [CI Build #4686ad2] Test results 🚀Test results✅ All tests passed on VSTS: test results. 🎉 All 199 tests passed 🎉 Tests counts✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download Linux Build VerificationPipeline on Agent |
- Add issues: write permission (needed for reactions/comments) - Handle null gist owner gracefully - Reject fork PRs early with a clear message - Export EXPECTED_DIR so the Python subprocess can access it - Validate filenames with a strict regex pattern to prevent path traversal (only allow known patterns like *-size.txt and *-preservedapis.txt) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
| # Create gist with all updated files | ||
| # shellcheck disable=SC2086 | ||
| GIST_URL=$(gh gist create --public -d "Updated expected app size files for PR #$PR_NUMBER (${{ parameters.testPrefix }})" $FILES 2>&1) | ||
| if [ $? -ne 0 ]; then | ||
| echo "##[warning]Failed to create gist: $GIST_URL" | ||
| exit 0 | ||
| fi |
There was a problem hiding this comment.
This is valid; use a private gist.
| # Download gist metadata to get file URLs | ||
| GIST_JSON=$(gh api "gists/$GIST_ID") | ||
| echo "$GIST_JSON" | python3 -c " | ||
| import json, sys, urllib.request, os, re | ||
|
|
||
| gist = json.load(sys.stdin) | ||
| expected_dir = os.environ['EXPECTED_DIR'] | ||
| files = gist['files'] | ||
| # Only allow known expected-file patterns | ||
| allowed_pattern = re.compile(r'^[A-Za-z0-9]+-[A-Za-z0-9-]+-(size|preservedapis)\.txt$') | ||
| for filename, file_info in files.items(): | ||
| if not allowed_pattern.match(filename): | ||
| print(f'Skipping file with unexpected name: {filename}') | ||
| continue | ||
| content = file_info.get('content') | ||
| if content is None: | ||
| # Large files need to be fetched from raw_url | ||
| raw_url = file_info['raw_url'] | ||
| content = urllib.request.urlopen(raw_url).read().decode('utf-8') | ||
| dest = os.path.join(expected_dir, filename) | ||
| with open(dest, 'w') as f: | ||
| f.write(content) | ||
| print(f'Applied: {filename}') | ||
| " |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
When the AppSizeTest fails in CI:
expected files and posts a PR comment with the gist URL.
/apply-gist <url>on the PR to triggera GitHub Actions workflow that downloads the gist files and commits
them to the PR branch.
Security:
vs-mobiletools-engineering-service2)🤖 Pull request created by Copilot