Skip to content

Commit

Permalink
Add suffix input and support empty strings in prefix/suffix
Browse files Browse the repository at this point in the history
  • Loading branch information
consideRatio committed Feb 15, 2024
1 parent df042f5 commit 1cdfafe
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 23 deletions.
93 changes: 92 additions & 1 deletion __tests__/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ test("Multiple prefix", async () => {
repo: "repo",
ref: "refs/tags/0.0.1",
// test use of different whitespace separators and a combination of both
prefix: "prefix1:\tprefix2:\n, prefix3:",
prefix: "prefix1:\tprefix2:\n ,prefix3:",
});
expect(tags).toEqual([
"prefix1:0.0.1",
Expand All @@ -309,6 +309,97 @@ test("Multiple prefix", async () => {
]);
});

test("Single suffix", async () => {
tagInterceptor.reply(200, [
{
name: "0.0.1",
},
]);
const tags = await calculateTags({
token: "TOKEN",
owner: "owner",
repo: "repo",
ref: "refs/tags/0.0.1",
suffix: "-suffix",
});
expect(tags).toEqual([
"0.0.1-suffix",
"0.0-suffix",
"0-suffix",
"latest-suffix",
]);
});

test("Multiple prefix and suffix", async () => {
tagInterceptor.reply(200, [
{
name: "0.0.1",
},
]);
const tags = await calculateTags({
token: "TOKEN",
owner: "owner",
repo: "repo",
ref: "refs/tags/0.0.1",
// test use of different whitespace separators and a combination of both
prefix: "prefix1:,prefix2:",
suffix: "-a -b",
});
expect(tags).toEqual([
"prefix1:0.0.1-a",
"prefix1:0.0.1-b",
"prefix2:0.0.1-a",
"prefix2:0.0.1-b",
"prefix1:0.0-a",
"prefix1:0.0-b",
"prefix2:0.0-a",
"prefix2:0.0-b",
"prefix1:0-a",
"prefix1:0-b",
"prefix2:0-a",
"prefix2:0-b",
"prefix1:latest-a",
"prefix1:latest-b",
"prefix2:latest-a",
"prefix2:latest-b",
]);
});

test("Multiple prefix and suffix with empty string", async () => {
tagInterceptor.reply(200, [
{
name: "0.0.1",
},
]);
const tags = await calculateTags({
token: "TOKEN",
owner: "owner",
repo: "repo",
ref: "refs/tags/0.0.1",
// test use of <empty-string>
prefix: "<empty-string>,prefix2:",
suffix: "<empty-string>,-b",
});
expect(tags).toEqual([
"0.0.1",
"0.0.1-b",
"prefix2:0.0.1",
"prefix2:0.0.1-b",
"0.0",
"0.0-b",
"prefix2:0.0",
"prefix2:0.0-b",
"0",
"0-b",
"prefix2:0",
"prefix2:0-b",
"latest",
"latest-b",
"prefix2:latest",
"prefix2:latest-b",
]);
});

