00ab790a7f56
prove koh offer --builds --json names saves that came in flagged during a stolen repo's upgrade, sharing the test platform helper (v3.0.88)
- time
- 2026-09-28 15:36 UTC · 2 weeks ago
- machine
- Junes-MacBook-Pro.local
- agent
- claude-opus-5-5
- session
- quarantine unsafe paths
- parent
- 0336dc246093
↓ kepr-00ab790a.tar.gzatlas at this save
files changed4 files
package.json+1 −1tests/fixture.ts+7 −0tests/kohrelease.test.ts+1 −8tests/kohsteal.test.ts+23 −1package.json+1 −1
@@ -1,6 +1,6 @@11 {22 "name": "kepr",3- "version": "3.0.87",3+ "version": "3.0.88",44 "private": true,55 "type": "module",66 "scripts": {tests/fixture.ts+7 −0
@@ -236,3 +236,10 @@236236 await writeFile(join(dir, "release.json"), JSON.stringify(record, null, 2));237237 if (latest) await writeFile(join(bucketDir, repo, "releases", "latest"), release.version);238238 }239+240+/** This machine's platform, which is what `koh build` builds for with no flags. */241+export function platform(): string {242+ const os = process.platform === "darwin" ? "macos" : "linux";243+ const arch = process.arch === "arm64" ? "aarch64" : "x86_64";244+ return `${os}-${arch}`;245+}tests/kohrelease.test.ts+1 −8
@@ -9,7 +9,7 @@99 import { syncAll } from "../src/bucket/sync.ts";1010 import { createApp } from "../src/server/app.ts";1111 import { openKeprDb } from "../src/server/db.ts";12-import { kohWorkspace } from "./fixture.ts";12+import { kohWorkspace, platform } from "./fixture.ts";1313 1414 /**1515 * The joint contract (§3 item 4): `koh3 offer --builds` publishes a release into a folder remote@@ -23,13 +23,6 @@2323 "a release note long enough to clear forty characters and the twelve word rule easily";2424 // No newline: a real newline inside koh.build's command would end the line there.2525 const ARTIFACT = "the artifact";26-27-/** This machine's platform, which is what `koh build` builds for with no flags. */28-function platform(): string {29- const os = process.platform === "darwin" ? "macos" : "linux";30- const arch = process.arch === "arm64" ? "aarch64" : "x86_64";31- return `${os}-${arch}`;32-}3326 3427 type Latest = {3528 version: string;tests/kohsteal.test.ts+23 −1
@@ -18,7 +18,7 @@1818 import { createApp } from "../src/server/app.ts";1919 import { openKeprDb } from "../src/server/db.ts";2020 import { Browser, PASSWORD } from "./browser.ts";21-import { stripPath } from "./fixture.ts";21+import { platform, stripPath } from "./fixture.ts";2222 2323 const REPO = "shipped";2424 const PRIVATE_REPO = "kept";@@ -198,6 +198,10 @@198198 const third = join(root, "thief-three");199199 await mkdir(third, { recursive: true });200200 expect((await koh3(third, thiefHome, ["steal", `${host}/${REPO}`])).code).toBe(0);201+ // And a fourth, for `offer --builds --json` to upgrade.202+ const fourth = join(root, "thief-four");203+ await mkdir(fourth, { recursive: true });204+ expect((await koh3(fourth, thiefHome, ["steal", `${host}/${REPO}`])).code).toBe(0);201205 202206 // Signing in: a code from the connect page, read the way `koh` reads it.203207 // This Kepr's domain is the loopback address it is served on, so the same-origin@@ -280,6 +284,17 @@280284 // Saves that come in flagged during offer's upgrade are named in its JSON, as steal's are.281285 expect((await koh3(repoDir, ownerHome, ["steal"])).code).toBe(0);282286 await writeFile(join(repoDir, "risky.txt"), "risky\n");287+ // The same save brings a build file, so the fourth copy can publish a release.288+ await writeFile(join(repoDir, "VERSION"), "1.0.0\n");289+ await writeFile(290+ join(repoDir, "koh.build"),291+ [292+ `command = mkdir -p out && printf built > out/app-1.0.0-${platform()}`,293+ "output = out/app-{version}-{platform}",294+ `platforms = ${platform()}`,295+ "",296+ ].join("\n"),297+ );283298 const risky = JSON.parse(284299 (await koh3(repoDir, ownerHome, ["save", "risky", "--json"])).out,285300 ).id;@@ -289,6 +304,13 @@289304 const flaggedOffer = await koh3(join(third, REPO), thiefHome, ["offer", "--json"]);290305 expect(flaggedOffer.code, flaggedOffer.err + flaggedOffer.out).toBe(0);291306 expect(JSON.parse(flaggedOffer.out).flagged).toEqual([risky]);307+ const flaggedBuilds = await koh3(join(fourth, REPO), thiefHome, [308+ "offer",309+ "--builds",310+ "--json",311+ ]);312+ expect(flaggedBuilds.code, flaggedBuilds.err + flaggedBuilds.out).toBe(0);313+ expect(JSON.parse(flaggedBuilds.out).flagged).toEqual([risky]);292314 } finally {293315 bucketServer.stop();294316 }