Skip to content

Release code that closely integrates with Scratch under the AGPL#1518

Open
zetter-rpf wants to merge 15 commits into
mainfrom
move-scratch-files-together
Open

Release code that closely integrates with Scratch under the AGPL#1518
zetter-rpf wants to merge 15 commits into
mainfrom
move-scratch-files-together

Conversation

@zetter-rpf

@zetter-rpf zetter-rpf commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

https://github.com/RaspberryPiFoundation/digital-editor-issues/issues/1533

Changes:

  • Move the that integrated with the Scratch Editor together in a new scratch-frame app
  • Introduce a new Yarn workspace and Vite to build the scratch-frame project
  • Licence scratch-frame under AGPL

See commits for more

Still todo

  • Review and update the project README and possibly add a README file to the scratch-frame project. I'll likely do this in a seperate change

@zetter-rpf zetter-rpf force-pushed the move-scratch-files-together branch from 7f83cd5 to 7292731 Compare July 2, 2026 14:17
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 2, 2026 14:17 — with GitHub Actions Inactive
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 2, 2026 14:27 — with GitHub Actions Inactive
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 2, 2026 14:34 — with GitHub Actions Inactive
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 2, 2026 14:39 — with GitHub Actions Inactive
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 2, 2026 14:51 — with GitHub Actions Inactive
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 2, 2026 15:14 — with GitHub Actions Inactive
@zetter-rpf zetter-rpf force-pushed the move-scratch-files-together branch from a195e71 to 9f2f812 Compare July 2, 2026 16:00
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 2, 2026 16:00 — with GitHub Actions Inactive
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 3, 2026 07:53 — with GitHub Actions Inactive
@zetter-rpf zetter-rpf marked this pull request as ready for review July 3, 2026 07:56
Copilot AI review requested due to automatic review settings July 3, 2026 07:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restructures the Scratch integration by extracting the Scratch-facing bundle/assets into a new apps/scratch-frame workspace (built with Vite) and updating the main editor UI to embed and communicate with that frame via a dedicated REACT_APP_SCRATCH_FRAME_URL.

Changes:

  • Introduces a new Yarn workspace apps/scratch-frame with Vite/Vitest and moves Scratch integration code into it.
  • Updates the host app to load Scratch from REACT_APP_SCRATCH_FRAME_URL and removes the webpack “scratch” build/config.
  • Updates Docker/CI/deploy workflows to build/start/test both the host app and the new scratch-frame app; updates licensing metadata (AGPL for scratch-frame).

Reviewed changes

Copilot reviewed 37 out of 41 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
yarn.lock Adds dependencies for Vite/Vitest and the new scratch-frame workspace.
webpack.config.js Removes the scratch-specific webpack config and scratch-gui asset serving from the main dev server.
src/utils/scratchIframe.js Switches allowed Scratch postMessage origin to REACT_APP_SCRATCH_FRAME_URL.
src/utils/scratchIframe.test.js Updates tests to use REACT_APP_SCRATCH_FRAME_URL for origin calculation.
src/hooks/useScratchSaveState.test.js Updates Scratch save-state tests for the new scratch-frame origin env var.
src/components/ScratchEditor/WrappedScratchGui.jsx Removes the host-app wrapper for scratch-gui (now lives in scratch-frame).
src/components/ProjectBar/ScratchProjectBar.test.js Updates message origin assumptions to scratch-frame.
src/components/Editor/Project/ScratchContainer.test.js Updates Scratch container tests for scratch-frame origin env var.
src/components/Editor/Project/ScratchContainer.jsx Loads the Scratch iframe from REACT_APP_SCRATCH_FRAME_URL.
package.json Adds workspaces and “all” scripts intended to build/start both apps; expands lint/stylelint globs; adds scratch-frame test script.
LICENSE.txt Adds project-level license preface and sets an explicit copyright line.
Dockerfile Exposes scratch-frame port and switches container start command to start:all.
docker-compose.yml Runs start:all and publishes scratch-frame port.
cypress/e2e/spec-scratch.cy.js Uses REACT_APP_SCRATCH_FRAME_URL for simulated Scratch postMessage origins.
cypress.config.mjs Exposes REACT_APP_SCRATCH_FRAME_URL to Cypress env.
COPYRIGHT Declares apps/scratch-frame as AGPL-3.0 licensed in addition to existing Apache-2.0 notices.
apps/scratch-frame/vite.config.js New Vite config: builds scratch.html + copies scratch-gui static/chunks into build output; dev server on 3014.
apps/scratch-frame/src/WrappedScratchGui.jsx New wrapper around window.GUI scratch-gui module + integration HOC.
apps/scratch-frame/src/utils/scratchProjectSave.test.js New Vitest-based tests for scratch project save behavior.
apps/scratch-frame/src/utils/scratchProjectSave.js New scratch project save helper that calls scratch-gui’s scratchFetch.
apps/scratch-frame/src/utils/iframeUtils.js Adds allowed-origin gate for incoming postMessage events to the frame.
apps/scratch-frame/src/utils/events.js Adds parent-origin resolution and event posting helpers for cross-frame messaging.
apps/scratch-frame/src/utils/dedupeScratchWarnings.js Updates prod/dev detection to Vite’s import.meta.env semantics.
apps/scratch-frame/src/stylesheets/Scratch.scss Adds scratch-frame-specific styling overrides and extension hiding.
apps/scratch-frame/src/ScratchIntegrationHOC.test.jsx Migrates integration HOC tests from Jest style to Vitest + module mocking.
apps/scratch-frame/src/ScratchIntegrationHOC.jsx Updates integration HOC to use window.GUI and scratch-frame-local utilities.
apps/scratch-frame/src/ScratchEditor.test.jsx Adds/updates ScratchEditor tests under Vitest.
apps/scratch-frame/src/ScratchEditor.jsx ScratchEditor implementation adjusted for scratch-frame-local save/events and basePath.
apps/scratch-frame/src/scratch.test.js Updates scratch bootstrap/handshake retry tests for Vite + Vitest.
apps/scratch-frame/src/scratch.jsx scratch-frame entrypoint updated for Vite-style imports and prod detection.
apps/scratch-frame/src/bootstrap.jsx New module loader that exposes React/Redux globals and loads scratch-gui UMD bundle.
apps/scratch-frame/scratch.html Converts scratch.html to Vite module bootstrap and CSP placeholder replacements.
apps/scratch-frame/README.md Adds a minimal scratch-frame README.
apps/scratch-frame/package.json Defines scratch-frame workspace package, scripts, and deps.
apps/scratch-frame/LICENSE Adds AGPL-3.0 license text for scratch-frame.
app.json Removes Heroku app manifest.
.github/workflows/deploy.yml Uses build:all and wires scratch-frame env var for deploy builds.
.github/workflows/ci-cd.yml Starts both dev servers for Cypress and adds scratch-frame unit test step.
.eslintrc.json Adds Vitest globals override for scratch-frame test files.
.env.example Adds REACT_APP_SCRATCH_FRAME_URL default for local dev.
.devcontainer/devcontainer.json Removes Heroku-related VS Code extensions from the devcontainer setup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils/scratchIframe.js
Comment thread src/components/Editor/Project/ScratchContainer.jsx
Comment thread src/components/ProjectBar/ScratchProjectBar.test.js
Comment thread apps/scratch-frame/src/utils/iframeUtils.js
Comment thread package.json
Comment thread .github/workflows/ci-cd.yml
Comment thread apps/scratch-frame/vite.config.js Outdated
Comment thread src/utils/scratchIframe.js
Comment thread apps/scratch-frame/src/bootstrap.jsx
@zetter-rpf zetter-rpf changed the title Move scratch files together Release code that closely integrates with Scratch under the AGPL Jul 3, 2026
zetter-rpf added 11 commits July 3, 2026 10:51
I've chosen to follow the default vite monorepo structure with
sub-directories for each app.

