diff --git a/src/tasks/createGithubRelease/getNextGitTag.ts b/src/tasks/createGithubRelease/getNextGitTag.ts index 5d3dc088..c8b2b789 100644 --- a/src/tasks/createGithubRelease/getNextGitTag.ts +++ b/src/tasks/createGithubRelease/getNextGitTag.ts @@ -16,8 +16,10 @@ type GitTagDetailsMap = { * * - If the package is a single-variant package, the tag will be in the format: * `v0.1.2` + * + * - If isMultiVariant is true, always use variant@v format, even for a single variant */ -export function getNextGitTag(releaseDetailsMap: GitTagDetailsMap): string { +export function getNextGitTag(releaseDetailsMap: GitTagDetailsMap, isMultiVariant: boolean): string { const variantVersions = Object.entries( releaseDetailsMap ).map(([, { variant, nextVersion }]) => ({ variant, nextVersion })); @@ -25,16 +27,24 @@ export function getNextGitTag(releaseDetailsMap: GitTagDetailsMap): string { if (variantVersions.length === 0) throw Error("Could not generate git tag. Missing variant or nextVersion"); - // Not a multi-variant package - if (variantVersions.length === 1) return `v${variantVersions[0].nextVersion}`; - // If any variant is null, throw an error if (variantVersions.some(({ variant }) => !variant)) throw Error("Could not generate git tag. Missing variant"); - // Multi-variant package + // If isMultiVariant, always use variant@v format, even for a single variant + if (isMultiVariant) { + return variantVersions + .sort((a, b) => (a.variant || "").localeCompare(b.variant || "")) + .map(({ variant, nextVersion }) => `${variant}@v${nextVersion}`) + .join("_"); + } + + // Not a multi-variant package + if (variantVersions.length === 1) return `v${variantVersions[0].nextVersion}`; + + // Multi-variant package (fallback, should not hit if isMultiVariant is set correctly) return variantVersions - .sort((a, b) => (a.variant || "").localeCompare(b.variant || "")) // Sort alphabetically by variant - .map(({ variant, nextVersion }) => `${variant}@${nextVersion}`) // Map to string - .join("_"); // Join into a single string + .sort((a, b) => (a.variant || "").localeCompare(b.variant || "")) + .map(({ variant, nextVersion }) => `${variant}@v${nextVersion}`) + .join("_"); } diff --git a/src/tasks/createGithubRelease/index.ts b/src/tasks/createGithubRelease/index.ts index 0c116577..7730ac53 100644 --- a/src/tasks/createGithubRelease/index.ts +++ b/src/tasks/createGithubRelease/index.ts @@ -26,7 +26,7 @@ export function createGithubRelease({ return new Listr( [ - getHandleTagsTask({ github }), + getHandleTagsTask({ github, isMultiVariant }), getCreateReleaseTask({ github, composeFileName, diff --git a/src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.ts b/src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.ts index f59089b1..03b326e7 100644 --- a/src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.ts +++ b/src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.ts @@ -32,7 +32,7 @@ export function getCreateReleaseTask({ task: async (ctx, task) => { const releaseDetailsMap = buildReleaseDetailsMap(ctx); - const tag = getNextGitTag(releaseDetailsMap); + const tag = getNextGitTag(releaseDetailsMap, isMultiVariant); task.output = "Deleting existing release..."; await github.deleteReleaseAndAssets(tag); diff --git a/src/tasks/createGithubRelease/subtasks/getHandleTagsTask.ts b/src/tasks/createGithubRelease/subtasks/getHandleTagsTask.ts index 5e1ebc5f..683a2aef 100644 --- a/src/tasks/createGithubRelease/subtasks/getHandleTagsTask.ts +++ b/src/tasks/createGithubRelease/subtasks/getHandleTagsTask.ts @@ -14,9 +14,11 @@ import { buildReleaseDetailsMap } from "../buildReleaseDetailsMap.js"; * tagged and released on that tag */ export function getHandleTagsTask({ - github + github, + isMultiVariant }: { github: Github; + isMultiVariant: boolean; }): ListrTask { const isCi = process.env.CI; const triggerTag = process.env.GITHUB_REF || process.env.TRAVIS_TAG; @@ -29,7 +31,7 @@ export function getHandleTagsTask({ const releaseDetailsMap = buildReleaseDetailsMap(ctx); - const tag = getNextGitTag(releaseDetailsMap); + const tag = getNextGitTag(releaseDetailsMap, isMultiVariant); // If the release is triggered in CI, // the trigger tag must be removed ("release/patch") diff --git a/test/tasks/gitTags.test.ts b/test/tasks/gitTags.test.ts index 2be13979..c995bb65 100644 --- a/test/tasks/gitTags.test.ts +++ b/test/tasks/gitTags.test.ts @@ -5,18 +5,29 @@ import { getNextGitTag } from "../../src/tasks/createGithubRelease/getNextGitTag // Describe your test suite describe("getNextGitTag", () => { - it("should format a single-variant package correctly", () => { + it("should format a single-variant package correctly (not multi-variant)", () => { const ctx = { "geth.dnp.dapnode.eth": { variant: "mainnet", nextVersion: "0.1.2" } }; - const result = getNextGitTag(ctx); + const result = getNextGitTag(ctx, false); expect(result).to.equal("v0.1.2"); }); - it("should format and sort a multi-variant package correctly", () => { + it("should format a single-variant package as variant@v if isMultiVariant is true", () => { + const ctx = { + "gnosis.dnp.dapnode.eth": { + variant: "gnosis", + nextVersion: "0.1.2" + } + }; + const result = getNextGitTag(ctx, true); + expect(result).to.equal("gnosis@v0.1.2"); + }); + + it("should format and sort a multi-variant package correctly (isMultiVariant)", () => { const ctx = { "geth.dnp.dapnode.eth": { variant: "mainnet", @@ -31,7 +42,22 @@ describe("getNextGitTag", () => { nextVersion: "0.1.1" } }; - const result = getNextGitTag(ctx); - expect(result).to.equal("goerli@0.1.2_holesky@0.1.1_mainnet@0.1.3"); + const result = getNextGitTag(ctx, true); + expect(result).to.equal("goerli@v0.1.2_holesky@v0.1.1_mainnet@v0.1.3"); + }); + + it("should throw if any variant is missing", () => { + const ctx = { + "geth.dnp.dapnode.eth": { + variant: null, + nextVersion: "0.1.2" + } + }; + expect(() => getNextGitTag(ctx, true)).to.throw(); + }); + + it("should throw if no variants are present", () => { + const ctx = {}; + expect(() => getNextGitTag(ctx, true)).to.throw(); }); });