Skip to content

Commit b425812

Browse files
authored
Merge branch 'master' into issue
2 parents 8502352 + 98745bf commit b425812

32 files changed

+15951
-14312
lines changed

.github/PULL_REQUEST_TEMPLATE/generic.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ about: Submit changes to the project for review and inclusion
1515

1616
This PR fixes #
1717

18+
## PR Category
19+
20+
<!--- CI ENFORCED: You MUST check at least ONE category below or the CI will fail. -->
21+
<!--- Check all categories that apply to this pull request. -->
22+
23+
- [ ] Bug Fix — Fixes a bug or incorrect behavior
24+
- [ ] Feature — Adds new functionality
25+
- [ ] Performance — Improves performance (load time, memory, rendering, etc.)
26+
- [ ] Tests — Adds or updates test coverage
27+
- [ ] Documentation — Updates to docs, comments, or README
28+
1829
## Changes Made
1930

2031
<!--- Provide a summary of the changes made in this pull request. -->

.github/workflows/linter.yml

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
name: ESLint
2-
1+
name: ESLint & Prettier
32
on:
43
pull_request:
54
branches: [master]
6-
75
jobs:
86
lint:
9-
name: Lint updated JavaScript files with ESLint
10-
7+
name: Lint and format-check changed JS files
118
runs-on: ubuntu-latest
12-
139
steps:
1410
- name: Checkout code
1511
uses: actions/checkout@v4
@@ -23,26 +19,29 @@ jobs:
2319
node-version: 20.x
2420
cache: "npm"
2521