I've not modified the files to make the diff easier to see. I'll
add additional commits to fix the imports and set up Vite for the new app.
I thought this was a good place to introduce Vite as we need
a way to build this app and there's a small amount of code to migrate.

I've made the projects use yarn workspaces for now as I think this is a
simpler first step, but we could move away from this later.
Vite expects this to signal that it's an inline import
This does two things:

It migrates env vars from `process.env`` to `import.meta.env`. I've
added a REACT_APP prefix so the apps can share a single .env file for
now.

It also introduces a new env var REACT_APP_SCRATCH_FRAME_URL which is
split off from ASSETS_URL. I've done this so that it's easier to run
the scratch-frame app from a separate port locally. In production
it will be set to the same URL as ASSETS_URL.
We can't use erb-style interpolation any more.
Create our own transformer to replace the strings
We were loading Scratch like this previously in Webpack, the difference
is that webpack 'externals' config is a bit more powerful and can be
used to keep the imports. I couldn't get Vite configured in the same way
so instead use the window.GUI object directly.

I thought I might be able to remove scratch-gui script tag in the
bootstrap file and use the import script, but one problem I ran into was
that some scratch assets are imported relative to the Scratch js file.
Having the file in a vendor directory made this easier to manage
(otherwise assets will need to be copied to src).
Scratch expects some assets to be in `scratch-gui/` and some to be in
`vendor/`. I had previously thought that vendor was hardcoded in
Scratch, but it's actually based on the location of the scratch-gui
file that we set in our build. By putting the file in `scratch-gui/`
instead of `vendor/`, we can server more of scratch's assets from the
same location, which is simpler and will reduce the build time.
We now deploy to cloudflare so don't need this.
For now, I've taken the easier route of making stylelint and eslint
work across app apps. In the future we could create different configs
and/or linters for these apps.
Make sure we're building and testing the apps in CI and
can run the app with docker.

We could create separate docker containers for each app, but for now
while the apps share the root package.json, I think it's
fine to run them all in one container.

I've chosen to build both apps in the same directory
to mirror the way the apps were built and deployed before.

I've checked that there's no overlap between files. If we wanted to
make this safer we could build to separate directories and combine in
the sync. It's harder to change the location for some of the scratch
assets.

Host: true is required for the app to be runnable within docker
@zetter-rpf zetter-rpf force-pushed the move-scratch-files-together branch from 5a2d86b to 4161faf Compare July 3, 2026 09:52
@zetter-rpf zetter-rpf temporarily deployed to previews/1518/merge July 3, 2026 09:52 — with GitHub Actions Inactive
Rather than configure jest with vite, use vitest.

This work was mostly done by Codex.
Since Scratch editor is licenced under AGPL and scratch-frame is tightly integrated with the scratch editor component we think it needs be licenced under the AGPL too. Some of the setup code might be on the AGPL code in the scratch editor repository which is another reason to licence it this way.

Now it's clearer that the Scratch Frame is a standalone app, doesn't share code editor ui, and has a message-based interface with with it's consumer.
Because we have a LICENSE and a COPYRIGHT file, it may be easy just to look at the license and
assume it applies everywhere.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a955413. Configure here.

Comment thread package.json
@mwtrew mwtrew self-assigned this Jul 3, 2026
@mwtrew mwtrew self-requested a review July 3, 2026 12:34

@mwtrew mwtrew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good - nice to see the initial moves with Vite and workspaces too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants