Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/sync-upstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,25 @@ jobs:

git push --force-with-lease origin develop

# After a clean rebase, the fork's schema patches may have moved the
# bundleVersion contract hash away from the (upstream-generated) fixture
# stamps, which would fail packages/protocol/fixtures.test.ts. Re-stamp
# them deterministically so develop stays green with no manual step.
# See packages/protocol/scripts/restamp-fixtures.ts.
- uses: ./.github/actions/ci-setup
if: steps.rebase.outcome == 'success'

- name: Re-stamp fixtures for fork schema
if: steps.rebase.outcome == 'success'
run: |
pnpm fixtures:restamp
if git diff --quiet; then
echo "Fixture bundleVersion already current."
else
git commit -am "chore(fixtures): re-stamp bundleVersion for fork schema"
git push origin develop
fi

- name: Open issue on rebase failure
if: steps.rebase.outcome == 'failure'
env:
Expand Down
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

This is a community fork. `develop` is maintained as `upstream/main` + a small patch series of thematic commits (listed in `COMMUNITY_CHANGES.md`), rebased on top of upstream at every sync. New PRs are squash-merged on `develop`, then folded into the relevant patch (or added as a new one, updating the list in `COMMUNITY_CHANGES.md`) at the next upstream sync. When a contribution is accepted upstream, drop it from the series and from the list.

### Fixture bundleVersion

`bundleVersion` (in `packages/protocol/src/schema.ts`) is a contract hash of the schema. The fork's self-hosting patches change the schema, so its hash differs from the (upstream-generated) stamps committed in `fixtures/*/.webstudio/data.json`, failing `fixtures.test.ts`. After changing the bundle schema — or after an upstream sync — run `pnpm fixtures:restamp` and commit. The `sync-upstream` workflow already does this automatically after a clean rebase; `pnpm fixtures:restamp --check` fails on drift (CI).

## Overview

Webstudio is an Open Source Visual Development Platform. This is a pnpm monorepo with three workspace types: `apps/`, `packages/`, and `fixtures/`.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"check:generated-api": "pnpm --filter @webstudio-is/project-build generate-runtime-operation-contracts && pnpm --filter @webstudio-is/builder generate-server-only-api-metadata && node scripts/check-clean-files.mjs packages/project-build/src/contracts/__generated__/runtime-operation-contracts.ts packages/protocol/src/builder-api/__generated__/server-only-router-operation-metadata.ts",
"check:generated-docs": "pnpm --filter @webstudio-is/project-build generate-docs && pnpm --filter webstudio generate-docs && node scripts/check-clean-files.mjs packages/project-build/src/docs.generated.ts packages/cli/src/docs.generated.ts",
"fixtures": "pnpm -r fixtures:link && pnpm -r fixtures:sync && pnpm -r fixtures:build",
"fixtures:restamp": "NODE_OPTIONS='--conditions=webstudio --import=tsx' node packages/protocol/scripts/restamp-fixtures.ts",
"checks": "pnpm -r test && pnpm -r typecheck && pnpm lint && pnpm check:package-boundaries && pnpm check:generated-api && pnpm check:generated-docs && pnpm fixtures",
"e2e:builder": "bash ./apps/builder/e2e/run-local.sh",
"e2e:builder:dev:backend": "E2E_SKIP_CLEANUP=true E2E_RUN_TESTS=false E2E_START_POSTGREST=true E2E_DB_BOOTSTRAP=if-empty E2E_INSTALL_PLAYWRIGHT=false bash ./apps/builder/e2e/run-local.sh",
Expand Down
77 changes: 77 additions & 0 deletions packages/protocol/scripts/restamp-fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Re-stamp the `bundleVersion` of every fixture bundle to the value computed
* from THIS checkout's schema.
*
* Why: `bundleVersion` is a contract hash derived from the schema
* (see ./src/schema.ts). This fork's self-hosting patches change the schema, so
* the hash differs from upstream's — but the committed fixtures under
* `fixtures/*` are generated by upstream and carry upstream's value. That makes
* `fixtures.test.ts` fail on every fork build. Rather than re-sync fixtures
* against a builder (needs infra), we deterministically overwrite just the
* `bundleVersion` field. The fixture data still parses under the fork schema
* (the test's `publishedProjectBundle.parse` keeps guarding that), so only the
* stamp needs refreshing.
*
* Usage:
* pnpm fixtures:restamp # rewrite stale stamps in place
* pnpm fixtures:restamp --check # report drift and exit non-zero (CI)
*
* The rewrite is a surgical text replace of the `bundleVersion` value only, so
* the rest of each data.json keeps its exact (oxfmt) formatting.
*/
import { readdirSync, readFileSync, writeFileSync, existsSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { bundleVersion } from "../src/schema";

const scriptDir = dirname(fileURLToPath(import.meta.url));
const fixturesRoot = resolve(scriptDir, "../../../fixtures");
const check = process.argv.includes("--check");

const target = JSON.stringify(bundleVersion);
const pattern = /("bundleVersion"\s*:\s*)("[^"]*"|\d+)/;

let drift = 0;
let updated = 0;

for (const entry of readdirSync(fixturesRoot, { withFileTypes: true })) {
if (entry.isDirectory() === false) {
continue;
}
const file = join(fixturesRoot, entry.name, ".webstudio", "data.json");
if (existsSync(file) === false) {
continue;
}
const text = readFileSync(file, "utf8");
const match = text.match(pattern);
if (match === null) {
continue;
}
if (match[2] === target) {
continue;
}
drift += 1;
if (check) {
console.error(`drift: ${entry.name} has ${match[2]}, expected ${target}`);
continue;
}
writeFileSync(file, text.replace(pattern, `$1${target}`));
updated += 1;
console.info(`re-stamped ${entry.name} → ${target}`);
}

if (check) {
if (drift > 0) {
console.error(
`${drift} fixture bundle(s) out of date. Run: pnpm fixtures:restamp`
);
process.exit(1);
}
console.info(`fixtures bundleVersion up to date (${target})`);
} else {
console.info(
updated === 0
? `fixtures already current (${target})`
: `re-stamped ${updated} fixture bundle(s) → ${target}`
);
}
Loading