Skip to content

Commit 1df8989

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feature/dots-boxes-ai
2 parents 8e2221f + e1b99c1 commit 1df8989

59 files changed

Lines changed: 11283 additions & 763 deletions

Some content is hidden

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

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,5 @@ body:
5454
required: true
5555
- label: "I want to work on this issue"
5656
required: false
57+
- label: "I am participating in GSSoC 2026"
58+
required: false

.github/ISSUE_TEMPLATE/feature_request.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,6 @@ body:
7373
required: true
7474
- label: "I want to work on this issue"
7575
required: false
76+
- label: "I am participating in GSSoC 2026"
77+
required: false
7678

.github/ISSUE_TEMPLATE/project_proposal.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,5 @@ body:
104104
required: true
105105
- label: "I want to work on this issue"
106106
required: false
107+
- label: "I am participating in GSSoC 2026"
108+
required: false

.github/labeler.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
documentation:
2+
- '**/*.md'
3+
- 'docs/**'
4+
5+
python:
6+
- '**/*.py'
7+
8+
github-actions:
9+
- '.github/**'
10+
11+
enhancement:
12+
- 'src/**'
13+
- '*/**.py'
14+
15+
beginner:
16+
- '**/*.md'
17+
18+
intermediate:
19+
- '**/*.py'
20+
21+
advanced:
22+
- '.github/**'
23+
- 'tests/**'
24+
25+
"type:design":
26+
- 'web-app/**'
27+
- 'web-app/*.html'
28+
- 'web-app/js/**'
29+
- 'web-app/css/**'
30+
31+
"type:feature":
32+
- '**/*.py'
33+
34+
"type:docs":
35+
- '**/*.md'
36+
- 'README.html'
37+
- 'docs/**'
38+
39+
"type:devops":
40+
- '.github/**'
41+
- '.github/workflows/**'
42+
43+
"type:refactor":
44+
- '**/*.py'
45+
- 'web-app/**'
46+
47+
"type:bug":
48+
- '**/*.py'
49+
- 'tests/**'
50+

.github/pull_request_template.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,5 @@ body:
7575
required: false
7676
- label: "I have updated the README.md (if adding new project)"
7777
required: false
78+
- label: "I am participating in GSSoC 2026"
79+
required: false

.github/workflows/contributors.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: contributor automation
2+
3+
on:
4+
schedule: # runs daily at midnight
5+
- cron: '0 0 * * *'
6+
pull_request:
7+
types: [closed]
8+
branches:
9+
- main
10+
11+
# allows manual trigger
12+
permissions:
13+
contents: write
14+
15+
jobs:
16+
update-readme:
17+
if: github.event_name != 'pull_request' || github.event.pull_request.merged == true
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
23+
- name: Fetch Merged PR Authors (Pagination)
24+
env:
25+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26+
run: |
27+
set -euo pipefail
28+
PAGE=1
29+
echo "[]" > final_list.json
30+
while true; do
31+
# Using pulls endpoint to capture only merged contributors
32+
RESPONSE=$(gh api "/repos/steam-bell-92/python-mini-project/pulls?state=closed&per_page=100&page=${PAGE}")
33+
COUNT=$(echo "$RESPONSE" | jq '. | length')
34+
if [ "$COUNT" -eq 0 ]; then break; fi
35+
jq -s '.[0] + .[1]' final_list.json <(echo "$RESPONSE") > tmp.json && mv tmp.json final_list.json
36+
PAGE=$((PAGE + 1))
37+
done
38+
# Filters for actual merged PRs and unique users
39+
jq '[.[]
40+
| select(.merged_at != null and .user != null and .user.type != "Bot")
41+
| .user.login]
42+
| unique
43+
| sort' final_list.json > contributors.json
44+
- name: Build Gallery HTML
45+
run: |
46+
set -euo pipefail
47+
GALLERY_HTML=""
48+
for USERNAME in $(jq -r '.[]' contributors.json); do
49+
GALLERY_HTML="${GALLERY_HTML}<a href=\"https://github.com/${USERNAME}\"><img src=\"https://github.com/${USERNAME}.png\" width=\"50px\" loading=\"lazy\" title=\"${USERNAME}\" style=\"border-radius:50%;margin:5px;\" alt=\"${USERNAME}\" /></a>"
50+
done
51+
echo "$GALLERY_HTML" > gallery_fragment.txt
52+
53+
- name: Update README.md
54+
run: |
55+
set -euo pipefail
56+
# Safety check for markers
57+
start_count=$(grep -c '<!-- CONTRIBUTORS_START -->' README.md || true)
58+
end_count=$(grep -c '<!-- CONTRIBUTORS_END -->' README.md || true)
59+
if [ "$start_count" -ne 1 ] || [ "$end_count" -ne 1 ]; then
60+
echo "Error: README.md must contain exactly one pair of markers."
61+
exit 1
62+
fi
63+
64+
start_line=$(grep -n '<!-- CONTRIBUTORS_START -->' README.md | cut -d: -f1)
65+
end_line=$(grep -n '<!-- CONTRIBUTORS_END -->' README.md | cut -d: -f1)
66+
if [ "$start_line" -ge "$end_line" ]; then
67+
echo "Error: CONTRIBUTORS_START must appear before CONTRIBUTORS_END."
68+
exit 1
69+
fi
70+
71+
sed -i '/<!-- CONTRIBUTORS_START -->/,/<!-- CONTRIBUTORS_END -->/ {
72+
/<!-- CONTRIBUTORS_START -->/! { /<!-- CONTRIBUTORS_END -->/! d; }
73+
}' README.md
74+
sed -i '/<!-- CONTRIBUTORS_START -->/r gallery_fragment.txt' README.md
75+
76+
- name: Commit and Push
77+
run: |
78+
git config --global user.name "github-actions[bot]"
79+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
80+
git add README.md
81+
if git diff --staged --quiet; then
82+
echo "No changes to README."
83+
else
84+
git commit -m "docs: update contributor gallery"
85+
git push
86+
fi
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: GSSoC Labeler
2+
3+
on:
4+
issues:
5+
types: [opened, edited]
6+
pull_request_target:
7+
types: [opened, edited]
8+
9+
jobs:
10+
label_gssoc:
11+
runs-on: ubuntu-latest
12+
13+
permissions:
14+
issues: write
15+
pull-requests: write
16+
17+
steps:
18+
- name: Check and add GSSoC label
19+
uses: actions/github-script@v7
20+
with:
21+
script: |
22+
let bodyText = "";
23+
let issueNum = null;
24+
25+
if (context.payload.issue?.body) {
26+
bodyText = context.payload.issue.body;
27+
issueNum = context.payload.issue.number;
28+
}
29+
else if (context.payload.pull_request?.body) {
30+
bodyText = context.payload.pull_request.body;
31+
issueNum = context.payload.pull_request.number;
32+
}
33+
34+
const isGSSoC =
35+
bodyText.includes("[x] I am participating in GSSoC 2026") ||
36+
bodyText.includes("[X] I am participating in GSSoC 2026");
37+
38+
if (isGSSoC && issueNum) {
39+
await github.rest.issues.addLabels({
40+
owner: context.repo.owner,
41+
repo: context.repo.repo,
42+
issue_number: issueNum,
43+
labels: ["gssoc:accepted"],
44+
});
45+
}

