fix(release): mark promoted CNB release as latest
This commit is contained in:
parent
beaf52582f
commit
cd10acb310
|
|
@ -16,7 +16,7 @@ async function main() {
|
|||
if (!tag) throw new Error("GitHub release JSON is missing tagName.");
|
||||
|
||||
const client = new CnbClient(args);
|
||||
const release = await client.ensureRelease(tag, githubRelease);
|
||||
const release = await client.ensureRelease(tag, githubRelease, { makeLatest: args.makeLatest });
|
||||
|
||||
if (args.metadataOnly) {
|
||||
console.log(`Updated CNB release metadata for ${tag}.`);
|
||||
|
|
@ -56,6 +56,7 @@ function parseArgs(argv) {
|
|||
assetsDir: "",
|
||||
metadataOnly: false,
|
||||
pruneAssets: false,
|
||||
makeLatest: false,
|
||||
};
|
||||
for (let index = 0; index < argv.length; index++) {
|
||||
const arg = argv[index];
|
||||
|
|
@ -64,12 +65,13 @@ function parseArgs(argv) {
|
|||
else if (arg === "--metadata-only") args.metadataOnly = true;
|
||||
else if (arg === "--overwrite-existing") args.overwriteExisting = true;
|
||||
else if (arg === "--prune-assets") args.pruneAssets = true;
|
||||
else if (arg === "--make-latest") args.makeLatest = true;
|
||||
else throw new Error(`Unknown argument: ${arg}`);
|
||||
}
|
||||
if (!args.token) throw new Error("CNB_TOKEN is required.");
|
||||
if (!args.githubReleasePath || (!args.metadataOnly && !args.assetsDir)) {
|
||||
throw new Error(
|
||||
"Usage: sync-cnb-release.mjs --github-release <release.json> (--assets-dir <dir> | --metadata-only) [--prune-assets]",
|
||||
"Usage: sync-cnb-release.mjs --github-release <release.json> (--assets-dir <dir> | --metadata-only) [--prune-assets] [--make-latest]",
|
||||
);
|
||||
}
|
||||
if (!Number.isInteger(args.concurrency) || args.concurrency < 1) {
|
||||
|
|
@ -112,13 +114,14 @@ export class CnbClient {
|
|||
this.token = token;
|
||||
}
|
||||
|
||||
async ensureRelease(tag, githubRelease) {
|
||||
async ensureRelease(tag, githubRelease, { makeLatest = false } = {}) {
|
||||
const payload = {
|
||||
tag_name: tag,
|
||||
name: githubRelease.name || tag,
|
||||
body: githubRelease.body || "",
|
||||
prerelease: Boolean(githubRelease.isPrerelease || githubRelease.prerelease),
|
||||
target_commitish: githubRelease.targetCommitish || githubRelease.target_commitish || "",
|
||||
...(makeLatest ? { make_latest: "true" } : {}),
|
||||
};
|
||||
const existing = await this.request("GET", `/${this.repository}/-/releases/tags/${encodeURIComponent(tag)}`, null, true);
|
||||
if (!existing) return this.request("POST", `/${this.repository}/-/releases`, payload);
|
||||
|
|
@ -128,6 +131,7 @@ export class CnbClient {
|
|||
name: payload.name,
|
||||
body: payload.body,
|
||||
prerelease: payload.prerelease,
|
||||
...(makeLatest ? { make_latest: "true" } : {}),
|
||||
});
|
||||
return existing;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,23 +70,85 @@ test("ensureRelease accepts an empty successful PATCH response", async (t) => {
|
|||
]);
|
||||
});
|
||||
|
||||
test("metadata-only sync updates release without reading an assets directory", async (t) => {
|
||||
test("ensureRelease explicitly marks a promoted release as latest", async (t) => {
|
||||
const release = { id: "release-latest", tag_name: "v1.2.3", assets: [] };
|
||||
const requests = [];
|
||||
const server = createServer((request, response) => {
|
||||
const bodyChunks = [];
|
||||
request.on("data", (chunk) => bodyChunks.push(chunk));
|
||||
request.on("end", () => {
|
||||
requests.push({
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
body: bodyChunks.length ? JSON.parse(Buffer.concat(bodyChunks).toString("utf8")) : null,
|
||||
});
|
||||
if (request.method === "GET") {
|
||||
response.setHeader("Content-Type", "application/json");
|
||||
response.end(JSON.stringify(release));
|
||||
return;
|
||||
}
|
||||
response.statusCode = 200;
|
||||
response.end();
|
||||
});
|
||||
});
|
||||
|
||||
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||
t.after(() => new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve()))));
|
||||
|
||||
const address = server.address();
|
||||
assert.ok(address && typeof address !== "string");
|
||||
const client = new CnbClient({
|
||||
apiBase: `http://127.0.0.1:${address.port}`,
|
||||
repository: "dbxio.com/dbx",
|
||||
token: "test-token",
|
||||
});
|
||||
|
||||
await client.ensureRelease(
|
||||
"v1.2.3",
|
||||
{ name: "DBX v1.2.3", body: "Stable", isPrerelease: false },
|
||||
{ makeLatest: true },
|
||||
);
|
||||
|
||||
assert.deepEqual(requests, [
|
||||
{ method: "GET", url: "/dbxio.com/dbx/-/releases/tags/v1.2.3", body: null },
|
||||
{
|
||||
method: "PATCH",
|
||||
url: "/dbxio.com/dbx/-/releases/release-latest",
|
||||
body: {
|
||||
name: "DBX v1.2.3",
|
||||
body: "Stable",
|
||||
prerelease: false,
|
||||
make_latest: "true",
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test("metadata-only sync can mark the release as latest without reading an assets directory", async (t) => {
|
||||
const release = { id: "release-2", tag_name: "v1.2.3", assets: [{ name: "large.dmg" }] };
|
||||
const requests = [];
|
||||
const server = createServer((request, response) => {
|
||||
requests.push({ method: request.method, url: request.url });
|
||||
if (request.method === "GET") {
|
||||
response.setHeader("Content-Type", "application/json");
|
||||
response.end(JSON.stringify(release));
|
||||
return;
|
||||
}
|
||||
if (request.method === "PATCH") {
|
||||
response.statusCode = 200;
|
||||
const bodyChunks = [];
|
||||
request.on("data", (chunk) => bodyChunks.push(chunk));
|
||||
request.on("end", () => {
|
||||
requests.push({
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
body: bodyChunks.length ? JSON.parse(Buffer.concat(bodyChunks).toString("utf8")) : null,
|
||||
});
|
||||
if (request.method === "GET") {
|
||||
response.setHeader("Content-Type", "application/json");
|
||||
response.end(JSON.stringify(release));
|
||||
return;
|
||||
}
|
||||
if (request.method === "PATCH") {
|
||||
response.statusCode = 200;
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
response.statusCode = 500;
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
response.statusCode = 500;
|
||||
response.end();
|
||||
});
|
||||
});
|
||||
|
||||
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||
|
|
@ -103,14 +165,18 @@ test("metadata-only sync updates release without reading an assets directory", a
|
|||
const address = server.address();
|
||||
assert.ok(address && typeof address !== "string");
|
||||
const result = await new Promise((resolve) => {
|
||||
const child = spawn(process.execPath, [scriptPath, "--github-release", releasePath, "--metadata-only"], {
|
||||
env: {
|
||||
...process.env,
|
||||
CNB_API_BASE: `http://127.0.0.1:${address.port}`,
|
||||
CNB_REPOSITORY: "dbxio.com/dbx",
|
||||
CNB_TOKEN: "test-token",
|
||||
const child = spawn(
|
||||
process.execPath,
|
||||
[scriptPath, "--github-release", releasePath, "--metadata-only", "--make-latest"],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
CNB_API_BASE: `http://127.0.0.1:${address.port}`,
|
||||
CNB_REPOSITORY: "dbxio.com/dbx",
|
||||
CNB_TOKEN: "test-token",
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
child.stdout.on("data", (chunk) => (stdout += chunk));
|
||||
|
|
@ -121,8 +187,17 @@ test("metadata-only sync updates release without reading an assets directory", a
|
|||
assert.equal(result.code, 0, result.stderr);
|
||||
assert.match(result.stdout, /Updated CNB release metadata for v1\.2\.3/);
|
||||
assert.deepEqual(requests, [
|
||||
{ method: "GET", url: "/dbxio.com/dbx/-/releases/tags/v1.2.3" },
|
||||
{ method: "PATCH", url: "/dbxio.com/dbx/-/releases/release-2" },
|
||||
{ method: "GET", url: "/dbxio.com/dbx/-/releases/tags/v1.2.3", body: null },
|
||||
{
|
||||
method: "PATCH",
|
||||
url: "/dbxio.com/dbx/-/releases/release-2",
|
||||
body: {
|
||||
name: "DBX v1.2.3",
|
||||
body: "Stable",
|
||||
prerelease: false,
|
||||
make_latest: "true",
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -400,7 +400,8 @@ jobs:
|
|||
# Sync metadata only so promoting a release never re-uploads large CNB assets.
|
||||
node .github/scripts/sync-cnb-release.mjs \
|
||||
--github-release "$RUNNER_TEMP/github-release/release.json" \
|
||||
--metadata-only
|
||||
--metadata-only \
|
||||
--make-latest
|
||||
|
||||
notify-qq:
|
||||
name: QQ Notify
|
||||
|
|
|
|||
Loading…
Reference in New Issue