perf(admin): defer icon and chart bundles #8182
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR Compliance | |
| on: | |
| pull_request_target: | |
| branches: [main] | |
| types: [opened, edited, synchronize] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| check-pr: | |
| name: Validate PR | |
| # Filter on the PR author, not github.actor: actor becomes a maintainer on | |
| # synchronize/edited events triggered by pushes or merges into a bot branch, | |
| # which lets bot PRs slip past an actor-based check. | |
| if: >- | |
| github.event.pull_request.user.login != 'dependabot[bot]' | |
| && github.event.pull_request.user.login != 'renovate[bot]' | |
| && github.event.pull_request.user.login != 'emdashbot[bot]' | |
| && github.event.pull_request.user.login != 'ask-bonk[bot]' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Check PR template | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const body = context.payload.pull_request.body || ''; | |
| const pr = context.payload.pull_request; | |
| // Maintainers (repo owners, org members, and collaborators) are trusted | |
| // to land features without a pre-approved Discussion link. | |
| const association = pr.author_association || ''; | |
| const isMaintainer = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(association); | |
| const errors = []; | |
| // Check if the PR body looks like it used the template at all | |
| const hasTemplate = body.includes('## What does this PR do?') || body.includes('## Type of change'); | |
| if (!hasTemplate) { | |
| errors.push('This PR does not use the required PR template. Please edit the description to use the [PR template](https://github.com/emdash-cms/emdash/blob/main/.github/PULL_REQUEST_TEMPLATE.md). Copy it into your PR description and fill out all sections.'); | |
| } else { | |
| // Must have a description (not just the raw template placeholder) | |
| const descriptionSection = body.match(/## What does this PR do\?\s*\n([\s\S]*?)(?=\n## )/); | |
| const description = descriptionSection?.[1]?.replace(/<!--[\s\S]*?-->/g, '').trim() || ''; | |
| if (!description || description === 'Closes #') { | |
| errors.push('Fill out the "What does this PR do?" section with a description of your change.'); | |
| } | |
| // Must check at least one type | |
| const typeChecks = [ | |
| /- \[x\] Bug fix/i, | |
| /- \[x\] Feature/i, | |
| /- \[x\] Refactor/i, | |
| /- \[x\] Translation/i, | |
| /- \[x\] Documentation/i, | |
| /- \[x\] Performance/i, | |
| /- \[x\] Tests/i, | |
| /- \[x\] Chore/i, | |
| ]; | |
| const hasType = typeChecks.some(re => re.test(body)); | |
| if (!hasType) { | |
| errors.push('Check at least one "Type of change" checkbox.'); | |
| } | |
| // If Feature is checked, require a discussion link. | |
| // Maintainers are exempt: they can approve their own features. | |
| const isFeature = /- \[x\] Feature/i.test(body); | |
| if (isFeature && !isMaintainer) { | |
| const hasDiscussionLink = /github\.com\/emdash-cms\/emdash\/discussions\/\d+/.test(body); | |
| if (!hasDiscussionLink) { | |
| errors.push('Feature PRs require a link to an approved Discussion (https://github.com/emdash-cms/emdash/discussions/categories/ideas). Open a Discussion first, get approval, then link it in the PR.'); | |
| } | |
| } | |
| // Must check the "I have read CONTRIBUTING.md" box. Be lenient about | |
| // formatting: accept the box whether or not CONTRIBUTING.md is still a | |
| // markdown link (authors often strip the link or tweak the wording). | |
| const hasReadContributing = /- \[x\][^\n]*\bI have read\b[^\n]*CONTRIBUTING/i.test(body); | |
| if (!hasReadContributing) { | |
| errors.push('Check the "I have read CONTRIBUTING.md" checkbox.'); | |
| } | |
| } | |
| if (errors.length > 0) { | |
| const message = [ | |
| '## PR template validation failed', | |
| '', | |
| 'Please fix the following issues by editing your PR description:', | |
| '', | |
| ...errors.map(e => `- ${e}`), | |
| '', | |
| 'See [CONTRIBUTING.md](https://github.com/emdash-cms/emdash/blob/main/CONTRIBUTING.md) for the full contribution policy.', | |
| ].join('\n'); | |
| // Leave a comment so the author sees the errors directly | |
| // Find and update existing bot comment, or create a new one | |
| const marker = '<!-- pr-compliance-check -->'; | |
| const commentBody = `${marker}\n${message}`; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: pr.number, | |
| }); | |
| const existing = comments.find(c => | |
| c.user?.login === 'github-actions[bot]' && | |
| c.body?.includes(marker) | |
| ); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body: commentBody, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: pr.number, | |
| body: commentBody, | |
| }); | |
| } | |
| core.setFailed(message); | |
| } else { | |
| // If passing now, remove any previous failure comment | |
| const marker = '<!-- pr-compliance-check -->'; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: pr.number, | |
| }); | |
| const existing = comments.find(c => | |
| c.user?.login === 'github-actions[bot]' && | |
| c.body?.includes(marker) | |
| ); | |
| if (existing) { | |
| await github.rest.issues.deleteComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| }); | |
| } | |
| } |