.github/workflows/pr-merged-thanks.yml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,27 @@ jobs:
88
thank-contributor:
99
if: github.event.pull_request.merged == true
1010
runs-on: ubuntu-latest
11+
1112
permissions:
13+
pull-requests: write
1214
issues: write
1315

1416
steps:
1517
- name: Thank contributor for the merge
1618
uses: actions/github-script@v7
1719
with:
1820
script: |
19-
github.rest.issues.createComment({
21+
await github.rest.issues.createComment({
2022
issue_number: context.payload.pull_request.number,
2123
owner: context.repo.owner,
2224
repo: context.repo.repo,
23-
body: |
24-
🎉 **Thank you for your contribution!**
25+
body: `🎉 **Thank you for your contribution!**
2526
26-
Your Pull Request has been merged successfully.
27+
Your Pull Request has been merged successfully.
2728
28-
We appreciate the time and effort you put into improving this project. Contributions like yours help the repository grow and stay useful for everyone.
29+
We appreciate the time and effort you put into improving this project. Contributions like yours help the repository grow and stay useful for everyone.
2930
30-
If you'd like to contribute again, please check the open issues and make sure you are assigned before opening another Pull Request.
31+
If you'd like to contribute again, please check the open issues and make sure you are assigned before opening another Pull Request.
3132
32-
Thanks again for your support! 🙌
33-
})
33+
Thanks again for your support! 🙌`
34+
});
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Update Contributors
2+
3+
on:
4+
pull_request_target:
5+
types: [closed]
6+
7+
permissions:
8+
contents: write
9+
issues: write
10+
pull-requests: write
11+
12+
jobs:
13+
update_contributors:
14+
if: github.event.pull_request.merged == true
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Add contributor to README
19+
uses: actions/github-script@v7
20+
with:
21+
script: |
22+
const owner = context.repo.owner;
23+
const repo = context.repo.repo;
24+
const author = context.payload.pull_request.user.login;
25+
const path = 'README.md';
26+
27+
// Fetch current README
28+
const { data: file } = await github.rest.repos.getContent({ owner, repo, path });
29+
const content = Buffer.from(file.content, file.encoding).toString();
30+
31+
const header = '## 🙌 Contributors';
32+
33+
if (content.includes(author)) {
34+
console.log(`Contributor ${author} already present; no update needed.`);
35+
return;
36+
}
37+
38+
let newContent;
39+
40+
if (!content.includes(header)) {
41+
// Append a Contributors section
42+
newContent = content + `\n\n## 🙌 Contributors\n\n- ${author}\n`;
43+
} else {
44+
// Insert the contributor bullet directly after the header
45+
const idx = content.indexOf(header) + header.length;
46+
const before = content.slice(0, idx);
47+
const after = content.slice(idx);
48+
newContent = before + '\n\n- ' + author + '\n' + after;
49+
}
50+
51+
const updatedBase64 = Buffer.from(newContent).toString('base64');
52+
53+
await github.rest.repos.createOrUpdateFileContents({
54+
owner,
55+
repo,
56+
path,
57+
message: `chore: add contributor ${author}`,
58+
content: updatedBase64,
59+
sha: file.sha,
60+
committer: { name: 'github-actions[bot]', email: '41898282+github-actions[bot]@users.noreply.github.com' }
61+
});
62+
63+
- name: Thank contributor comment
64+
uses: actions/github-script@v7
65+
with:
66+
script: |
67+
await github.rest.issues.createComment({
68+
issue_number: context.payload.pull_request.number,
69+
owner: context.repo.owner,
70+
repo: context.repo.repo,
71+
body: `Thanks @${context.payload.pull_request.user.login}! I've added you to the contributors list.`
72+
});

.gitignore

18 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)