Skip to content

Commit ac9dfdc

Browse files
authored
Merge branch 'master' into fix-auto-sync
2 parents 8d6bc88 + 227a128 commit ac9dfdc

13 files changed

Lines changed: 200 additions & 14 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.');

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,14 @@ These changes are available on the `master` branch, but have not yet been releas
1616

1717
### Fixed
1818

19+
- Fixed internal use of deprecated role type methods.
20+
([#3167](https://github.com/Pycord-Development/pycord/pull/3167))
1921
- Fixed a `TypeError` when using `Label.set_select` and not providing `default_values`.
2022
([#3171](https://github.com/Pycord-Development/pycord/pull/3171))
23+
- Fixed `View.from_dict()` incorrectly returning `None`.
24+
([#3181](https://github.com/Pycord-Development/pycord/pull/3181))
25+
- Fixed internal use of deprecated \_PayloadLike dict operations.
26+
([#3189](https://github.com/Pycord-Development/pycord/pull/3189))
2127

2228
### Deprecated
2329

discord/guild.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
NotificationLevel,
6262
NSFWLevel,
6363
OnboardingMode,
64+
RoleType,
6465
ScheduledEventLocationType,
6566
ScheduledEventPrivacyLevel,
6667
SortOrder,
@@ -1250,7 +1251,7 @@ def premium_subscriber_role(self) -> Role | None:
12501251
.. versionadded:: 1.6
12511252
"""
12521253
for role in self._roles.values():
1253-
if role.is_premium_subscriber():
1254+
if role.type is RoleType.BOOSTER:
12541255
return role
12551256
return None
12561257

discord/role.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ def is_bot_managed(self) -> bool:
572572
573573
.. versionadded:: 1.6
574574
"""
575-
return self.tags is not None and self.tags.is_bot_managed()
575+
return self.type is RoleType.APPLICATION
576576

577577
@deprecated(
578578
"Role.is_premium_subscriber is deprecated since version 2.8, consider using Role.type instead."
@@ -585,7 +585,7 @@ def is_premium_subscriber(self) -> bool:
585585
586586
.. versionadded:: 1.6
587587
"""
588-
return self.tags is not None and self.tags.is_premium_subscriber()
588+
return self.type is RoleType.BOOSTER
589589

590590
@deprecated(
591591
"Role.is_integration is deprecated since version 2.8, consider using Role.type instead."
@@ -599,7 +599,11 @@ def is_integration(self) -> bool:
599599
600600
.. versionadded:: 1.6
601601
"""
602-
return self.tags is not None and self.tags.is_integration()
602+
return self.type in (
603+
RoleType.INTEGRATION,
604+
RoleType.PREMIUM_SUBSCRIPTION_TIER,
605+
RoleType.DRAFT_PREMIUM_SUBSCRIPTION_TIER,
606+
)
603607

604608
def is_assignable(self) -> bool:
605609
"""Whether the role is able to be assigned or removed by the bot. This checks whether all of the following conditions are true:
@@ -639,7 +643,7 @@ def is_available_for_purchase(self) -> bool:
639643
640644
.. versionadded:: 2.7
641645
"""
642-
return self.tags is not None and self.tags.is_available_for_purchase()
646+
return self.type is RoleType.PREMIUM_SUBSCRIPTION_TIER
643647

644648
@deprecated(
645649
"Role.is_guild_connections_role is deprecated since version 2.8, consider using Role.type instead."
@@ -652,7 +656,7 @@ def is_guild_connections_role(self) -> bool:
652656
653657
.. versionadded:: 2.7
654658
"""
655-
return self.tags is not None and self.tags.is_guild_connections_role()
659+
return self.type is RoleType.CONNECTION
656660

657661
@property
658662
def permissions(self) -> Permissions:

discord/ui/view.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,7 @@ def from_dict(
701701
components = [_component_factory(d) for d in data]
702702
for component in _walk_all_components(components):
703703
view.add_item(_component_to_item(component))
704+
return view
704705

705706
def add_item(self, item: ViewItem[V]) -> Self:
706707
"""Adds an item to the view. Attempting to add a :class:`~discord.ui.ActionRow` will add its children instead.

discord/voice/state.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ async def voice_state_update(self, data: RawVoiceStateUpdateEvent) -> None:
346346
await self.disconnect()
347347
return
348348

349-
self.session_id = data["session_id"]
349+
self.session_id = data.session_id
350350

351351
if self.state in (
352352
ConnectionFlowState.set_guild_voice_state,

docs/api/enums.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ of :class:`enum.Enum`.
2929
A string.
3030
.. attribute:: integer
3131

32-
An integer between -2⁵³ and 2⁵³.
32+
An integer where :math:`-2^{53} < x < 2^{53}`.
3333

3434
.. note::
3535

@@ -52,7 +52,7 @@ of :class:`enum.Enum`.
5252
A mentionable (user or role).
5353
.. attribute:: number
5454

55-
A floating-point number between -2⁵³ and 2⁵³.
55+
A floating-point number where :math:`-2^{53} < x < 2^{53}`.
5656

5757
.. note::
5858

0 commit comments

Comments
 (0)