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.jsonwith 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.jsonandmetaData.json, returns a one timekey
- Frontend prepares
-
Edit existing project
- Frontend sends
repoName,key,projectData, andcommitMessagetoPUT /api/github/edit - Backend verifies owner by hashing the
keyand 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/forkHistoryclones 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_PATis 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 startThe 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
repoNameorthemeis missing the backend falls back to a timestamp name and themedefault. - Spaces in
repoNameare converted to underscores. themesupports 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
keyand comparing withmetaData.json. - On success the service updates
projectData.jsonusing the providedcommitMessage.
Success response
{ "message": "Project updated successfully" }Possible errors
400 Missing key or RepoName300 Commit message is required403 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_PATin.envto push the cloned history.
POST /create-pr
Body
{
"forkRepo": "forked-repo-name",
"updatedProjectData": { "blocks": [] }
}Behavior
- Reads
forkedFromfrommetaData.jsonin the fork to identify the base repository. - Creates a new branch on the base repo and commits
projectData.jsonwith 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.jsonholds the serialized Music Blocks program.metaData.jsonholdscreatedAtISO timestampthemetopic stringhashedKeySHA256 of the client keyforkedFromset 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
keyvalues 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.