import { createRemoteJWKSet, jwtVerify, type JWTPayload } from "jose" interface Env { DB: D1Database } type ArtifactRow = { channel: string name: string distribution: string version: string metadata: string active: number time_created: number time_updated: number } type Artifact = Omit & { metadata: unknown active: boolean } type ArtifactInput = Pick & { metadata: unknown } const identifier = /^[a-zA-Z0-9._-]{1,64}$/ const version = /^[a-zA-Z0-9.+_-]{1,128}$/ const select = "SELECT channel, name, distribution, version, metadata, active, time_created, time_updated FROM artifact" const audience = "https://update.opencode.ai" const githubKeys = createRemoteJWKSet(new URL("https://token.actions.githubusercontent.com/.well-known/jwks")) export default { async fetch(request, env): Promise { const url = new URL(request.url) if (url.pathname === "/") return json({ service: "opencode-updates" }) if (url.pathname === "/admin" && request.method === "GET") return admin(request, env) if (url.pathname === "/admin/activate" && request.method === "POST") return activateArtifact(request, env) if (url.pathname === "/api/publish" && request.method === "POST") return publishArtifact(request, env) if (request.method !== "GET") return new Response("Method not allowed", { status: 405 }) const segments = url.pathname.split("/").filter(Boolean) if (segments.length === 2 && segments[0] === "api" && validIdentifier(segments[1])) { return channel(env.DB, segments[1]) } if ( segments.length === 3 && segments[0] === "api" && validIdentifier(segments[1]) && validIdentifier(segments[2]) ) { return artifactName(env.DB, segments[1], segments[2]) } if ( segments.length === 4 && segments[0] === "api" && validIdentifier(segments[1]) && validIdentifier(segments[2]) && validIdentifier(segments[3]) ) { return artifactDistribution(env.DB, segments[1], segments[2], segments[3]) } return new Response("Not found", { status: 404 }) }, } satisfies ExportedHandler async function channel(db: D1Database, channel: string) { const result = await db .prepare(`${select} WHERE channel = ? AND active = 1 ORDER BY name, distribution`) .bind(channel) .all() if (!result.results.length) return json({ error: "Channel not found" }, 404) return cached({ channel, artifacts: result.results.map(decodeArtifact) }) } async function artifactName(db: D1Database, channel: string, name: string) { const result = await db .prepare(`${select} WHERE channel = ? AND name = ? AND active = 1 ORDER BY distribution`) .bind(channel, name) .all() if (!result.results.length) return json({ error: "Artifact not found" }, 404) return cached({ channel, name, artifacts: result.results.map(decodeArtifact) }) } async function artifactDistribution(db: D1Database, channel: string, name: string, distribution: string) { const artifact = await db .prepare(`${select} WHERE channel = ? AND name = ? AND distribution = ? AND active = 1`) .bind(channel, name, distribution) .first() if (!artifact) return json({ error: "Artifact not found" }, 404) return cached(decodeArtifact(artifact)) } async function admin(request: Request, env: Env) { const url = new URL(request.url) const requestedPage = Number.parseInt(url.searchParams.get("page") ?? "1", 10) const page = Number.isSafeInteger(requestedPage) && requestedPage > 0 ? requestedPage : 1 const pageSize = 100 const count = await env.DB.prepare("SELECT COUNT(*) AS total FROM artifact").first<{ total: number }>() const pages = Math.max(1, Math.ceil((count?.total ?? 0) / pageSize)) const currentPage = Math.min(page, pages) const result = await env.DB .prepare(`${select} ORDER BY time_created DESC LIMIT ? OFFSET ?`) .bind(pageSize, (currentPage - 1) * pageSize) .all() const rows = result.results .map( (artifact) => ` ${escape(artifact.channel)} ${escape(artifact.name)} ${escape(artifact.distribution)} ${escape(artifact.version)} ${new Date(artifact.time_created).toISOString()} ${artifact.active ? 'Active' : 'Inactive'} ${ artifact.active ? "" : `
` } `, ) .join("") return new Response( ` OpenCode Updates

Release control

Artifacts

${escape(request.headers.get("Cf-Access-Authenticated-User-Email") ?? "Cloudflare Access pending")}

Published builds

Every build received from the trusted publishing workflow, newest first.

${rows || ''}
ChannelNameDistributionVersionCreatedStatus
No builds have been published yet.

Page ${currentPage} of ${pages} ยท ${count?.total ?? 0} builds

`, { headers: { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" } }, ) } async function publishArtifact(request: Request, env: Env) { const claims = await verifyGitHub(request) if (claims instanceof Response) return claims const input: unknown = await request.json().catch(() => undefined) const artifact = parseArtifact(isRecord(input) ? input : {}) if (artifact instanceof Response) return artifact if (!channelsForRef(claims.ref).includes(artifact.channel)) return json({ error: "Channel is not allowed" }, 403) if (!isRecord(artifact.metadata)) return json({ error: "Metadata must be an object" }, 400) await activate(env.DB, [ { ...artifact, metadata: { ...artifact.metadata, github: { sha: claims.sha, run_id: claims.run_id, run_attempt: claims.run_attempt, actor: claims.actor, ref: claims.ref, }, }, }, ]) return json({ published: true }) } async function activateArtifact(request: Request, env: Env) { const invalid = validMutation(request) if (invalid) return invalid const form = await request.formData() const key = parseKey({ channel: form.get("channel"), name: form.get("name"), distribution: form.get("distribution"), version: form.get("version"), }) if (key instanceof Response) return key const exists = await env.DB.prepare( "SELECT 1 FROM artifact WHERE channel = ? AND name = ? AND distribution = ? AND version = ?", ) .bind(key.channel, key.name, key.distribution, key.version) .first() if (!exists) return json({ error: "Artifact not found" }, 404) await env.DB.batch([ deactivateStatement(env.DB, key), env.DB .prepare( "UPDATE artifact SET active = 1, time_updated = ? WHERE channel = ? AND name = ? AND distribution = ? AND version = ?", ) .bind(Date.now(), key.channel, key.name, key.distribution, key.version), ]) return Response.redirect(new URL("/admin", request.url), 303) } function activate(db: D1Database, artifacts: ArtifactInput[]) { return db.batch( artifacts.flatMap((artifact) => { const time = Date.now() return [ deactivateStatement(db, artifact), db .prepare( `INSERT INTO artifact (channel, name, distribution, version, metadata, active, time_created, time_updated) VALUES (?, ?, ?, ?, ?, 1, ?, ?) ON CONFLICT (channel, name, distribution, version) DO UPDATE SET metadata = excluded.metadata, active = 1, time_updated = excluded.time_updated`, ) .bind( artifact.channel, artifact.name, artifact.distribution, artifact.version, JSON.stringify(artifact.metadata), time, time, ), ] }), ) } function deactivateStatement(db: D1Database, artifact: Pick) { return db .prepare("UPDATE artifact SET active = 0 WHERE channel = ? AND name = ? AND distribution = ? AND active = 1") .bind(artifact.channel, artifact.name, artifact.distribution) } function parseArtifact(input: Record): ArtifactInput | Response { const key = parseKey(input) if (key instanceof Response) return key const metadata = typeof input.metadata === "string" ? parseMetadata(input.metadata) : input.metadata if (metadata === undefined) return json({ error: "Metadata must be valid JSON" }, 400) return { ...key, metadata } } function parseKey(input: Record): Omit | Response { if ( !validIdentifier(input.channel) || !validIdentifier(input.name) || !validIdentifier(input.distribution) || !validVersion(input.version) ) return json({ error: "Invalid artifact" }, 400) return { channel: input.channel, name: input.name, distribution: input.distribution, version: input.version, } } function decodeArtifact(row: ArtifactRow): Artifact { return { ...row, metadata: decodeMetadata(row.metadata), active: row.active === 1 } } function decodeMetadata(input: string) { return parseMetadata(input) ?? null } function parseMetadata(input: string): unknown | undefined { try { return JSON.parse(input) } catch { return } } async function verifyGitHub(request: Request) { const authorization = request.headers.get("Authorization") if (!authorization?.startsWith("Bearer ")) return json({ error: "Unauthorized" }, 401) const result = await jwtVerify(authorization.slice("Bearer ".length), githubKeys, { issuer: "https://token.actions.githubusercontent.com", audience, }).catch(() => undefined) if (!result || !validGitHubClaims(result.payload)) return json({ error: "Unauthorized" }, 401) return result.payload } type GitHubClaims = JWTPayload & { repository: string repository_id: string repository_owner_id: string workflow_ref: string ref: string sha: string run_id: string run_attempt: string actor: string } export function validGitHubClaims(claims: JWTPayload): claims is GitHubClaims { if (claims.repository !== "anomalyco/opencode") return false if (claims.repository_id !== "975734319") return false if (claims.repository_owner_id !== "66570915") return false if (typeof claims.workflow_ref !== "string" || typeof claims.ref !== "string") return false if (claims.workflow_ref !== `anomalyco/opencode/.github/workflows/publish.yml@${claims.ref}`) return false if (!channelsForRef(claims.ref).length) return false return [claims.sha, claims.run_id, claims.run_attempt, claims.actor].every((value) => typeof value === "string") } export function channelsForRef(ref: string) { if (ref === "refs/heads/dev") return ["dev", "latest"] if (ref === "refs/heads/v2") return ["next"] if (ref === "refs/heads/beta") return ["beta"] if (ref === "refs/heads/ci") return ["ci"] if (ref === "refs/heads/fix/npm-native-binary-install") return ["fix/npm-native-binary-install"] const snapshot = ref.match(/^refs\/heads\/(snapshot-[a-zA-Z0-9._-]+)$/)?.[1] return snapshot ? [snapshot] : [] } function validMutation(request: Request) { const origin = request.headers.get("Origin") if (origin && origin !== new URL(request.url).origin) return json({ error: "Invalid origin" }, 403) } function validIdentifier(input: unknown): input is string { return typeof input === "string" && identifier.test(input) } function validVersion(input: unknown): input is string { return typeof input === "string" && version.test(input) } function isRecord(input: unknown): input is Record { return typeof input === "object" && input !== null && !Array.isArray(input) } function cached(value: unknown) { return json(value, 200, { "Cache-Control": "public, max-age=60" }) } function json(value: unknown, status = 200, headers?: HeadersInit) { return Response.json(value, { status, headers }) } function escape(value: string) { return value.replace(/[&<>"']/g, (character) => { if (character === "&") return "&" if (character === "<") return "<" if (character === ">") return ">" if (character === '"') return """ return "'" }) }