test("Branch", async () => {
const tags = await calculateTags({
token: "TOKEN",
Expand Down
13 changes: 11 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,23 @@ inputs:
prefix:
required: false
description: |-
A string that each returned tag should be prefixed with, for example to tag a Docker container set this to `user/repository:`.
One or more whitespace or comma deliminated prefixes for returned tags.
All permutations of prefixes and suffixes are considered.
default: ""
suffix:
required: false
description: |-
One or more whitespace or comma deliminated suffixes for returned tags.
All permutations of prefixes and suffixes are considered.
default: ""
defaultTag:
required: false
description: |-
If the tag output would be empty return this tag instead.
This can be useful for running a workflow in pull requests where no suitable git references are present.
`prefix` is _not_ automatically added.
`prefix` or `suffix` are _not_ automatically added.
default: ""
branchRegex:
required: false
Expand Down
64 changes: 44 additions & 20 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,25 @@ function checkAgainstRegex(name, regexAllowed) {
return re.test(name);
}

function expandPrefix(prefix, tag) {
// Adds one or more prefixes to a tag, where prefix could be a single prefix
// or a comma/whitespace separated list of prefixes.
if (!prefix) {
return [tag];
function expandPrefixSuffix(prefix, suffix, tag) {
// Adds all permutations of prefixes and suffixes to a tag, where
// prefix/suffix could be a single prefix/suffix or a comma/whitespace
// separated list of prefixes/suffixes. If <empty-string> is observed, its
// replaced with an empty string.
let prefixes = [...new Set(prefix.split(/[\s,]/).filter(Boolean))];
let suffixes = [...new Set(suffix.split(/[\s,]/).filter(Boolean))];
prefixes = prefixes.map((p) => p.replaceAll(/<empty-string>/g, ""));
suffixes = suffixes.map((p) => p.replaceAll(/<empty-string>/g, ""));

// the permutation logic requires at least one element in each list
if (prefixes.length == 0) {
prefixes.push("");
}

let rv = [];
let prefixes = prefix.split(/\s|,/).filter(Boolean);
prefixes.forEach((p) => rv.push(`${p}${tag}`));
return rv;
if (suffixes.length == 0) {
suffixes.push("");
}
// permute
return prefixes.flatMap((p) => suffixes.map((s) => `${p}${tag}${s}`));
}

async function calculateTags({
Expand All @@ -44,6 +52,7 @@ async function calculateTags({
repo,
ref,
prefix = "",
suffix = "",
defaultTag = "",
regexAllowed = "",
}) {
Expand Down Expand Up @@ -72,7 +81,7 @@ async function calculateTags({
}
return [];
}
return expandPrefix(prefix, branch);
return expandPrefixSuffix(prefix, suffix, branch);
}
if (!ref.startsWith("refs/tags/")) {
throw new Error(`Not a tag or branch: ${ref}`);
Expand All @@ -90,7 +99,7 @@ async function calculateTags({
});
if (!supportedPrerelease(current.prerelease)) {
core.warning(`Tag prerelease ${currentTag} is not supported`);
return expandPrefix(prefix, currentTag);
return expandPrefixSuffix(prefix, suffix, currentTag);
}

const octokit = github.getOctokit(token);
Expand All @@ -116,7 +125,7 @@ async function calculateTags({

let outputTags = [];
if (current.prerelease.length) {
outputTags.push(...expandPrefix(prefix, current.version));
outputTags.push(...expandPrefixSuffix(prefix, suffix, current.version));

// return without additional output tags if we got an outdated build number
const similarTags = tags.filter(
Expand All @@ -128,8 +137,9 @@ async function calculateTags({
}

outputTags.push(
...expandPrefix(
...expandPrefixSuffix(
prefix,
suffix,
`${current.major}.${current.minor}.${current.patch}`,
),
);
Expand All @@ -140,22 +150,34 @@ async function calculateTags({
semver.compare(current.toString().split("-")[0], tags[0]) >= 0
) {
outputTags.push(
...expandPrefix(prefix, `${current.major}.${current.minor}`),
...expandPrefixSuffix(
prefix,
suffix,
`${current.major}.${current.minor}`,
),
);
outputTags.push(...expandPrefix(prefix, `${current.major}`));
outputTags.push(...expandPrefix(prefix, "latest"));
outputTags.push(...expandPrefixSuffix(prefix, suffix, `${current.major}`));
outputTags.push(...expandPrefixSuffix(prefix, suffix, "latest"));
} else if (
semver.compare(current.toString().split("-")[0], majorTags[0]) >= 0
) {
outputTags.push(
...expandPrefix(prefix, `${current.major}.${current.minor}`),
...expandPrefixSuffix(
prefix,
suffix,
`${current.major}.${current.minor}`,
),
);
outputTags.push(...expandPrefix(prefix, `${current.major}`));
outputTags.push(...expandPrefixSuffix(prefix, suffix, `${current.major}`));
} else if (
semver.compare(current.toString().split("-")[0], minorTags[0]) >= 0
) {
outputTags.push(
...expandPrefix(prefix, `${current.major}.${current.minor}`),
...expandPrefixSuffix(
prefix,
suffix,
`${current.major}.${current.minor}`,
),
);
}
core.debug(`outputTags: ${outputTags}`);
Expand All @@ -168,6 +190,7 @@ async function run() {
// githubToken: ${{ secrets.GITHUB_TOKEN }}
const githubToken = core.getInput("githubToken");
const prefix = core.getInput("prefix");
const suffix = core.getInput("suffix");
const defaultTag = core.getInput("defaultTag");
const branchRegex = core.getInput("branchRegex");

Expand All @@ -178,6 +201,7 @@ async function run() {
repo: github.context.payload.repository.name,
ref: github.context.payload.ref,
prefix: prefix,
suffix: suffix,
defaultTag: defaultTag,
regexAllowed: branchRegex,
});
Expand Down

0 comments on commit 1cdfafe

Please sign in to comment.