Skip to content

Commit a2ec318

Browse files
authored
Merge branch 'development' into jac/redirect-followups
2 parents 79c06bc + a5a8c48 commit a2ec318

77 files changed

Lines changed: 3995 additions & 747 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/PULL_REQUEST_TEMPLATE.md‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!--
2+
Delete sections that don't apply. The prompts are here to make review
3+
faster, not to add ceremony - one sentence per section is often enough.
4+
See contributing.md for background; add a bullet to CHANGELOG.md under
5+
Unreleased for any user-visible behavior change.
6+
-->
7+
8+
## Motivation
9+
10+
<!--
11+
Why now. Link the issue, incident, user report, or parent PR. If this
12+
is preparation for another change, name it. If it's cleanup, say what
13+
prompted it.
14+
-->
15+
16+
## Behavior change
17+
18+
<!--
19+
For users of the library or CLI: what changes in observable behavior?
20+
"None - refactor only" is a valid answer. If a public symbol, endpoint
21+
signature, exception type, or return value shape changes, call it out
22+
here so downstream code isn't surprised.
23+
-->
24+
25+
## Test plan
26+
27+
<!--
28+
What's exercised by the tests in this PR. If any behavior claim in the
29+
description ISN'T covered by a test (e.g. "verified manually against a
30+
live server", "matches server behavior at REST endpoint X"), say so
31+
explicitly so reviewers know what's on trust vs. what regression tests
32+
will catch.
33+
-->

‎.github/dependabot.yml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ updates:
33
- package-ecosystem: "pip"
44
directory: "/"
55
target-branch: "development"
6+
# Security advisories fire independently of the weekly schedule as long
7+
# as the repo has "Dependabot security updates" enabled under
8+
# Settings -> Code security. Weekly = non-security updates.
69
schedule:
710
interval: "weekly"
11+
open-pull-requests-limit: 10
812

913
- package-ecosystem: "github-actions"
1014
directory: "/"
1115
target-branch: "development"
1216
schedule:
1317
interval: "weekly"
18+
open-pull-requests-limit: 10
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Mark linked issues in-progress
2+
3+
# When an open PR references an issue with Closes/Fixes/Resolves, apply the
4+
# 'in-progress' label to that issue so the stale bot leaves it alone (the
5+
# stale workflow already exempts 'in-progress'). Remove the label when the
6+
# PR closes without merging, so a genuinely abandoned PR does not keep its
7+
# referenced issues shielded forever.
8+
#
9+
# actions/stale looks at issue-level events only; a PR that references an
10+
# issue does not reset the issue's stale timer or move it off the stale
11+
# label. This workflow bridges that gap.
12+
#
13+
# Security note: the script only reads pr.body, extracts decimal issue
14+
# numbers via a fixed regex, and passes those numbers to the REST API.
15+
# Body content is never expanded into a run: command or a shell.
16+
17+
on:
18+
pull_request_target:
19+
types: [opened, edited, reopened, synchronize, ready_for_review, closed]
20+
21+
permissions:
22+
issues: write
23+
pull-requests: read
24+
25+
jobs:
26+
link:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/github-script@v9
30+
with:
31+
script: |
32+
const pr = context.payload.pull_request;
33+
const body = pr.body || '';
34+
const re = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)/gi;
35+
// Cross-repo references (owner/repo#123) are intentionally skipped;
36+
// this workflow only labels issues in the current repo.
37+
const MAX_REFS = 50; // cap runaway PR bodies from forks (pull_request_target).
38+
const extract = (text) => [...new Set(
39+
[...(text || '').matchAll(re)].map(m => Number(m[1]))
40+
)].slice(0, MAX_REFS);
41+
42+
const current = extract(body);
43+
44+
// On `edited`, compute which references were REMOVED so their
45+
// labels come off. Without this, a PR that once said "Closes #42"
46+
// and no longer does would leave #42 shielded indefinitely.
47+
let removed = [];
48+
if (context.payload.action === 'edited') {
49+
const prevBody = context.payload.changes?.body?.from;
50+
if (prevBody !== undefined) {
51+
const previous = extract(prevBody);
52+
const now = new Set(current);
53+
removed = previous.filter(n => !now.has(n));
54+
}
55+
}
56+
57+
// Apply the label while the PR is open. Remove it when the PR
58+
// closes without merging (merged PRs also close, but the issue
59+
// will be auto-closed by GitHub once the merge lands, so the
60+
// in-progress label on it is harmless). Also remove on `edited`
61+
// when a reference was deleted from the body.
62+
const shouldLabel = pr.state === 'open';
63+
const closeUnlabel = pr.state === 'closed' && !pr.merged ? current : [];
64+
const toUnlabel = [...new Set([...removed, ...closeUnlabel])];
65+
66+
if (current.length === 0 && toUnlabel.length === 0) {
67+
core.info('No Closes/Fixes/Resolves references to process; nothing to do.');
68+
return;
69+
}
70+
71+
const removeLabelSafe = async (n) => {
72+
await github.rest.issues.removeLabel({
73+
...context.repo,
74+
issue_number: n,
75+
name: 'in-progress',
76+
}).catch(err => {
77+
// 404 just means the label was not present; not an error.
78+
if (err.status !== 404) throw err;
79+
});
80+
core.info(`#${n}: removed in-progress`);
81+
};
82+
83+
if (shouldLabel) {
84+
for (const n of current) {
85+
try {
86+
await github.rest.issues.addLabels({
87+
...context.repo,
88+
issue_number: n,
89+
labels: ['in-progress'],
90+
});
91+
core.info(`#${n}: added in-progress`);
92+
} catch (err) {
93+
core.warning(`#${n}: ${err.message}`);
94+
}
95+
}
96+
}
97+
98+
for (const n of toUnlabel) {
99+
try {
100+
await removeLabelSafe(n);
101+
} catch (err) {
102+
core.warning(`#${n}: ${err.message}`);
103+
}
104+
}

‎.github/workflows/publish-pypi.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ jobs:
4747
uses: pypa/gh-action-pypi-publish@release/v1 # license BSD-2
4848
with:
4949
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
50-
repository_url: https://test.pypi.org/legacy/
51-
skip_existing: true
50+
repository-url: https://test.pypi.org/legacy/
51+
skip-existing: true
5252

5353
smoke-test-pypi:
5454
name: Smoke test from Test PyPI

‎.github/workflows/run-tests.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
os: [ubuntu-latest, macos-latest, windows-latest]
16-
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', '3.14t']
16+
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', '3.14t', '3.15']
1717

1818
runs-on: ${{ matrix.os }}
1919

‎.github/workflows/stale.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
with:
1919
stale-issue-label: 'stale'
2020
stale-pr-label: 'stale'
21-
exempt-issue-labels: 'good first issue,Design Proposal,in-progress'
21+
exempt-issue-labels: 'good first issue,Design Proposal,in-progress,Server-Side Enhancement'
2222
exempt-pr-labels: 'in-progress'
2323

2424
days-before-issue-stale: 60

0 commit comments

Comments
 (0)