Skip to content

Commit d74925c

Browse files
authored
Merge branch 'master' into fix/message-pins-types
2 parents 6b91043 + d9890f3 commit d74925c

5 files changed

Lines changed: 175 additions & 4 deletions

File tree

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
blank_issues_enabled: true
1+
blank_issues_enabled: false
22
contact_links:
33
- name: Ask a question
44
about: Ask questions and discuss with other users of the library.

.github/workflows/docs-localization-download.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
working-directory: ./docs
4141
- name: "Crowdin"
4242
id: crowdin
43-
uses: crowdin/github-action@v2.15.2
43+
uses: crowdin/github-action@v2.16.0
4444
with:
4545
upload_sources: false
4646
upload_translations: false

.github/workflows/docs-localization-upload.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
sphinx-intl update -p ./build/locales ${{ vars.SPHINX_LANGUAGES }}
4545
working-directory: ./docs
4646
- name: "Crowdin"
47-
uses: crowdin/github-action@v2.15.2
47+
uses: crowdin/github-action@v2.16.0
4848
with:
4949
upload_sources: true
5050
upload_translations: false
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
name: Enforce PR Template
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, edited, synchronize, reopened]
6+
workflow_dispatch:
7+
inputs:
8+
pr_number:
9+
description: 'Pull request number to validate'
10+
required: true
11+
type: number
12+
13+
permissions:
14+
pull-requests: write
15+
contents: read
16+
issues: write
17+
18+
jobs:
19+
enforce-template:
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: Determine PR number
24+
id: pr
25+
run: |
26+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
27+
echo "number=${{ inputs.pr_number }}" >> "$GITHUB_OUTPUT"
28+
else
29+
echo "number=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
30+
fi
31+
32+
- name: Enforce template
33+
uses: actions/github-script@v8
34+
with:
35+
github-token: ${{ secrets.GITHUB_TOKEN }}
36+
script: |
37+
const prNumber = Number('${{ steps.pr.outputs.number }}');
38+
const org = 'Pycord-Development';
39+
const INVALID_LABEL = 'invalid';
40+
41+
// 1) Load PR
42+
const { data: pr } = await github.rest.pulls.get({
43+
owner: context.repo.owner,
44+
repo: context.repo.repo,
45+
pull_number: prNumber,
46+
});
47+
48+
const author = pr.user.login;
49+
50+
if (pr.locked) {
51+
core.info(`PR #${prNumber} is already locked; skipping enforcement.`);
52+
return;
53+
}
54+
55+
const skipAuthors = [
56+
'renovate[bot]',
57+
'renovate-bot',
58+
'dependabot[bot]',
59+
'github-actions[bot]',
60+
'github-copilot[bot]',
61+
'copilot[bot]',
62+
'copilot'
63+
];
64+
65+
if (skipAuthors.includes(author)) {
66+
core.info(`Author ${author} is in skip list; skipping enforcement.`);
67+
return;
68+
}
69+
70+
// 2) Check org membership
71+
let isMember = false;
72+
try {
73+
await github.rest.orgs.checkMembershipForUser({ org, username: author });
74+
isMember = true;
75+
} catch (error) {
76+
if (error.status !== 404) {
77+
throw error;
78+
}
79+
}
80+
81+
if (isMember) {
82+
core.info(`Author ${author} is in org ${org}; skipping enforcement.`);
83+
return;
84+
}
85+
86+
// 3) Validate body
87+
const body = (pr.body || '').trim();
88+
const problems = [];
89+
90+
// Basic length check – tune as needed
91+
if (body.length < 150) {
92+
problems.push('PR description is too short (expected more content based on the template).');
93+
}
94+
95+
// Required headings from PULL_REQUEST_TEMPLATE.md
96+
const requiredHeadings = [
97+
'## Summary',
98+
'## Information',
99+
'## Checklist',
100+
];
101+
102+
for (const heading of requiredHeadings) {
103+
if (!body.includes(heading)) {
104+
problems.push(`Missing required section: "${heading}"`);
105+
}
106+
}
107+
108+
// Enforce AI disclosure line
109+
if (!body.includes('AI Usage has been disclosed')) {
110+
problems.push('The line "AI Usage has been disclosed." is missing.');
111+
}
112+
113+
if (problems.length === 0) {
114+
core.info('PR body passed template validation.');
115+
return;
116+
}
117+
118+
// 4) If invalid: label, comment, close, and fail
119+
core.info('Template validation failed. Applying actions.');
120+
121+
const existingLabels = (pr.labels || []).map(l => l.name);
122+
if (!existingLabels.includes(INVALID_LABEL)) {
123+
await github.rest.issues.addLabels({
124+
owner: context.repo.owner,
125+
repo: context.repo.repo,
126+
issue_number: prNumber,
127+
labels: [INVALID_LABEL],
128+
});
129+
}
130+
131+
const problemsBlock = problems.join('\n');
132+
133+
await github.rest.issues.createComment({
134+
owner: context.repo.owner,
135+
repo: context.repo.repo,
136+
issue_number: prNumber,
137+
body: [
138+
'This pull request does not follow the required pull request template.',
139+
'',
140+
'Please use the default template (`PULL_REQUEST_TEMPLATE.md`) and fill out all required sections.',
141+
'',
142+
'Problems detected:',
143+
'',
144+
'```',
145+
problemsBlock,
146+
'```',
147+
].join('\n'),
148+
});
149+
150+
if (pr.state === 'open') {
151+
await github.rest.pulls.update({
152+
owner: context.repo.owner,
153+
repo: context.repo.repo,
154+
pull_number: prNumber,
155+
state: 'closed',
156+
});
157+
}
158+
159+
try {
160+
await github.rest.issues.lock({
161+
owner: context.repo.owner,
162+
repo: context.repo.repo,
163+
issue_number: prNumber,
164+
lock_reason: 'spam',
165+
});
166+
core.info('Locked PR conversation.');
167+
} catch (lockError) {
168+
core.warning(`Failed to lock issue/PR #${prNumber}: ${lockError.message}`);
169+
}
170+
171+
core.setFailed('PR does not follow the required template.');

requirements/docs.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ myst-parser[linkify]==5.0.0 ; python_version >= "3.13"
55
sphinxext-opengraph==0.13.0 ; python_version >= "3.13"
66
sphinx-copybutton==0.5.2 ; python_version >= "3.13"
77
furo==2025.12.19 ; python_version >= "3.13"
8-
sphinx-autodoc-typehints==3.9.9 ; python_version >= "3.13"
8+
sphinx-autodoc-typehints==3.9.11 ; python_version >= "3.13"
99
sphinx-intl==2.3.2 ; python_version >= "3.13"
1010
typing_extensions==4.15.0 ; python_version >= "3.13"
1111
levenshtein==0.27.3 ; python_version >= "3.13"

0 commit comments

Comments
 (0)