fix(release): reject incompatible bridge recovery
Fail closed when an existing transport-tag release has a title that does not match the product version, preventing the new updater from re-entering the bridge loop.
This commit is contained in:
parent
c7fa422d9b
commit
cad270dd2c
@ -43,6 +43,14 @@ export function createReleasePlan(options) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveExistingReleaseId(plan, release) {
|
||||||
|
const existingTitle = typeof release?.name === 'string' ? release.name : '';
|
||||||
|
if (existingTitle !== plan.releaseTitle) {
|
||||||
|
throw new Error(`Refusing recovery for ${plan.tag}: existing release title "${existingTitle}" does not match "${plan.releaseTitle}"`);
|
||||||
|
}
|
||||||
|
return release.id;
|
||||||
|
}
|
||||||
|
|
||||||
export function renderLatestYml(plan, sha, size, releaseDate = new Date().toISOString()) {
|
export function renderLatestYml(plan, sha, size, releaseDate = new Date().toISOString()) {
|
||||||
return `version: ${plan.version}\nfiles:\n - url: ${plan.setupName}\n sha512: ${sha}\n size: ${size}\npath: ${plan.setupName}\nsha512: ${sha}\nreleaseDate: '${releaseDate}'\n`;
|
return `version: ${plan.version}\nfiles:\n - url: ${plan.setupName}\n sha512: ${sha}\n size: ${size}\npath: ${plan.setupName}\nsha512: ${sha}\nreleaseDate: '${releaseDate}'\n`;
|
||||||
}
|
}
|
||||||
@ -240,7 +248,7 @@ async function main(args = process.argv.slice(2)) {
|
|||||||
if (createStatus === 409 || createStatus === 422) {
|
if (createStatus === 409 || createStatus === 422) {
|
||||||
// Release already exists, find it
|
// Release already exists, find it
|
||||||
const { data: releases } = await giteaApi('GET', `/api/v1/repos/Administrator/${PRODUCT_NAME}/releases/tags/${tag}`, token);
|
const { data: releases } = await giteaApi('GET', `/api/v1/repos/Administrator/${PRODUCT_NAME}/releases/tags/${tag}`, token);
|
||||||
releaseId = releases.id;
|
releaseId = resolveExistingReleaseId(plan, releases);
|
||||||
console.log(`Release already exists (id: ${releaseId})`);
|
console.log(`Release already exists (id: ${releaseId})`);
|
||||||
} else {
|
} else {
|
||||||
releaseId = createData.id;
|
releaseId = createData.id;
|
||||||
|
|||||||
@ -59,3 +59,40 @@ test('release plan keeps product artifacts separate from the transport tag', ()
|
|||||||
latestYml: "version: 2.0.1\nfiles:\n - url: Multi-Hoster-Upload Setup 2.0.1.exe\n sha512: abc123\n size: 456\npath: Multi-Hoster-Upload Setup 2.0.1.exe\nsha512: abc123\nreleaseDate: '2026-08-07T12:00:00.000Z'\n"
|
latestYml: "version: 2.0.1\nfiles:\n - url: Multi-Hoster-Upload Setup 2.0.1.exe\n sha512: abc123\n size: 456\npath: Multi-Hoster-Upload Setup 2.0.1.exe\nsha512: abc123\nreleaseDate: '2026-08-07T12:00:00.000Z'\n"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('compatible existing release preserves the recovery id', async () => {
|
||||||
|
const moduleUrl = pathToFileURL(path.resolve(__dirname, '../scripts/release_gitea.mjs')).href;
|
||||||
|
const { createReleasePlan, parseReleaseArgs, resolveExistingReleaseId } = await import(moduleUrl);
|
||||||
|
const plan = createReleasePlan(parseReleaseArgs(['2.0.1', '--transport-tag', 'v3.3.109', 'Bridge notes']));
|
||||||
|
const release = {
|
||||||
|
id: 81,
|
||||||
|
tag_name: 'v3.3.109',
|
||||||
|
name: 'Multi-Hoster-Upload v2.0.1',
|
||||||
|
body: 'Bridge notes',
|
||||||
|
draft: false,
|
||||||
|
prerelease: false,
|
||||||
|
assets: []
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.equal(resolveExistingReleaseId(plan, release), 81);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('incompatible existing release title fails closed', async () => {
|
||||||
|
const moduleUrl = pathToFileURL(path.resolve(__dirname, '../scripts/release_gitea.mjs')).href;
|
||||||
|
const { createReleasePlan, parseReleaseArgs, resolveExistingReleaseId } = await import(moduleUrl);
|
||||||
|
const plan = createReleasePlan(parseReleaseArgs(['2.0.1', '--transport-tag', 'v3.3.109', 'Bridge notes']));
|
||||||
|
const release = {
|
||||||
|
id: 81,
|
||||||
|
tag_name: 'v3.3.109',
|
||||||
|
name: 'Multi-Hoster-Upload v3.3.109',
|
||||||
|
body: 'Old transport release',
|
||||||
|
draft: false,
|
||||||
|
prerelease: false,
|
||||||
|
assets: []
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => resolveExistingReleaseId(plan, release),
|
||||||
|
/Refusing recovery for v3\.3\.109: existing release title "Multi-Hoster-Upload v3\.3\.109" does not match "Multi-Hoster-Upload v2\.0\.1"/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user