Skip to content

Commit b52813f

Browse files
committed
feat: raise error when GitLab CLI is required but not installed
1 parent e0885b5 commit b52813f

File tree

5 files changed

+59
-3
lines changed

5 files changed

+59
-3
lines changed

lib/definitions/errors.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,8 @@ Please make sure the GitLab user associated with the token has the [permission t
8787
8888
Please make sure to create a [GitLab personal access token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html) and to set it in the \`GL_TOKEN\` or \`GITLAB_TOKEN\` environment variable on your CI environment. The token must allow to push to the repository ${repositoryUrl}.`,
8989
}),
90+
EGLABNOTINSTALLED: () => ({
91+
message: 'GitLab CLI not installed.',
92+
details: 'The [GitLab CLI needs to be installed](https://gitlab.com/gitlab-org/cli#installation) so that the project\'s CI components can be published.',
93+
}),
9094
};

lib/glab.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { execa } from "execa";
2+
3+
export default async (args, options) => {
4+
return execa("glab", args, options);
5+
};

lib/publish.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import resolveConfig from "./resolve-config.js";
1212
import getAssets from "./glob-assets.js";
1313
import { RELEASE_NAME } from "./definitions/constants.js";
1414
import getProjectContext from "./get-project-context.js";
15-
import { execa } from "execa";
15+
import glab from "./glab.js";
1616
const isUrlScheme = (value) => /^(https|http|ftp):\/\//.test(value);
1717

1818
export default async (pluginConfig, context) => {
@@ -195,7 +195,7 @@ export default async (pluginConfig, context) => {
195195

196196
if (publishToCatalog) {
197197
try {
198-
await execa("glab", ["repo", "publish", "catalog", gitTag], {
198+
await glab(["repo", "publish", "catalog", gitTag], {
199199
cwd,
200200
timeout: 30 * 1000,
201201
env: { GITLAB_TOKEN: gitlabToken },

lib/verify.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ export default async (pluginConfig, context) => {
3030
options: { repositoryUrl },
3131
logger,
3232
} = context;
33-
const { gitlabToken, gitlabUrl, gitlabApiUrl, proxy, ...options } = resolveConfig(pluginConfig, context);
33+
const { gitlabToken, gitlabUrl, gitlabApiUrl, proxy, publishToCatalog, ...options } = resolveConfig(
34+
pluginConfig,
35+
context
36+
);
3437
const { projectPath, projectApiUrl } = getProjectContext(context, gitlabUrl, gitlabApiUrl, repositoryUrl);
3538

3639
debug("apiUrl: %o", gitlabApiUrl);
@@ -89,6 +92,18 @@ export default async (pluginConfig, context) => {
8992
}
9093
}
9194

95+
if (publishToCatalog === true) {
96+
try {
97+
logger.log("Verifying that the GitLab CLI is installed");
98+
await glab(["version"], {
99+
timeout: 5 * 1000,
100+
});
101+
} catch (error) {
102+
logger.error("The GitLab CLI is required but failed to run:\n%O", error);
103+
errors.push(getError("EGLABNOTINSTALLED"));
104+
}
105+
}
106+
92107
if (errors.length > 0) {
93108
throw new AggregateError(errors);
94109
}

test/verify.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import nock from "nock";
33
import { stub } from "sinon";
44
import verify from "../lib/verify.js";
55
import authenticate from "./helpers/mock-gitlab.js";
6+
import * as td from "testdouble";
67

78
/* eslint camelcase: ["error", {properties: "never"}] */
89

@@ -988,3 +989,34 @@ test.serial(
988989
t.true(gitlab.isDone());
989990
}
990991
);
992+
993+
test.serial(
994+
'Throw SemanticReleaseError if "publishToCatalog" option is set and the GitLab CLI is not installed.',
995+
async (t) => {
996+
const owner = "test_user";
997+
const repo = "test_repo";
998+
const env = { GITLAB_TOKEN: "gitlab_token" };
999+
const gitlab = authenticate(env)
1000+
.get(`/projects/${owner}%2F${repo}`)
1001+
.reply(200, { permissions: { project_access: { access_level: 40 } } });
1002+
1003+
const execa = (await td.replaceEsm("execa")).execa;
1004+
td.when(
1005+
execa("glab", ["version"], {
1006+
timeout: 5000,
1007+
})
1008+
).thenReject();
1009+
const verifyWithMockExeca = (await import("../lib/verify.js")).default;
1010+
const {
1011+
errors: [error],
1012+
} = await t.throwsAsync(
1013+
verifyWithMockExeca(
1014+
{ publishToCatalog: true },
1015+
{ env, options: { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` }, logger: t.context.logger }
1016+
)
1017+
);
1018+
t.is(error.name, "SemanticReleaseError");
1019+
t.is(error.code, "EGLABNOTINSTALLED");
1020+
t.true(gitlab.isDone());
1021+
}
1022+
);

0 commit comments

Comments
 (0)