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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged.

## Unreleased

### `bun run dev` no longer starts a routines worker that cannot start

`bun run dev` fanned out across every workspace, and one of them is the routines worker. That worker
is handed `DATABASE_URL`, `SERVER_INTERNAL_URL` and `WORKER_SHARED_SECRET` by `scripts/start.sh` and
by nothing else, so the copy this command started read none of them and threw at boot on every run,
printing a stack trace in between the app's output and the server's. It has never started
successfully. The command now starts the app and the server, which is what `README.md` and
`docs/development.md` already say it does. Routines are unaffected: `scripts/start.sh` starts the
worker exactly as before, and on Kubernetes the CronJob does.

### Double-clicking works while a person is driving a Bot's browser

A double click was sent to the Bot's browser as two separate first clicks, because every press said
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"scripts": {
"build": "bun run generate:app-config && bun run --filter '*' build",
"dev": "bun run generate:app-config && bun run --filter '*' --parallel dev",
"dev": "bun run generate:app-config && bun run --filter app --filter server --parallel dev",
"generate:app-config": "bun --env-file=.env scripts/generate-app-config.ts",
"format": "bunx biome format --write .",
"format:check": "bunx biome format .",
Expand Down
49 changes: 44 additions & 5 deletions tests/workspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,56 @@ function packageManifest(path: string) {
};
}

function rootManifest() {
return JSON.parse(
readFileSync(join(repositoryRoot, "package.json"), "utf8"),
) as { workspaces: string[]; scripts: Record<string, string> };
}

function packagesStartedBy(script: string, workspaces: string[]): string[] {
const filters = [
...script.matchAll(/--filter\s+(?:'([^']*)'|"([^"]*)"|(\S+))/g),
].map((match) => match[1] ?? match[2] ?? match[3]);
return workspaces.filter((workspace) =>
filters.some((filter) => filter === "*" || filter === workspace),
);
}

describe("OpenBot workspace", () => {
test("defines the app, server, and worker packages", () => {
const rootManifest = JSON.parse(
readFileSync(join(repositoryRoot, "package.json"), "utf8"),
) as { workspaces: string[] };
const manifest = rootManifest();

expect(rootManifest.workspaces).toEqual(["app", "server", "worker"]);
expect(manifest.workspaces).toEqual(["app", "server", "worker"]);

for (const packageName of rootManifest.workspaces) {
for (const packageName of manifest.workspaces) {
expect(existsSync(join(repositoryRoot, packageName))).toBe(true);
expect(packageManifest(packageName).name).toBe(packageName);
}
});

test("dev starts the app and the server, and not the routines worker", () => {
const manifest = rootManifest();

expect(
packagesStartedBy(manifest.scripts.dev, manifest.workspaces),
).toEqual(["app", "server"]);
});

test("build still covers every workspace, including the worker", () => {
const manifest = rootManifest();

expect(
packagesStartedBy(manifest.scripts.build, manifest.workspaces),
).toEqual(manifest.workspaces);
});

test("scripts/start.sh is what starts the routines worker", () => {
const startScript = readFileSync(
join(repositoryRoot, "scripts", "start.sh"),
"utf8",
);

expect(startScript).toContain("bun worker/src/index.ts");
expect(startScript).toContain("WORKER_SHARED_SECRET=");
});
});