Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .github/workflows/check-media-attachments.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: Check PR for Screenshots when HTML changes

on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- '**/*.html'

Comment thread
Aaqilyousuf marked this conversation as resolved.
jobs:
check-for-screenshots:
runs-on: ubuntu-latest
name: Check for PR screenshots
permissions:
contents: read
pull-requests: read
issues: write
steps:
Comment thread
Aaqilyousuf marked this conversation as resolved.
- name: Checkout code
uses: actions/checkout@v4

Comment thread
Aaqilyousuf marked this conversation as resolved.
- name: Check for screenshots in PR description or comments
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo } = context.repo;
const prNumber = context.payload.pull_request.number;
const botCommentIdentifier = '<!-- media-check-bot -->';

console.log(`Checking PR #${prNumber} for screenshots because HTML files were changed.`);

// --- 1. Get PR body + comments ---
const prBody = context.payload.pull_request.body || '';

const comments = await github.paginate(
github.rest.issues.listComments,
{ owner, repo, issue_number: prNumber }
);

const allCommentsText = comments.map(comment => comment.body || '').join('\n');
const combinedText = prBody + '\n' + allCommentsText;

// --- 2. Look for actual media (image/video uploads) ---

// Extract URLs from Markdown image syntax (![alt](url))
const mdImageUrls = [...combinedText.matchAll(/!\[[^\]]*\]\(([^)]+)\)/gi)].map(m => m[1]);

// Extract all plain URLs in the text
const allUrls = [...combinedText.matchAll(/\bhttps?:\/\/[^\s)>"']+/gi)].map(m => m[0]);

// Merge and deduplicate all URLs
const candidates = [...new Set([...mdImageUrls, ...allUrls])];

// Define file extensions that count as media
const mediaExt = /\.(?:png|jpe?g|gif|webp|svg|apng|mp4|mov|webm)$/i;

// Define known GitHub hosts for attachments (including new user-attachments paths)
const ghAssetsHost = /(?:^|\/\/)(?:user-images\.githubusercontent\.com|private-user-images\.githubusercontent\.com|github\.com\/user-attachments\/assets|github-production-user-asset-[^/]+\.s3\.amazonaws\.com)\b/i;

// Filter candidate URLs: either matches media extensions OR GitHub attachment hosts
const mediaUrls = candidates.filter(u => mediaExt.test(u) || ghAssetsHost.test(u));

// Final flag: true if at least one media URL found
const mediaFound = mediaUrls.length > 0;

// --- 3. Find previous bot comment ---
const botComment = comments.find(comment =>
comment.user?.login === 'github-actions[bot]' &&
comment.body?.includes(botCommentIdentifier)
);

Comment thread
Aaqilyousuf marked this conversation as resolved.
if (mediaFound) {
console.log('✅ Screenshot or media found in the PR.');
if (botComment) {
try {
await github.rest.issues.deleteComment({
owner,
repo,
comment_id: botComment.id,
});
console.log('Removed previous warning comment.');
} catch (e) {
console.warn(`Could not delete previous comment (likely fork perms): ${e.status || ''}`);
}
}
return;
}

// --- 4. Post or update warning comment ---
const commentBody = `${botCommentIdentifier}

## Screenshot Missing

You've modified **HTML files**, but no screenshots or recordings were found in the PR description or comments.

*Please attach a screenshot or GIF demonstrating the change.*`;

Comment thread
Aaqilyousuf marked this conversation as resolved.
if (botComment) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: botComment.id,
body: commentBody,
});
console.log('Updated existing warning comment.');
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: commentBody,
});
console.log('Created a new warning comment.');
}

// --- 5. Fail workflow to block merging ---
core.setFailed('Missing screenshots for HTML changes. Please add one to continue.');
Comment thread Fixed
Loading