From 9bf62b238e84652be22b56958e889ab7ee2dac12 Mon Sep 17 00:00:00 2001 From: whyujjwal <138800022+whyujjwal@users.noreply.github.com> Date: Fri, 22 May 2026 18:36:25 +0000 Subject: [PATCH] fix: download Deployer manifest without logging its body Save manifest.json to a runner temp file instead of piping curl output into action logs. When deployer-version is set explicitly, build the release URL directly and skip the manifest request entirely. On manifest download failures, surface the saved response body to aid debugging. Fixes #88 Co-authored-by: Cursor --- dist/index.js | 38 ++++++++++++++++++++-------- package.json | 1 + src/index.ts | 56 ++++++++++++++++++++++++++++++++--------- tests/manifest.test.mjs | 32 +++++++++++++++++++++++ 4 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 tests/manifest.test.mjs diff --git a/dist/index.js b/dist/index.js index fe6c47f..6d61cb2 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6,6 +6,7 @@ import * as fs$1 from "fs"; import { constants, promises } from "fs"; import * as path$1 from "path"; import * as events from "events"; +import { fileURLToPath } from "node:url"; import "child_process"; import "timers"; import * as process$1 from "node:process"; @@ -36632,14 +36633,34 @@ var { VERSION, YAML, argv, dotenv, echo, expBackoff, fetch, fs, glob, globby, mi //#endregion //#region src/index.ts $.verbose = true; -(async function main() { +function deployerReleaseUrl(version) { + return `https://deployer.org/releases/v${version}/deployer.phar`; +} +function manifestPath() { + return `${process.env["RUNNER_TEMP"] ?? "."}/deployer-manifest.json`; +} +async function loadDeployerManifest() { + const path = manifestPath(); + try { + await $`curl -fsSL -o ${path} https://deployer.org/manifest.json`; + } catch (err) { + if (fs.existsSync(path)) error(fs.readFileSync(path, "utf8")); + throw err; + } + return JSON.parse(fs.readFileSync(path, "utf8")); +} +async function resolveDeployerDownloadUrl(version, explicitVersion) { + if (explicitVersion) return deployerReleaseUrl(version); + return (await loadDeployerManifest()).find((asset) => asset.version === version)?.url; +} +async function main() { try { await ssh(); await dep(); } catch (err) { setFailed(err instanceof Error ? err.message : String(err)); } -})(); +} async function ssh() { if (getBooleanInput("skip-ssh-setup")) return; const sshHomeDir = `${process.env["HOME"]}/.ssh`; @@ -36685,7 +36706,8 @@ async function dep() { } } if (bin === "") { - let version = getInput("deployer-version"); + const explicitVersion = getInput("deployer-version"); + let version = explicitVersion; if (version === "" && fs.existsSync("composer.lock")) { const lock = JSON.parse(fs.readFileSync("composer.lock", "utf8")); if (lock.packages) version = lock.packages.find((p) => p.name === "deployer/deployer")?.version; @@ -36693,12 +36715,7 @@ async function dep() { } if (version === "" || version === void 0) throw new Error("Deployer binary not found. Please specify deployer-binary or deployer-version."); version = version.replace(/^v/, ""); - const manifest = JSON.parse((await $`curl -L https://deployer.org/manifest.json`).stdout); - let url; - for (const asset of manifest) if (asset.version === version) { - url = asset.url; - break; - } + const url = await resolveDeployerDownloadUrl(version, explicitVersion !== ""); if (url === void 0) setFailed(`The version "${version}" does not exist in the "https://deployer.org/manifest.json" file.`); else { console.log(`Downloading "${url}".`); @@ -36731,5 +36748,6 @@ async function dep() { setFailed(`Failed: dep ${cmd}`); } } +if (process.argv[1] === fileURLToPath(import.meta.url)) main(); //#endregion -export {}; +export { deployerReleaseUrl, loadDeployerManifest, main, manifestPath, resolveDeployerDownloadUrl }; diff --git a/package.json b/package.json index c773d4d..90b87db 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "scripts": { "build": "vite build", "typecheck": "tsc --noEmit", + "test": "npm run build && node --test tests/*.test.mjs", "format": "prettier --write .", "format:check": "prettier --check ." }, diff --git a/src/index.ts b/src/index.ts index 3864887..2cffcff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import * as core from '@actions/core' import { $, fs, cd } from 'zx' +import { fileURLToPath } from 'node:url' $.verbose = true @@ -13,14 +14,46 @@ interface DeployerManifestEntry { url: string } -void (async function main(): Promise { +export function deployerReleaseUrl(version: string): string { + return `https://deployer.org/releases/v${version}/deployer.phar` +} + +export function manifestPath(): string { + return `${process.env['RUNNER_TEMP'] ?? '.'}/deployer-manifest.json` +} + +export async function loadDeployerManifest(): Promise { + const path = manifestPath() + try { + await $`curl -fsSL -o ${path} https://deployer.org/manifest.json` + } catch (err) { + if (fs.existsSync(path)) { + core.error(fs.readFileSync(path, 'utf8')) + } + throw err + } + return JSON.parse(fs.readFileSync(path, 'utf8')) as DeployerManifestEntry[] +} + +export async function resolveDeployerDownloadUrl( + version: string, + explicitVersion: boolean, +): Promise { + if (explicitVersion) { + return deployerReleaseUrl(version) + } + const manifest = await loadDeployerManifest() + return manifest.find((asset) => asset.version === version)?.url +} + +export async function main(): Promise { try { await ssh() await dep() } catch (err) { core.setFailed(err instanceof Error ? err.message : String(err)) } -})() +} async function ssh(): Promise { if (core.getBooleanInput('skip-ssh-setup')) { @@ -85,7 +118,8 @@ async function dep(): Promise { } if (bin === '') { - let version: string | undefined = core.getInput('deployer-version') + const explicitVersion = core.getInput('deployer-version') + let version: string | undefined = explicitVersion if (version === '' && fs.existsSync('composer.lock')) { const lock: ComposerLock = JSON.parse( fs.readFileSync('composer.lock', 'utf8'), @@ -107,16 +141,10 @@ async function dep(): Promise { ) } version = version.replace(/^v/, '') - const manifest: DeployerManifestEntry[] = JSON.parse( - (await $`curl -L https://deployer.org/manifest.json`).stdout, + const url = await resolveDeployerDownloadUrl( + version, + explicitVersion !== '', ) - let url: string | undefined - for (const asset of manifest) { - if (asset.version === version) { - url = asset.url - break - } - } if (url === undefined) { core.setFailed( `The version "${version}" does not exist in the "https://deployer.org/manifest.json" file.`, @@ -167,3 +195,7 @@ async function dep(): Promise { core.setFailed(`Failed: dep ${cmd}`) } } + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + void main() +} diff --git a/tests/manifest.test.mjs b/tests/manifest.test.mjs new file mode 100644 index 0000000..b122621 --- /dev/null +++ b/tests/manifest.test.mjs @@ -0,0 +1,32 @@ +import test from 'node:test' +import assert from 'node:assert/strict' + +import { + deployerReleaseUrl, + manifestPath, +} from '../dist/index.js' + +test('deployerReleaseUrl builds the canonical release download URL', () => { + assert.equal( + deployerReleaseUrl('7.5.12'), + 'https://deployer.org/releases/v7.5.12/deployer.phar', + ) + assert.equal( + deployerReleaseUrl('8.0.0-beta'), + 'https://deployer.org/releases/v8.0.0-beta/deployer.phar', + ) +}) + +test('manifestPath uses RUNNER_TEMP when available', () => { + const previous = process.env.RUNNER_TEMP + process.env.RUNNER_TEMP = '/tmp/github-runner' + try { + assert.equal(manifestPath(), '/tmp/github-runner/deployer-manifest.json') + } finally { + if (previous === undefined) { + delete process.env.RUNNER_TEMP + } else { + process.env.RUNNER_TEMP = previous + } + } +})