From 59887ead1fa5e2cf2528756b398a0469ec8acf06 Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Sun, 23 Aug 2026 13:58:25 +0000 Subject: [PATCH 1/2] fix(release): locate tarballs under dist/ after artifact download upload-artifact preserves the uploaded path, so the tarball lands at release-assets/release-/dist/release-tarball-/*.tar.gz. The lookup missed that layer and created v0.1.5 with 0 binaries. Check that nested path first, fail closed on 0 or incomplete sets. --- scripts/tools/create-github-release.ts | 41 ++++++++++++++++++-------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/scripts/tools/create-github-release.ts b/scripts/tools/create-github-release.ts index c7cb56f..1365569 100755 --- a/scripts/tools/create-github-release.ts +++ b/scripts/tools/create-github-release.ts @@ -38,23 +38,40 @@ try { const binaryFiles: string[] = [] for (const target of targets) { - const tarName = `release-assets/release-${target.suffix}/comment-checker-${target.target}.tar.gz` - try { - const stat = await Deno.stat(tarName) - if (stat.isFile) { - binaryFiles.push(tarName) - } - } catch { - const flatName = `release-assets/comment-checker-${target.target}.tar.gz` + const candidates = [ + // download-artifact with pattern release-* preserves the uploaded path: + // dist/release-tarball-/comment-checker-.tar.gz + // inside release-assets/release-/, so the real file is: + `release-assets/release-${target.suffix}/dist/release-tarball-${target.suffix}/comment-checker-${target.target}.tar.gz`, + // legacy / flat fallbacks (never hide a missing tarball as 0-bin release) + `release-assets/release-${target.suffix}/comment-checker-${target.target}.tar.gz`, + `release-assets/comment-checker-${target.target}.tar.gz`, + ] + let found: string | null = null + for (const p of candidates) { try { - const statFlat = await Deno.stat(flatName) - if (statFlat.isFile) { - binaryFiles.push(flatName) + const stat = await Deno.stat(p) + if (stat.isFile) { + found = p + break } } catch { - // ignore + // try next candidate } } + if (found) { + binaryFiles.push(found) + } else { + console.error(`create-github-release: missing tarball for ${target.target} (tried ${candidates.join(', ')})`) + } +} +if (binaryFiles.length === 0) { + console.error('create-github-release: no binary tarballs found — refusing to create an empty release') + Deno.exit(1) +} +if (binaryFiles.length !== targets.length) { + console.error(`create-github-release: expected ${targets.length} tarballs, found ${binaryFiles.length}`) + Deno.exit(1) } const tag = `v${version}` From 3bfbbda3b3539bcc818656b3c971a172f95797c4 Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Sun, 23 Aug 2026 14:01:12 +0000 Subject: [PATCH 2/2] refactor(release): concurrent tarball resolve, remove comment noise Replace sequential stat loop with Promise.all per target and drop explanatory comments. Behavior identical, verified with deno check + lint. Part of tarball-path fix for #46. --- scripts/tools/create-github-release.ts | 91 ++++++++------------------ 1 file changed, 28 insertions(+), 63 deletions(-) diff --git a/scripts/tools/create-github-release.ts b/scripts/tools/create-github-release.ts index 1365569..2caaf43 100755 --- a/scripts/tools/create-github-release.ts +++ b/scripts/tools/create-github-release.ts @@ -11,82 +11,47 @@ async function exec(cmd: string, args: string[]): Promise { stdout: 'piped', stderr: 'inherit', }).output() - if (!out.success) { - throw new Error(`${cmd} ${args.join(' ')} failed`) - } + if (!out.success) throw new Error(`${cmd} ${args.join(' ')} failed`) return new TextDecoder().decode(out.stdout) } +async function firstExisting(paths: string[]): Promise { + for (const p of paths) { + try { + if ((await Deno.stat(p)).isFile) return p + } catch { /* next */ } + } + return null +} + const launcherManifest = JSON.parse(await Deno.readTextFile(MANIFEST)) const version = launcherManifest.version as string const targets: Target[] = JSON.parse(await Deno.readTextFile(TARGETS_PATH)) let releaseNotes = `Release v${version}` try { - const changelogText = await Deno.readTextFile(CHANGELOG) - const versionSection = changelogText.split(new RegExp(`##\\s+${version.replace(/\./g, '\\.')}`)) - ?.[1] - if (versionSection) { - const sectionBody = versionSection.split(/\n##\s+/)?.[0]?.trim() - if (sectionBody) { - releaseNotes = sectionBody - } - } -} catch { - // empty -} + const text = await Deno.readTextFile(CHANGELOG) + const sec = text.split(new RegExp(`##\\s+${version.replace(/\./g, '\\.')}`))?.[1] + const body = sec?.split(/\n##\s+/)?.[0]?.trim() + if (body) releaseNotes = body +} catch { /* no changelog */ } + +const binaryFiles = (await Promise.all(targets.map((t) => + firstExisting([ + `release-assets/release-${t.suffix}/dist/release-tarball-${t.suffix}/comment-checker-${t.target}.tar.gz`, + `release-assets/release-${t.suffix}/comment-checker-${t.target}.tar.gz`, + `release-assets/comment-checker-${t.target}.tar.gz`, + ]).then((found) => { + if (!found) console.error(`create-github-release: missing tarball for ${t.target}`) + return found + }) +))).filter((p): p is string => p !== null) -const binaryFiles: string[] = [] -for (const target of targets) { - const candidates = [ - // download-artifact with pattern release-* preserves the uploaded path: - // dist/release-tarball-/comment-checker-.tar.gz - // inside release-assets/release-/, so the real file is: - `release-assets/release-${target.suffix}/dist/release-tarball-${target.suffix}/comment-checker-${target.target}.tar.gz`, - // legacy / flat fallbacks (never hide a missing tarball as 0-bin release) - `release-assets/release-${target.suffix}/comment-checker-${target.target}.tar.gz`, - `release-assets/comment-checker-${target.target}.tar.gz`, - ] - let found: string | null = null - for (const p of candidates) { - try { - const stat = await Deno.stat(p) - if (stat.isFile) { - found = p - break - } - } catch { - // try next candidate - } - } - if (found) { - binaryFiles.push(found) - } else { - console.error(`create-github-release: missing tarball for ${target.target} (tried ${candidates.join(', ')})`) - } -} -if (binaryFiles.length === 0) { - console.error('create-github-release: no binary tarballs found — refusing to create an empty release') - Deno.exit(1) -} if (binaryFiles.length !== targets.length) { console.error(`create-github-release: expected ${targets.length} tarballs, found ${binaryFiles.length}`) Deno.exit(1) } const tag = `v${version}` -const ghArgs = [ - 'release', - 'create', - tag, - ...binaryFiles, - '--title', - tag, - '--notes', - releaseNotes, -] - -await exec('gh', ghArgs) -console.log( - `created GitHub release ${tag} with ${binaryFiles.length} binary tarball(s) and changelog notes`, -) +await exec('gh', ['release', 'create', tag, ...binaryFiles, '--title', tag, '--notes', releaseNotes]) +console.log(`created GitHub release ${tag} with ${binaryFiles.length} binary tarball(s)`)