22+
- name: Install dependencies
23+
run: npm ci
24+
2625
- name: Get changed JavaScript files
2726
id: get_files
2827
run: |
29-
CHANGED_FILES=$(git diff --diff-filter=ACMRT --name-only ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} -- '*.js')
30-
echo "files<<EOF" >> $GITHUB_ENV
31-
echo "$CHANGED_FILES" >> $GITHUB_ENV
32-
echo "EOF" >> $GITHUB_ENV
33-
34-
- name: Install dependencies
35-
run: npm ci
28+
git diff --diff-filter=ACMRT --name-only ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} -- '*.js' '*.mjs' ':!node_modules/**' > changed-js-files.txt
29+
if [ -s changed-js-files.txt ]; then
30+
echo "has_files=true" >> "$GITHUB_OUTPUT"
31+
else
32+
echo "has_files=false" >> "$GITHUB_OUTPUT"
33+
fi
3634
3735
- name: Run ESLint on changed files
38-
if: env.files != ''
36+
if: steps.get_files.outputs.has_files == 'true'
3937
run: |
4038
echo "Linting the following files:"
41-
echo "$files"
42-
echo "$files" | xargs npx eslint --no-warn-ignored
39+
cat changed-js-files.txt
40+
xargs -r npx eslint < changed-js-files.txt
41+
4342
- name: Run Prettier check on changed files
44-
if: env.files != ''
43+
if: steps.get_files.outputs.has_files == 'true'
4544
run: |
4645
echo "Checking formatting for the following files:"
47-
echo "$files"
48-
echo "$files" | xargs npx prettier --check
46+
cat changed-js-files.txt
47+
xargs -r npx prettier --check < changed-js-files.txt
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
name: PR Category Check
2+
3+
# Ensures every PR has at least one category checkbox checked.
4+
# Automatically applies matching GitHub labels to the PR.
5+
# Creates labels with custom colors if they don't exist yet.
6+
# Uses pull_request_target so it works for fork PRs too (runs in base repo context).
7+
# This is safe because we only read the PR body from the event payload — no fork code is checked out or executed.
8+
9+
on:
10+
pull_request_target:
11+
types: [opened, edited, synchronize, reopened]
12+
13+
permissions:
14+
pull-requests: write
15+
contents: read
16+
17+
jobs:
18+
check-pr-category:
19+
name: Validate PR Category & Auto-Label
20+
runs-on: ubuntu-latest
21+
steps:
22+
- name: Check categories and apply labels
23+
uses: actions/github-script@v7
24+
with:
25+
script: |
26+
const prBody = context.payload.pull_request.body || '';
27+
const prNumber = context.payload.pull_request.number;
28+
29+
// Category checkboxes mapped to their GitHub label names, colors, and descriptions
30+
const categories = [
31+
{
32+
label: 'bug fix',
33+
color: 'D73A4A',
34+
description: 'Fixes a bug or incorrect behavior',
35+
displayName: 'Bug Fix',
36+
pattern: /-\s*\[x\]\s*Bug Fix/i,
37+
},
38+
{
39+
label: 'feature',
40+
color: '9333EA',
41+
description: 'Adds new functionality',
42+
displayName: 'Feature',
43+
pattern: /-\s*\[x\]\s*Feature/i,
44+
},
45+
{
46+
label: 'performance',
47+
color: 'F97316',
48+
description: 'Improves performance (load time, memory, rendering)',
49+
displayName: 'Performance',
50+
pattern: /-\s*\[x\]\s*Performance/i,
51+
},
52+
{
53+
label: 'tests',
54+
color: '3B82F6',
55+
description: 'Adds or updates test coverage',
56+
displayName: 'Tests',
57+
pattern: /-\s*\[x\]\s*Tests/i,
58+
},
59+
{
60+
label: 'documentation',
61+
color: '10B981',
62+
description: 'Updates to docs, comments, or README',
63+
displayName: 'Documentation',
64+
pattern: /-\s*\[x\]\s*Documentation/i,
65+
},
66+
];
67+
68+
const checkedCategories = categories.filter(cat => cat.pattern.test(prBody));
69+
const uncheckedCategories = categories.filter(cat => !cat.pattern.test(prBody));
70+
71+
// --- Step 1: Fail CI if no category is selected ---
72+
if (checkedCategories.length === 0) {
73+
const message = [
74+
'## PR Category Required',
75+
'',
76+
'This pull request does not have any **PR Category** selected.',
77+
'Please edit your PR description and check **at least one** category checkbox:',
78+
'',
79+
'| Category | Description |',
80+
'|----------|-------------|',
81+
'| Bug Fix | Fixes a bug or incorrect behavior |',
82+
'| Feature | Adds new functionality |',
83+
'| Performance | Improves performance |',
84+
'| Tests | Adds or updates test coverage |',
85+
'| Documentation | Updates to docs, comments, or README |',
86+
'',
87+
'Example: Change `- [ ] Bug Fix` to `- [x] Bug Fix`',
88+
'',
89+
'> **Tip:** You can select multiple categories if your PR spans several areas.',
90+
].join('\n');
91+
92+
core.setFailed(message);
93+
return;
94+
}
95+
96+
// --- Step 2: Ensure labels exist with proper colors ---
97+
const { data: existingLabels } = await github.rest.issues.listLabelsForRepo({
98+
owner: context.repo.owner,
99+
repo: context.repo.repo,
100+
per_page: 100,
101+
});
102+
const existingLabelNames = existingLabels.map(l => l.name);
103+
104+
for (const cat of categories) {
105+
if (!existingLabelNames.includes(cat.label)) {
106+
try {
107+
await github.rest.issues.createLabel({
108+
owner: context.repo.owner,
109+
repo: context.repo.repo,
110+
name: cat.label,
111+
color: cat.color,
112+
description: cat.description,
113+
});
114+
core.info(`Created label: "${cat.label}" with color #${cat.color}`);
115+
} catch (error) {
116+
core.warning(`Could not create label "${cat.label}". Error: ${error.message}`);
117+
}
118+
}
119+
}
120+
121+
// --- Step 3: Auto-apply labels for checked categories ---
122+
const labelsToAdd = checkedCategories.map(cat => cat.label);
123+
const labelsToRemove = uncheckedCategories.map(cat => cat.label);
124+
125+
// Get current labels on the PR
126+
const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({
127+
owner: context.repo.owner,
128+
repo: context.repo.repo,
129+
issue_number: prNumber,
130+
});
131+
const currentLabelNames = currentLabels.map(l => l.name);
132+
133+
// Add labels that are checked but not yet on the PR
134+
for (const label of labelsToAdd) {
135+
if (!currentLabelNames.includes(label)) {
136+
try {
137+
await github.rest.issues.addLabels({
138+
owner: context.repo.owner,
139+
repo: context.repo.repo,
140+
issue_number: prNumber,
141+
labels: [label],
142+
});
143+
core.info(`Added label: "${label}"`);
144+
} catch (error) {
145+
core.warning(`Could not add label "${label}". Error: ${error.message}`);
146+
}
147+
}
148+
}
149+
150+
// Remove labels that are unchecked but still on the PR
151+
for (const label of labelsToRemove) {
152+
if (currentLabelNames.includes(label)) {
153+
try {
154+
await github.rest.issues.removeLabel({
155+
owner: context.repo.owner,
156+
repo: context.repo.repo,
157+
issue_number: prNumber,
158+
name: label,
159+
});
160+
core.info(`Removed label: "${label}"`);
161+
} catch (error) {
162+
core.warning(`Could not remove label "${label}". Error: ${error.message}`);
163+
}
164+
}
165+
}
166+
167+
const selected = checkedCategories.map(c => c.displayName).join(', ');
168+
core.info(`PR categories selected: ${selected}`);
169+
core.info(`Labels synced: ${labelsToAdd.join(', ')}`);

.husky/pre-commit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env sh
2+
npx lint-staged

CONTRIBUTING.md

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,56 @@ contributions](https://github.com/sugarlabs/sugar-docs/blob/master/src/contribut
5656

5757
Follow [AI guidelines for Sugar Labs](https://github.com/sugarlabs/sugar-docs/blob/master/src/contributing.md#ai-guidelines-for-sugar-labs)
5858

59+
AI-assisted development tools (such as GitHub Copilot, ChatGPT, Cursor, Claude,
60+
or similar systems) may be used to support contributions. However, contributors
61+
remain fully responsible for any code they submit.
62+
63+
When using AI tools, please follow these guidelines:
64+
65+
- **Understand the code** - Do not submit code that you do not fully understand.
66+
Contributors must be able to explain and maintain their changes.
67+
- **Review carefully** - AI-generated code can contain errors, security issues,
68+
or incorrect assumptions. Always review outputs critically.
69+
- **Follow project conventions** - Ensure that generated code matches the existing
70+
coding style, architecture, and design patterns used in the repository.
71+
- **Test thoroughly** - AI-assisted changes must pass all project checks. Run
72+
linting, formatting, and test commands before submitting.
73+
- **Avoid large blind changes** - Large-scale automated modifications should be
74+
reviewed incrementally and preferably split into smaller, focused pull requests.
75+
- **Licensing awareness** - Ensure that generated content does not introduce
76+
incompatible licensed material or copied external code without attribution.
77+
- **Architecture awareness** - Prefer small, incremental AI-assisted changes that
78+
align with existing architecture rather than large structural rewrites.
79+
80+
Mentioning AI assistance in your pull request description is optional but encouraged
81+
for transparency.
82+
83+
#### Using AI/LLM tools for code changes
84+
85+
AI tools such as ChatGPT, Copilot, or other LLMs may assist contributors
86+
in understanding the codebase or drafting code changes. However,
87+
contributors remain fully responsible for the code they submit.
88+
89+
When using AI tools:
90+
91+
- Ensure you understand the generated code before including it in a pull request.
92+
- Verify that the code follows project style and architecture.
93+
- Avoid submitting large AI-generated patches without manual review.
94+
- Run linting, formatting, and tests before submitting changes.
95+
- Ensure the generated code does not introduce licensing issues.
96+
97+
#### AI-assisted pull requests
98+
99+
If AI tools were used while preparing a pull request:
100+
101+
- Clearly review and test all generated changes.
102+
- Keep pull requests small and focused.
103+
- Avoid submitting unrelated modifications suggested by AI.
104+
- Be prepared to explain the reasoning behind the changes during review.
105+
106+
AI tools should assist development, but they should not replace
107+
understanding of the codebase.
108+
59109
### Before You Push
60110

61111
Run these commands locally before submitting a PR:
@@ -66,10 +116,50 @@ npx prettier --check . # Formatting
66116
npm test # Jest
67117
```
68118

69-
NOTE: Only run ```prettier``` on the files you have modified.
119+
NOTE: Only run `prettier` on the files you have modified.
70120

71121
If formatting fails, run `npx prettier --write .` to fix it.
72122

123+
### Creating Pull Requests
124+
125+
Follow these steps when contributing:
126+
127+
1. **Create a new branch**
128+
129+
```
130+
git checkout -b docs/issue-number-short-description
131+
```
132+
133+
2. Make your changes following project guidelines.
134+
135+
3. Run required checks before pushing:
136+
137+
```
138+
npm run lint
139+
npx prettier --check .
140+
npm test
141+
```
142+
143+
4. Commit with clear, descriptive messages:
144+
145+
```
146+
git commit -m "docs: add AI contribution guidelines (Related to #XXXX)"
147+
```
148+
149+
5. Push your branch:
150+
151+
```
152+
git push origin branch-name
153+
```
154+
155+
6. **Open a Pull Request:**
156+
- Use a clear and descriptive title.
157+
- Link the related issue using `Related to #XXXX` or `Partially addresses #XXXX`.
158+
- Explain what changed and why.
159+
- Keep pull requests focused on a single topic or feature.
160+
161+
7. Respond to review feedback and update your branch as needed.
162+
73163
### After your PR is merged
74164
75165
Please note that production deployments of Music Blocks are **manual**.

css/activities.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ body:not(.dark) #helpfulSearchDiv {
135135
font-weight: bold;
136136
cursor: pointer;
137137
transition: background-color 0.2s ease;
138-
background-color: #f1f1f1;
138+
background-color: #e0e0e0;
139139
color: black;
140140
}
141141

@@ -2197,4 +2197,4 @@ table {
21972197
padding: 0 10px;
21982198
box-sizing: border-box;
21992199
}
2200-
}
2200+
}

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
});
108108
</script>
109109
<script src="lib/astring.min.js" defer></script>
110+
<script src="js/utils/mb-dialog.js" defer></script>
110111
<script src="lib/acorn.min.js" defer></script>
111112
<script src="env.js"></script>
112113

0 commit comments

Comments
 (0)