From 55cedfa35ce89756cc38416ba303b7bf2df0c95b Mon Sep 17 00:00:00 2001 From: Adam Daley Date: Thu, 28 May 2026 22:49:08 +0100 Subject: [PATCH 1/2] Support versioned FOSSBilling zip assets --- src/services/versions/v1/index.ts | 21 +++++++++-- test/services/versions/v1/index.test.ts | 48 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/services/versions/v1/index.ts b/src/services/versions/v1/index.ts index d5fbd38..e77a126 100644 --- a/src/services/versions/v1/index.ts +++ b/src/services/versions/v1/index.ts @@ -125,6 +125,23 @@ function buildSuccessResponse( }; } +interface ReleaseAsset { + name: string; + browser_download_url: string; + size: number; +} + +function getReleaseZipAsset( + assets: ReleaseAsset[], + tag: string +): ReleaseAsset | undefined { + return assets.find( + (asset) => + asset.name === "FOSSBilling.zip" || + asset.name === `FOSSBilling-${tag}.zip` + ); +} + registerCachedRoute("/", async (c) => { const result = await loadReleases(c); const releases = result.releases; @@ -387,9 +404,7 @@ export async function getReleases( return null; } - const zipAsset = release.assets.find( - (asset) => asset.name === "FOSSBilling.zip" - ); + const zipAsset = getReleaseZipAsset(release.assets, tag); if (!zipAsset) { return null; } diff --git a/test/services/versions/v1/index.test.ts b/test/services/versions/v1/index.test.ts index f90947d..38d0482 100644 --- a/test/services/versions/v1/index.test.ts +++ b/test/services/versions/v1/index.test.ts @@ -98,6 +98,54 @@ describe("Versions API v1", () => { } }); + it("should include releases with versioned zip asset names", async () => { + (vi.mocked(ghRequest) as MockGitHubRequest).mockImplementation( + async (route: string) => { + if (route === "GET /repos/{owner}/{repo}/releases") { + return { + data: [ + ...mockGitHubReleases, + { + id: 1005, + tag_name: "0.8.0", + name: "0.8.0", + published_at: "2026-05-28T21:12:54Z", + prerelease: false, + body: "## 0.8.0\n- New release", + assets: [ + { + name: "FOSSBilling-0.8.0.zip", + browser_download_url: + "https://github.com/FOSSBilling/FOSSBilling/releases/download/0.8.0/FOSSBilling-0.8.0.zip", + size: 2048000 + } + ] + } + ] + }; + } + if (route === "GET /repos/{owner}/{repo}/contents/{path}{?ref}") { + const content = btoa(JSON.stringify(mockComposerJson)); + return { data: { content } }; + } + throw new Error("Unexpected route"); + } + ); + + const ctx = createExecutionContext(); + const response = await app.request("/versions/v1", {}, env, ctx); + await waitOnExecutionContext(ctx); + + expect(response.status).toBe(200); + const data: VersionsResponse = await response.json(); + expect(data.result["0.8.0"]).toMatchObject({ + version: "0.8.0", + download_url: + "https://github.com/FOSSBilling/FOSSBilling/releases/download/0.8.0/FOSSBilling-0.8.0.zip", + size_bytes: 2048000 + }); + }); + it("should cache releases data", async () => { const ctx = createExecutionContext(); await app.request("/versions/v1", {}, env, ctx); From cfe8449e5c08ad564fcdabffa12adf9914f6d241 Mon Sep 17 00:00:00 2001 From: Adam Daley Date: Thu, 28 May 2026 22:55:50 +0100 Subject: [PATCH 2/2] Avoid stale release response cache --- src/services/versions/v1/index.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/services/versions/v1/index.ts b/src/services/versions/v1/index.ts index e77a126..1f089a0 100644 --- a/src/services/versions/v1/index.ts +++ b/src/services/versions/v1/index.ts @@ -1,6 +1,5 @@ import { bearerAuth } from "hono/bearer-auth"; import { Hono, type Context, type Handler } from "hono"; -import { cache } from "hono/cache"; import { cors } from "hono/cors"; import { etag } from "hono/etag"; import { prettyJSON } from "hono/pretty-json"; @@ -15,7 +14,6 @@ import { import { Releases, ReleaseDetails } from "./interfaces"; import { getPlatform } from "../../../lib/middleware"; import { ICache } from "../../../lib/interfaces"; -import { publicCacheKey } from "../../../lib/cache"; import { logError, logWarn, logInfo } from "../../../lib/logger"; import { GitHubError, @@ -28,7 +26,6 @@ import { } from "../../../lib/github-errors"; const RELEASE_CACHE_KEY = "gh-fossbilling-releases"; -const RELEASES_CACHE_NAME = "versions-api-v1"; const RELEASES_CACHE_CONTROL = "max-age: 86400"; const RELEASE_CACHE_TTL = 86400; const RELEASES_URL = @@ -74,11 +71,10 @@ function registerCachedRoute

( ) { return versionsV1.get( path, - cache({ - cacheName: RELEASES_CACHE_NAME, - cacheControl: RELEASES_CACHE_CONTROL, - keyGenerator: publicCacheKey - }), + async (c, next) => { + c.header("Cache-Control", RELEASES_CACHE_CONTROL); + return next(); + }, etag(), prettyJSON(), handler