You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I don't really have the time or (more importantly) motivation to review
extensions these days.
I've gotten the feedback that reviewers don't merge pull requests
because there is no guidance when things are okay to be merged. So I'm
trying to define that here.
Here's my idea. We define passing the automated tests + getting two
approvals as fully sufficient to be merged. Now just have to define
criteria for an approval, so I've written some guidelines and a couple
templates to copy and paste into the review comment box. Check all the
boxes, then you can approve it. Get two of those, then any reviewer can
merge it.
Read the new document. It's not long. Give feedback to refine it. You'll
be the ones following it after all
---------
Co-authored-by: PPPDUD <107440101+PPPDUD@users.noreply.github.com>
Co-authored-by: DNin01 <106490990+DNin01@users.noreply.github.com>
- A better development server: https://docs.turbowarp.org/development/extensions/better-development-server
13
+
## Acceptance criteria
12
14
13
-
Read this document **in full** too. Pull requests that don't follow the guidelines will take *much* longer to be reviewed.
15
+
These categories of extensions are **highly discouraged**:
14
16
15
-
## Acceptance criteria
17
+
- Broad "Utilities" extensions. Break them up into multiple extensions instead. See https://github.com/TurboWarp/extensions/issues/674 for discussion.
18
+
- Extensions that are very similar to existing ones. Consider modifying the existing extension instead.
19
+
- Very niche extensions. You can write the extension for yourself, then import it as a file instead without needing us to review.
20
+
- Extensions whose primary purpose is monetization. It isn't in the spirit of a free and open source project.
21
+
- Joke extensions. Things that are funny to you are not funny to everyone, especially when we get bug reports about it.
16
22
17
-
Strictly, nothing is banned, but the following are *highly* discouraged:
23
+
Some extensions were added before these guidelines existed. We're trying to enforce them moving forward.
18
24
19
-
- Broad "Utilities" extensions (break them up into multiple extensions, see https://github.com/TurboWarp/extensions/issues/674)
20
-
- Extensions that are very similar to existing ones (consider modifying the existing one instead)
21
-
- One-use personal extensions (load the extension as a local file instead)
22
-
- Extensions whose primary purpose is monetization (not in the spirit of an open source project)
23
-
- Joke extensions (they aren't funny when they cause us to get bug reports)
25
+
## Security
24
26
25
-
Some extensions were added before these rules existed. That doesn't mean you will be exempted too.
27
+
TurboWarp's threat model is that loading a project in the editor should be no more dangerous than opening a PowerPoint. Projects can't affect anything outside of the editor without consent from the user. We offer a [bug bounty](https://github.com/TurboWarp/extensions/security/policy) to people who find and report security bugs in merged extensions. Most guardrails can disappear once the project is packaged.
28
+
29
+
Evaluating project-supplied JavaScript using `eval()`, `new Function()`, or other methods is not allowed.
26
30
27
31
## Important context
28
32
29
-
Every merged extension is more code that we will be expected to maintain indefinitely, even if you disappear. Remember: broken extensions mean that real projects by real people no longer work. If the renderer is rewritten one day, we will have to ensure that extensions like Clipping & Blending, RGB Channels, and Augmented Reality still work. That's not a small commitment.
33
+
Every merged extension is more code that we are expected to maintain indefinitely, even if you disappear. Broken extensions mean that real projects by real people no longer work. If the renderer is rewritten one day, we will have to ensure that extensions like Clipping & Blending, RGB Channels, and Augmented Reality still work. That's not a small commitment.
30
34
31
35
We're all volunteers who all have lives outside of TurboWarp extensions. Many have full time jobs or are full time students. We'll get to you as soon as we can, so please be patient.
32
36
33
-
Every extension is also covered under [our bug bounty](https://github.com/TurboWarp/extensions/security/policy), so mindlessly merging things will have a direct impact on my wallet.
34
-
35
-
## Writing extensions
37
+
## Writing and organizing extensions
36
38
37
-
Extension source code goes in the [`extensions`](extensions) folder. For example, an extension placed at `extensions/hello-world.js` would be accessible at [http://localhost:8000/hello-world.js](http://localhost:8000/hello-world.js)using our development server.
39
+
This repository contains a custom development server. Extension source code goes in the [`extensions`](extensions) folder. For example, an extension placed at `extensions/hello-world.js` would be accessible at [http://localhost:8000/hello-world.js](http://localhost:8000/hello-world.js)when you start the development server.
38
40
39
-
New extensions should be added in a user folder. You can name your folder anything you want; common choices are your GitHub username or your Scratch username. If your username is `TestMuffin123`, then `TestMuffin123`, `TestMuffin`, or even just `Muffin` would all be accepted -- we are very lenient about this. Do note that user folders are just for organization; other people are still allowed to edit your extension. Renaming your folder later is only allowed in very rare circumstances, so please get it right the first time.
40
-
41
-
Extensions must be self-contained. All libraries and hardcoded resources should be embedded into the extension's JavaScript file. If you include minified code, please link where to find the unminified code and include a copy of the original license.
41
+
New extensions should be added in a user folder. You can name your folder anything you want; common choices are your GitHub username or your Scratch username. You can largely choose whatever you want. These folders are just for organization; other people are still allowed to edit your extension. Folder name changes are only granted in rare circumstances, so please get it right the first time.
42
42
43
43
## License
44
44
45
45
**We are not lawyers. This is not legal advice.**
46
46
47
-
Everything in this repository must be available under an open source license. You can use any license you want, but we **STRONGLY**recommend using the [Mozilla Public License verison 2.0](licenses/MPL-2.0.txt) for all new extensions.
47
+
Everything in this repository must be available under an open source license. You can use any license you want, but we recommend using the [Mozilla Public License verison 2.0](licenses/MPL-2.0.txt) for all new extensions.
48
48
49
-
The following licenses are banned for being [incompatible the GPLv3](https://www.gnu.org/licenses/license-list.en.html), so do not use any code, images, etc. under them:
49
+
All extension are included in TurboWarp Desktop which is licensed under the GPLv3. Thus, you need to use [a license that is compatible with GPLv3](https://www.gnu.org/licenses/license-list.en.html). This excludes:
50
50
51
51
- Creative Commons Attribution-ShareAlike licenses prior to version 4.0
52
-
- This includes user-generated content on the Scratch website which [uses version 2.0](https://scratch.mit.edu/terms_of_use) of this license.
52
+
- This includes user-generated content on the Scratch website which [uses version 2.0](https://scratch.mit.edu/terms_of_use).
53
53
- This includes StackOverflow posts contributed before 2018-05-02 which [use several different versions](https://stackoverflow.com/help/licensing).
54
-
-Creative Commons Attribution-NoDerivs and similar "no derivatives" licenses
55
-
-Creative Commons Attribution-NonCommercial and similar "non commercial" or "personal use only" licenses
54
+
-"No derivatives" licenses such as Creative Commons Attribution-NoDerivs
55
+
-"Non commercial" or "personal use only" licenses such as Creative Commons Attribution-NonCommercial
56
56
57
-
Once you choose a license for your extension, [find its SPDX identifier from this table](https://spdx.org/licenses/). The "FSF Free/Libre?" and "OSI Approved?" columns should both contain "Y".
57
+
Once you choose a license for your extension, [find its SPDX identifier from this table](https://spdx.org/licenses/). The "FSF Free/Libre?" and "OSI Approved?" columns should both contain "Y". You'll need to include the identifier in the extension's metadata.
58
58
59
59
## Metadata
60
60
61
-
All extensions should need a metadata comment at the *very*start of the file, before any code. We have a script that will read these, so to make sure it understands what you write, use this exact format:
61
+
All extensions need a metadata comment at the start of the file, before any code. This section gets read by a script, so make sure to follow the format closely.
62
62
63
63
```js
64
64
// Name: My Cool Extension
@@ -71,33 +71,58 @@ All extensions should need a metadata comment at the *very* start of the file, b
71
71
72
72
You must use line comments; block comments `/* */` will not work. These fields are **REQUIRED**:
73
73
74
-
-`Name`will appear on the website. It should be similar to the name returned by getInfo().
75
-
-`ID`should be identical to the id returned by getInfo().
76
-
-`Description`will appear on the website.
77
-
-`License` describes the license that the extension's code is under. It should be a valid [SPDX license](https://spdx.org/licenses/) expression. (use `MPL-2.0` if you are unsure)
74
+
-`Name`appears on the website and in the library. It should be similar to the `name` returned by getInfo().
75
+
-`ID`must be identical to the `id` returned by getInfo().
76
+
-`Description`appears on the webstie and in the library.
77
+
-`License` describes the license that the extension's code is under. It must be a valid [SPDX license](https://spdx.org/licenses/) expression. For the Mozilla Public License verison 2.0 that we recommend, the identifier is `MPL-2.0`.
78
78
79
-
`By`is optionally used to credit the author of the extension (you!). `Original` is used if the extension is based on or ported from somewhere else. They both use the same format of `Name` or `Name <https://scratch.mit.edu/users/username>`. Links to places other than Scratch are not allowed at this time. You can repeat both of these as many times as needed, just add another `// By: ...` comment after.
79
+
`By`allows you to credit yourself. `Original` is used if the extension is based on another person's work. They both use the same format of `Name` or `Name <https://scratch.mit.edu/users/username>`. Links to places other than Scratch are not allowed at this time. You can repeat both of these as many times as needed, just add another `// By: ...` comment.
80
80
81
-
In addition to `// License: ...`, you can also add a larger block comment with more information if you want to.
81
+
## Translations
82
82
83
-
## Website stuff
83
+
Extensions should support being translated into any language. The development server and [volunteer translators](https://docs.turbowarp.org/translate) will handle the hard part. The developer's job is to use `Scratch.translate()` for any string that should be translated, such as block text or labels. Here's some examples to explain the idea:
84
84
85
-
Add your extension's path (without `extensions/` and without `.js`) to `extensions/extensions.json`. The order of that list determines the order of the library. Don't worry about putting it in the right spot, we'll move it if we disagree.
85
+
```js
86
+
// For simple strings that can be understood without additional context,
87
+
// call Scratch.translate with your string directly:
88
+
Scratch.translate("stage width")
89
+
90
+
// The translation system handles block inputs properly, so use the same process:
91
+
Scratch.translate("move [STEPS] steps")
92
+
93
+
// If your string needs some context to understand properly, call
94
+
// Scratch.translate with an object:
95
+
Scratch.translate({
96
+
default:"map",
97
+
description:"A map in the computer science sense. Maps keys to values. Sometimes called a dictionary."
98
+
})
99
+
100
+
// If your string needs to fill in a value that isn't known until runtime,
101
+
// use a placeholder. Don't try to concatenate strings yourself as that is
102
+
// confusing and not all languages have the same grammar structure.
103
+
Scratch.translate({
104
+
default:"Hello, {name}!",
105
+
description:"{name} is replaced with the user's name"
106
+
}, {
107
+
name:"world"
108
+
})
109
+
```
86
110
87
-
New extensions do not *need* images, but they are encouraged. Save the image in the `images` folder with the same folder name and file name (but different file extension) as the extension's source code. For example, if your extension is located in `extensions/TestMuffin/fetch.js`, save the image as `images/TestMuffin/fetch.svg` or `images/TestMuffin/fetch.png`. The homepage generator will detect it automatically. Images are displayed in a 2:1 aspect ratio. SVG (preferred), PNG, or JPG are accepted. PNG or JPG should be 600x300 in resolution. Please add proper attribution to `images/README.md` for *any* resources that were not made by you. The resulting image must be licensed under the [GNU General Public License version 3](licenses/GPL-3.0.txt).
111
+
All translators will see is the extension's name and description, the English text, and any description you add.
88
112
89
-
Most extensions shouldn't need external documentation -- it should be obvious what to do just by looking at the blocks. That said, some do need more explanation. Documentation is written in markdown and placed in the `docs` folder with a similar layout to images. For example, documentation for `extensions/TestMuffin/fetch.js` would be saved as `docs/TestMuffin/fetch.md`. Our version of markdown is slightly extended to allow rendering [scratchblocks](https://scratchblocks.github.io/). Just look at the existing documentation for syntax examples. It's not a perfect experience: block colors have to be manually copied, and icons aren't supported, but it's better than what we had before. Once you put your markdown there, you can set a `docsURI` like `https://extensions.turbowarp.org/TestMuffin/fetch`.
113
+
## Third-party libraries
90
114
91
-
Static resources such as example resources used by extensions go in the `website` folder.
115
+
First, try to avoid using third-party libraries if you can. If you must, we have a custom dependency system for extensions called `Scratch.external`. It's somewhat in flux but the type definitions should make it clear enough how to use.
92
116
93
-
## Banned APIs
117
+
## Adding your extension to the library
94
118
95
-
Don't use these:
119
+
Add your extension's path (without `extensions/` and without `.js`) to `extensions/extensions.json`. The order of that list determines the order of the library. Try to put it next to related related extensions if possible.
96
120
97
-
-`eval()`
98
-
-`new Function()`
99
-
- untrusted or remote `<script>` or `<iframe>`
100
-
- other arbitrary JS/CSS/HTML evaluation
121
+
New extensions do not need an image for the library, but they are encouraged. Put any image in the `images` folder with the same folder name and file name but different file extension as the extension's JavaScript. For example, if your extension's code is in `extensions/TestMuffin/fetch.js`, the image would be `images/TestMuffin/fetch.svg` or `images/TestMuffin/fetch.png`. The homepage generator will find this file automatically. Images are displayed in a 2:1 aspect ratio. SVG (preferred), PNG, or JPG are accepted. PNG or JPG should be 600x300 in resolution. Add attribution to `images/README.md` for yourself and anything not made by you. Images submitted to this repository must be licensed under the [GNU General Public License version 3](licenses/GPL-3.0.txt). Avoid text if possible since these images can't be translated.
122
+
123
+
Most extensions shouldn't need external documentation -- it should be obvious what to do just by looking at the blocks. That said, some do need more explanation. Documentation is written in markdown and placed in the `docs` folder with a similar layout to images. For example, documentation for `extensions/TestMuffin/fetch.js` would be `docs/TestMuffin/fetch.md`. Our version of markdown is extended to allow rendering [scratchblocks](https://scratchblocks.github.io/). Just look at the existing documentation for syntax examples. It's not a perfect experience: block colors have to be manually copied, and icons aren't supported, but it's better than what we had before. Once you put your markdown there, you can set a `docsURI` like `https://extensions.turbowarp.org/TestMuffin/fetch`.
124
+
125
+
Static resources such as example resources used by extensions go in the `website` folder. They are copied to the final website without any additional processing.
101
126
102
127
## Type checking
103
128
@@ -107,32 +132,26 @@ If you encounter a TypeScript error, as long as you understand the error, feel f
107
132
108
133
## Linting, validation, and formatting
109
134
110
-
All pull requests are automatically checked by a combination of custom validation scripts, [ESLint](https://eslint.org/), and [Prettier](https://prettier.io/). Don't worry about passing these checks on the first attempt -- most don't. That's why we have these checks.
135
+
All pull requests are automatically checked by a combination of custom validation scripts, [ESLint](https://eslint.org/), and [Prettier](https://prettier.io/). Don't worry about passing these checks on the first attempt -- most don't. That's why we have these checks. Click on the failing check to view more details about what failed. All checks will tell you which file failed and usually some additional explanation.
111
136
112
-
Our custom validation scripts do things like making sure you have the correct headers at the start of your extension and that the images are the right size. **Your extension must pass validation.** You can run them locally with:
137
+
Our custom validation scripts do things like making sure you have the correct headers at the start of your extension and that the images are the right size. **Your extension must pass validation.**The errors will tell you what file failed and why to help you fix it. You can run these checks locally with:
113
138
114
139
```bash
115
140
npm run validate
116
141
```
117
142
118
-
ESLint detects common JavaScript errors such as referencing non-existant variables.**Your extension must pass linting.** You can run it locally with:
143
+
ESLint detects common JavaScript errors such as referencing non-existant variables as well as extension-specific issues such as fetching a resource without using Scratch.fetch().**Your extension must pass linting.** You are allowed to [disable ESLint warnings and errors](https://eslint.org/docs/latest/use/configure/rules#disabling-rules), with proper justification. You can run ESLint locally with:
119
144
120
145
```bash
121
146
npm run lint
122
147
```
123
148
124
-
You are allowed to [disable ESLint warnings and errors](https://eslint.org/docs/latest/use/configure/rules#disabling-rules) as needed, but please only do so if actually required.
125
-
126
-
When including third-party code, especially minified code, you may use `/* eslint-disable*/` and `/* eslint-enable */` markers to disable linting for that entire section.
127
-
128
-
We use Prettier to ensure consistent code formatting. **Your extension does not need to pass format; we will fix it for you if linting and validation pass.** You can format your code automatically with:
149
+
We use Prettier to ensure consistent code formatting. You can format your pull request by commenting "!format" on it then waiting a couple minutes for the bot to process it, or you can format your code locally with:
0 commit comments