Empowering students with Git through Musicblocks
This project is being developed as part of Sugar Labs Google Summer of Code (GSoC) 2025.
Music Blocks backend is a Node.js and Express service written in TypeScript. It lets the Music Blocks frontend create, edit, fork, and browse projects that are stored as GitHub repositories. The service automates repository creation, manages metadata, and authenticates using a GitHub App installation. It is developed as a potential replacement to the existing Planet
server in Musicblocks and introduce students with the concept of Git and version control.
- Create projects: New GitHub repository per project with initial files, the project data containing the blocks`s Json and metadata containing information about the project created.
- Edit projects: Safe updates to
projectData.json
with commit messages via akey
. The key serves as an identity of the users, through which they can edit an existing project. - Fork projects: Fork with complete commit history, developed as a feature to extend on the work of other students.
- Browse data: List repos, fetch commits, retrieve Project data at any commit
-
Create new project
- Frontend prepares
projectData.json
- Sends to
POST /api/github/create
- Backend creates repo, writes
projectData.json
andmetaData.json
, returns a one timekey
- Frontend prepares
-
Edit existing project
- Frontend sends
repoName
,key
,projectData
, andcommitMessage
toPUT /api/github/edit
- Backend verifies owner by hashing the
key
and comparing withmetaData.json
- If valid, backend commits update to
projectData.json
- Frontend sends
-
View commits or load older version
- Frontend fetches list via
GET /api/github/commitHistory?repoName=...
- When a commit is selected, frontend calls
GET /api/github/getProjectDataAtCommit?repoName=...&sha=...
- Frontend fetches list via
-
Fork existing project
- Fork with history:
POST /api/github/forkHistory
clones and pushes full history, updatesmetaData.json
. - Only this feature requires a
PAT
(Personal access token).
- Fork with history:
- Runtime: Node.js 18+
- Framework: Express 5
- Language: TypeScript
- GitHub SDK:
octokit
- Testing: Jest and Supertest
src/
config/ GitHub App config and private key
controllers/ Express route handlers
middleware/ Request middleware such as owner verification
routes/ Express routers
services/ GitHub API integration and business logic
types/ Shared TypeScript types
utils/ Helpers for auth, hashing, parsing, topics
dist/ Compiled output
- Node.js 18 or later
- A GitHub App installed on the target organization
- A GitHub organization that will own project repositories
Create a .env
file at the repository root. The service reads the following variables:
PORT=3000
GITHUB_APP_ID=your_app_id
GITHUB_INSTALLATION_ID=your_installation_id
ORG_NAME=your_org_name
FORKED_ORG_NAME=optional_other_org_for_forks
GITHUB_PAT=personal_access_token_required_for_forkHistory
- Place the GitHub App private key file at
src/config/private-key.pem
. GITHUB_PAT
is required only by the fork with history workflow which pushes via HTTPS.
git clone https://github.com/BeNikk/musicblocks-backend.git
cd musicblocks-backend
npm install
npm run build
npm start
The server listens on PORT
from .env
default is 5000
in code if unset.
Base path: /api/github
POST /create
Body
{
"repoName": "my-musicblocks-project",
"projectData": { "blocks": [] },
"theme": "piano,learning",
"description": "Short description"
}
Notes
- If
repoName
ortheme
is missing the backend falls back to a timestamp name and themedefault
. - Spaces in
repoName
are converted to underscores. theme
supports a comma separated list. Topics are sanitized to GitHub topic rules.
Success response
{
"success": true,
"key": "store_this_client_side",
"repository": "created-repo-name"
}
The key
is hashed and stored in metaData.json
. Keep the raw value safely on the client to authorize edits.
PUT /edit
Body
{
"repoName": "created-repo-name",
"key": "the_key_from_create_or_fork",
"projectData": { "blocks": [1,2,3] },
"commitMessage": "Update blocks"
}
Behavior
- Middleware verifies owner by hashing
key
and comparing withmetaData.json
. - On success the service updates
projectData.json
using the providedcommitMessage
.
Success response
{ "message": "Project updated successfully" }
Possible errors
400 Missing key or RepoName
300 Commit message is required
403 Invalid key, permission denied
POST /fork
Body
{ "repositoryName": "source-repo" }
Success response
{
"repoName": "fork-source-repo-<uuid>",
"key": "new_key_for_fork",
"projectData": { },
"description": "Fork of source-repo"
}
POST /forkHistory
Body
{ "sourceRepo": "source-repo" }
Success response
{ "success": true, "repoUrl": "https://github.com/<org>/<new-repo>" }
Notes
- Requires
GITHUB_PAT
in.env
to push the cloned history.
POST /create-pr
Body
{
"forkRepo": "forked-repo-name",
"updatedProjectData": { "blocks": [] }
}
Behavior
- Reads
forkedFrom
frommetaData.json
in the fork to identify the base repository. - Creates a new branch on the base repo and commits
projectData.json
with the provided content. - Opens a pull request to
main
.
Success response
{ "success": true, "prUrl": "https://github.com/<org>/<repo>/pull/<id>" }
GET /openPR
Body
{ "repo": "target-repo" }
Response is an array where each item contains the PR metadata and the parsed projectData.json
from the PR head branch if available.
GET /commitHistory?repoName=<name>
Returns the commit list from the GitHub API for the repository.
GET /getProjectDataAtCommit?repoName=<name>&sha=<commit_sha>
Success response
{ "success": true, "projectData": { }, "sha": "<commit_sha>" }
GET /getProjectData?repoName=<name>
Success response
{ "content": { "success": true, "projectData": { } } }
GET /allRepos?page=<number>
Returns the GitHub API response for repositories. per_page
is 50 and results are ordered by creation time descending.
projectData.json
holds the serialized Music Blocks program.metaData.json
holdscreatedAt
ISO timestamptheme
topic stringhashedKey
SHA256 of the client keyforkedFrom
set on forks so that PRs can target the base repo
-
Lint
npx eslint .
-
Build
npm run build
-
Test
npm test
- Never commit
src/config/private-key.pem
. - Do not expose the raw
key
values in logs or error messages. Only the hash is stored server side.
This repository was made under Google summer of code 2025 program by Nikhil bhatt(https://github.com/Benikk)
Music Blocks Git backend is licensed under the AGPL. It is free to copy and modify. The project does not access or share user data beyond what is required to restore sessions.
Contributions welcome. Please open issues or pull requests.