Skip to content

feat(settings): add theme preset selection support #2884

feat(settings): add theme preset selection support

feat(settings): add theme preset selection support #2884

Workflow file for this run

name: GSSoC Label Automation
on:
pull_request_target:
types: [opened, reopened, synchronize]
pull_request_review:
types: [submitted]
permissions:
pull-requests: write
contents: read
issues: write
jobs:
auto-type-label:
name: Auto-apply type labels
runs-on: ubuntu-latest
if: github.event_name == 'pull_request_target'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect and apply type labels
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr = context.payload.pull_request;
const { owner, repo } = context.repo;
const prNumber = pr.number;
const title = pr.title.toLowerCase();
const body = (pr.body || '').toLowerCase();
// Fetch changed files
const filesRes = await github.rest.pulls.listFiles({
owner, repo, pull_number: prNumber, per_page: 100
});
const files = filesRes.data.map(f => f.filename.toLowerCase());
const labelsToAdd = new Set();
// --- Type detection from title ---
if (/^fix|^bug|hotfix/.test(title)) labelsToAdd.add('type:bug');
if (/^feat|^feature|add |implement/.test(title)) labelsToAdd.add('type:feature');
if (/^docs|^doc|readme|changelog|contributing/.test(title)) labelsToAdd.add('type:docs');
if (/^refactor|cleanup|clean up|reorgani/.test(title)) labelsToAdd.add('type:refactor');
if (/test|spec|coverage/.test(title)) labelsToAdd.add('type:testing');
if (/perf|performance|optimi|speed|latency/.test(title)) labelsToAdd.add('type:performance');
if (/a11y|accessibility|aria|wcag|screen.?reader/.test(title)) labelsToAdd.add('type:accessibility');
if (/security|auth|cve|xss|injection|csrf/.test(title)) labelsToAdd.add('type:security');
if (/ci|cd|deploy|docker|kubernetes|workflow|pipeline|devops/.test(title)) labelsToAdd.add('type:devops');
if (/design|ui|ux|theme|style|layout|responsive|dark.?mode/.test(title)) labelsToAdd.add('type:design');
// --- Type detection from files changed ---
const hasMarkdown = files.some(f => f.endsWith('.md') || f.endsWith('.mdx'));
const hasTests = files.some(f =>
f.includes('.test.') || f.includes('.spec.') ||
f.includes('__tests__') || f.includes('/tests/')
);
const hasWorkflow = files.some(f => f.includes('.github/workflows'));
const hasSecurity = files.some(f =>
f.includes('auth') || f.includes('middleware') || f.includes('security')
);
const hasStyle = files.some(f =>
f.endsWith('.css') || f.endsWith('.scss') ||
f.includes('globals') || f.includes('tailwind')
);
if (hasMarkdown) labelsToAdd.add('type:docs');
if (hasTests) labelsToAdd.add('type:testing');
if (hasWorkflow) labelsToAdd.add('type:devops');
if (hasSecurity && !labelsToAdd.has('type:bug') && !labelsToAdd.has('type:feature')) {
labelsToAdd.add('type:security');
}
if (hasStyle && !labelsToAdd.has('type:bug')) labelsToAdd.add('type:design');
// Fetch current labels
const currentLabels = pr.labels.map(l => l.name);
// Always add gssoc26 to every PR
if (!currentLabels.includes('gssoc26')) labelsToAdd.add('gssoc26');
// Only add labels not already present
const newLabels = [...labelsToAdd].filter(l => !currentLabels.includes(l));
if (newLabels.length > 0) {
await github.rest.issues.addLabels({
owner, repo, issue_number: prNumber, labels: newLabels
});
console.log(`Added labels: ${newLabels.join(', ')}`);
}
// Auto-assign PR author to PR
const creator = pr.user.login;
const currentAssignees = pr.assignees.map(a => a.login);
if (!currentAssignees.includes(creator)) {
await github.rest.issues.addAssignees({
owner,
repo,
issue_number: prNumber,
assignees: [creator]
});
console.log(`Assigned PR #${prNumber} to author @${creator}`);
}
- name: Post admin checklist comment
uses: actions/github-script@v7
if: github.event.action == 'opened'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr = context.payload.pull_request;
const { owner, repo } = context.repo;
const body = `## GSSoC Label Checklist 🏷️
@${context.repo.owner} — please apply the appropriate labels before merging:
**Difficulty** (pick one):
- [ ] \`level:beginner\` — 20 pts
- [ ] \`level:intermediate\` — 35 pts
- [ ] \`level:advanced\` — 55 pts
- [ ] \`level:critical\` — 80 pts
**Quality** (optional):
- [ ] \`quality:clean\` — ×1.2 multiplier
- [ ] \`quality:exceptional\` — ×1.5 multiplier
**Validation** (required to score):
- [ ] \`gssoc:approved\` — counts for points
- [ ] \`gssoc:invalid\` / \`gssoc:spam\` / \`gssoc:ai-slop\` — does not score
> Type labels (\`type:*\`) are auto-detected from files and title. Review and adjust if needed.
> Points formula: \`(difficulty × quality_multiplier) + type_bonus\``;
await github.rest.issues.createComment({
owner, repo, issue_number: pr.number, body
});
notify-on-approve:
name: Remind admin to add gssoc:approved
runs-on: ubuntu-latest
if: |
github.event_name == 'pull_request_review' &&
github.event.review.state == 'approved'
steps:
- name: Check for gssoc:approved label
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr = context.payload.pull_request;
const { owner, repo } = context.repo;
const hasApproved = pr.labels.some(l => l.name === 'gssoc:approved');
const hasDifficulty = pr.labels.some(l => l.name.startsWith('level:'));
if (!hasApproved || !hasDifficulty) {
const missing = [];
if (!hasDifficulty) missing.push('a `level:*` difficulty label');
if (!hasApproved) missing.push('`gssoc:approved`');
await github.rest.issues.createComment({
owner,
repo,
issue_number: pr.number,
body: `PR is approved but missing ${missing.join(' and ')} — add before merging so it scores in GSSoC. 🏷️`
});
}