build marketplace icon URLs from HEAD, not from a branch name

Every available plugin drew a broken image on any server reading the remote
catalogue. The URLs said /raw/branch/main/, and four plugin repositories were
created on `master` — so those 404'd, and the others only worked by accident of
which branch somebody happened to use.

The comment above the builder already said "a repo whose default branch is
`master` gets a 404", marked [open]. It then happened. A warning in a comment
is not a guard.

Gitea resolves /raw/HEAD/ to whatever the default branch is, so the question
stops being asked. Verified against both spellings, and all 12 icons in the
live catalogue now answer 200.

It did not show on alpha because every plugin there is INSTALLED, and an
installed plugin's tile is served locally from /plugins/<name>/ rather than
from the catalogue.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 10:55:10 +00:00
co-authored by Claude Opus 5
parent 427bd1afff
commit 5b486ed019
2 changed files with 14 additions and 9 deletions
+12 -7
View File
@@ -123,9 +123,7 @@ async function syncOne(dir: string): Promise<Sync | null> {
});
console.log(
`[marketplace-sync] ${appName} ← ${repoUrl}${readme ? '' : ' (no README)'}${
has.web ? '' : ' (no web/)'
}`,
`[marketplace-sync] ${appName} ← ${repoUrl}${readme ? '' : ' (no README)'}${has.web ? '' : ' (no web/)'}`,
);
return { appName, developer, repoUrl };
}
@@ -133,12 +131,19 @@ async function syncOne(dir: string): Promise<Sync | null> {
/**
* A raw-file URL for a Gitea repository.
*
* `[open]` Gitea-shaped and branch-`main`-shaped. A GitHub-hosted plugin needs the other form, and a
* repo whose default branch is `master` gets a 404. Fine while every plugin is on our own Gitea; the
* moment one is not, this needs the forge to be part of the registry rather than inferred.
* `HEAD`, not a branch name. This said `branch/main` and the comment here warned that "a repo whose
* default branch is `master` gets a 404" — which then happened: four plugin repositories were created
* on `master` and every one of them served a broken image in the marketplace on any server that reads
* the remote catalogue. A warning in a comment is not a guard.
*
* Gitea resolves `HEAD` to whatever the default branch is, so the question stops being asked. Verified
* against both spellings.
*
* `[open]` Still Gitea-shaped. A GitHub-hosted plugin needs the other form, and that wants the forge to
* be part of the registry rather than inferred from the URL.
*/
function rawUrl(repoUrl: string, path: string): string {
return `${repoUrl.replace(/\.git$/, '')}/raw/branch/main/${path}`;
return `${repoUrl.replace(/\.git$/, '')}/raw/HEAD/${path}`;
}
const dirs = existsSync(PLUGINS_DIR)
+2 -2
View File
@@ -285,7 +285,7 @@ const BUNDLED: CatalogueEntry[] = [
color: '#22c55e',
// Artwork rather than a glyph, so the tile draws no coloured square behind it.
tile: 'bare',
iconUrl: 'https://gitea.officer.dev/plugins/music/raw/branch/main/assets/icon.png',
iconUrl: 'https://gitea.officer.dev/plugins/music/raw/HEAD/assets/icon.png',
source: 'https://gitea.officer.dev/plugins/music.git',
permissions: [
{
@@ -320,7 +320,7 @@ const BUNDLED: CatalogueEntry[] = [
// Ships artwork as of 2026-08-15, so the tile is `bare` like music's. `icon` stays as the fallback
// for the case the assets fail to publish — the glyph is strictly better than the generic box.
tile: 'bare',
iconUrl: 'https://gitea.officer.dev/plugins/offscale/raw/branch/main/assets/icon.png',
iconUrl: 'https://gitea.officer.dev/plugins/offscale/raw/HEAD/assets/icon.png',
icon: 'Network',
source: 'https://gitea.officer.dev/plugins/offscale.git',
permissions: [