Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ jobs:
strategy:
matrix:
node-version:
- '14.17'
- 16
- 18.0.0
- 19
os:
- ubuntu-latest
- macos-latest
Expand All @@ -30,7 +30,7 @@ jobs:
- run: npm ci
- name: Ensure dependencies are compatible with the version of node
run: npx ls-engines
- run: "npm run test:ci"
- run: npm run test
test:
runs-on: ubuntu-latest
needs: test_matrix
Expand Down
92 changes: 48 additions & 44 deletions README.md

Large diffs are not rendered by default.

18 changes: 8 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/* eslint require-atomic-updates: off */

const verifyGitLab = require('./lib/verify');
const publishGitLab = require('./lib/publish');
const successGitLab = require('./lib/success');
const failGitLab = require('./lib/fail');
import verifyGitLab from "./lib/verify.js";
import publishGitLab from "./lib/publish.js";
import successGitLab from "./lib/success.js";
import failGitLab from "./lib/fail.js";

let verified;

async function verifyConditions(pluginConfig, context) {
export async function verifyConditions(pluginConfig, context) {
await verifyGitLab(pluginConfig, context);
verified = true;
}

async function publish(pluginConfig, context) {
export async function publish(pluginConfig, context) {
if (!verified) {
await verifyGitLab(pluginConfig, context);
verified = true;
Expand All @@ -21,7 +21,7 @@ async function publish(pluginConfig, context) {
return publishGitLab(pluginConfig, context);
}

async function success(pluginConfig, context) {
export async function success(pluginConfig, context) {
if (!verified) {
await verifyGitLab(pluginConfig, context);
verified = true;
Expand All @@ -30,13 +30,11 @@ async function success(pluginConfig, context) {
return successGitLab(pluginConfig, context);
}

async function fail(pluginConfig, context) {
export async function fail(pluginConfig, context) {
if (!verified) {
await verifyGitLab(pluginConfig, context);
verified = true;
}

return failGitLab(pluginConfig, context);
}

module.exports = {verifyConditions, publish, success, fail};
6 changes: 2 additions & 4 deletions lib/definitions/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const HOME_URL = 'https://github.com/semantic-release/semantic-release';
export const HOME_URL = 'https://github.com/semantic-release/semantic-release';

const RELEASE_NAME = 'GitLab release';

module.exports = {HOME_URL, RELEASE_NAME};
export const RELEASE_NAME = 'GitLab release';
6 changes: 3 additions & 3 deletions lib/definitions/errors.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const {inspect} = require('util');
const pkg = require('../../package.json');
import {inspect} from 'util';
import pkg from '../../package.json' assert {type: 'json'};

const [homepage] = pkg.homepage.split('#');
const linkify = (file) => `${homepage}/blob/master/${file}`;
const stringify = (object) => inspect(object, {breakLength: Number.POSITIVE_INFINITY, depth: 2, maxArrayLength: 5});

module.exports = {
export default {
EINVALIDASSETS: ({assets}) => ({
message: 'Invalid `assets` option.',
details: `The [assets option](${linkify(
Expand Down
47 changes: 24 additions & 23 deletions lib/fail.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,63 @@
const {template} = require('lodash');
const urlJoin = require('url-join');
const got = require('got');
const debug = require('debug')('semantic-release:gitlab');
const resolveConfig = require('./resolve-config');
const getRepoId = require('./get-repo-id');
const getFailComment = require('./get-fail-comment');

module.exports = async (pluginConfig, context) => {
import { template } from "lodash-es";
import urlJoin from "url-join";
import got from "got";
import _debug from "debug";
const debug = _debug("semantic-release:gitlab");
import resolveConfig from "./resolve-config.js";
import getRepoId from "./get-repo-id.js";
import getFailComment from "./get-fail-comment.js";

export default async (pluginConfig, context) => {
const {
options: {repositoryUrl},
options: { repositoryUrl },
branch,
errors,
logger,
} = context;
const {gitlabToken, gitlabUrl, gitlabApiUrl, failComment, failTitle, labels, assignee} = resolveConfig(
const { gitlabToken, gitlabUrl, gitlabApiUrl, failComment, failTitle, labels, assignee } = resolveConfig(
pluginConfig,
context
);
const repoId = getRepoId(context, gitlabUrl, repositoryUrl);
const encodedRepoId = encodeURIComponent(repoId);
const apiOptions = {headers: {'PRIVATE-TOKEN': gitlabToken}};
const apiOptions = { headers: { "PRIVATE-TOKEN": gitlabToken } };

if (failComment === false || failTitle === false) {
logger.log('Skip issue creation.');
logger.log("Skip issue creation.");
} else {
const encodedFailTitle = encodeURIComponent(failTitle);
const description = failComment ? template(failComment)({branch, errors}) : getFailComment(branch, errors);
const description = failComment ? template(failComment)({ branch, errors }) : getFailComment(branch, errors);

const issuesEndpoint = urlJoin(gitlabApiUrl, `/projects/${encodedRepoId}/issues`);
const openFailTitleIssueEndpoint = urlJoin(issuesEndpoint, `?state=opened&search=${encodedFailTitle}`);

const openFailTitleIssues = await got(openFailTitleIssueEndpoint, {...apiOptions}).json();
const openFailTitleIssues = await got(openFailTitleIssueEndpoint, { ...apiOptions }).json();
const existingIssue = openFailTitleIssues.find((openFailTitleIssue) => openFailTitleIssue.title === failTitle);

if (existingIssue) {
debug('comment on issue: %O', existingIssue);
debug("comment on issue: %O", existingIssue);

const issueNotesEndpoint = urlJoin(
gitlabApiUrl,
`/projects/${existingIssue.project_id}/issues/${existingIssue.iid}/notes`
);
await got.post(issueNotesEndpoint, {
...apiOptions,
json: {body: description},
json: { body: description },
});

const {id, web_url} = existingIssue;
logger.log('Commented on issue #%d: %s.', id, web_url);
const { id, web_url } = existingIssue;
logger.log("Commented on issue #%d: %s.", id, web_url);
} else {
const newIssue = {id: encodedRepoId, description, labels, title: failTitle, assignee_id: assignee};
debug('create issue: %O', newIssue);
const newIssue = { id: encodedRepoId, description, labels, title: failTitle, assignee_id: assignee };
debug("create issue: %O", newIssue);

/* eslint camelcase: off */
const {id, web_url} = await got.post(issuesEndpoint, {
const { id, web_url } = await got.post(issuesEndpoint, {
...apiOptions,
json: newIssue,
});
logger.log('Created issue #%d: %s.', id, web_url);
logger.log("Created issue #%d: %s.", id, web_url);
}
}
};
8 changes: 4 additions & 4 deletions lib/get-error.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const SemanticReleaseError = require('@semantic-release/error');
const ERROR_DEFINITIONS = require('./definitions/errors');
import SemanticReleaseError from "@semantic-release/error";
import ERROR_DEFINITIONS from "./definitions/errors.js";

module.exports = (code, ctx = {}) => {
const {message, details} = ERROR_DEFINITIONS[code](ctx);
export default (code, ctx = {}) => {
const { message, details } = ERROR_DEFINITIONS[code](ctx);
return new SemanticReleaseError(message, code, details);
};
8 changes: 4 additions & 4 deletions lib/get-fail-comment.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {HOME_URL} = require('./definitions/constants');
import { HOME_URL } from "./definitions/constants.js";

const FAQ_URL = `${HOME_URL}/blob/master/docs/support/FAQ.md`;
const GET_HELP_URL = `${HOME_URL}#get-help`;
Expand All @@ -12,11 +12,11 @@ ${
`Unfortunately this error doesn't have any additional information.${
error.pluginName
? ` Feel free to kindly ask the author of the \`${error.pluginName}\` plugin to add more helpful information.`
: ''
: ""
}`
}`;

module.exports = (branch, errors) => `## :rotating_light: The automated release from the \`${
export default (branch, errors) => `## :rotating_light: The automated release from the \`${
branch.name
}\` branch failed. :rotating_light:

Expand All @@ -39,7 +39,7 @@ If those don't help, or if this issue is reporting something you think isn't rig

---

${errors.map((error) => formatError(error)).join('\n\n---\n\n')}
${errors.map((error) => formatError(error)).join("\n\n---\n\n")}

---

Expand Down
16 changes: 8 additions & 8 deletions lib/get-repo-id.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const parseUrl = require('parse-url');
const escapeStringRegexp = require('escape-string-regexp');
import parseUrl from "parse-url";
import escapeStringRegexp from "escape-string-regexp";

module.exports = ({envCi: {service} = {}, env: {CI_PROJECT_PATH}}, gitlabUrl, repositoryUrl) =>
service === 'gitlab' && CI_PROJECT_PATH
export default ({ envCi: { service } = {}, env: { CI_PROJECT_PATH } }, gitlabUrl, repositoryUrl) =>
service === "gitlab" && CI_PROJECT_PATH
? CI_PROJECT_PATH
: parseUrl(repositoryUrl)
.pathname.replace(new RegExp(`^${escapeStringRegexp(parseUrl(gitlabUrl).pathname)}`), '')
.replace(/^\//, '')
.replace(/\/$/, '')
.replace(/\.git$/, '');
.pathname.replace(new RegExp(`^${escapeStringRegexp(parseUrl(gitlabUrl).pathname)}`), "")
.replace(/^\//, "")
.replace(/\/$/, "")
.replace(/\.git$/, "");
10 changes: 5 additions & 5 deletions lib/get-success-comment.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
const {HOME_URL} = require('./definitions/constants');
import { HOME_URL } from "./definitions/constants.js";

const linkify = (releaseInfo) =>
`${releaseInfo.url ? `[${releaseInfo.name}](${releaseInfo.url})` : `\`${releaseInfo.name}\``}`;

module.exports = (issueOrMergeRequest, releaseInfos, nextRelease) =>
`:tada: This ${issueOrMergeRequest.isMergeRequest ? 'MR is included' : 'issue has been resolved'} in version ${
export default (issueOrMergeRequest, releaseInfos, nextRelease) =>
`:tada: This ${issueOrMergeRequest.isMergeRequest ? "MR is included" : "issue has been resolved"} in version ${
nextRelease.version
} :tada:${
releaseInfos.length > 0
? `\n\nThe release is available on${
releaseInfos.length === 1
? ` ${linkify(releaseInfos[0])}.`
: `:\n${releaseInfos.map((releaseInfo) => `- ${linkify(releaseInfo)}`).join('\n')}`
: `:\n${releaseInfos.map((releaseInfo) => `- ${linkify(releaseInfo)}`).join("\n")}`
}`
: ''
: ""
}
\nYour **[semantic-release](${HOME_URL})** bot :package: :rocket:`;
25 changes: 13 additions & 12 deletions lib/glob-assets.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const path = require('path');
const {isPlainObject, castArray, uniqWith, uniq} = require('lodash');
const dirGlob = require('dir-glob');
const globby = require('globby');
const debug = require('debug')('semantic-release:gitlab');
import path from "path";
import { isPlainObject, castArray, uniqWith, uniq } from "lodash-es";
import dirGlob from "dir-glob";
import globby from "globby";
import _debug from "debug";
const debug = _debug("semantic-release:gitlab");

module.exports = async ({cwd}, assets) =>
export default async ({ cwd }, assets) =>
uniqWith(
[]
// eslint-disable-next-line unicorn/prefer-spread
Expand All @@ -14,12 +15,12 @@ module.exports = async ({cwd}, assets) =>
// Wrap single glob definition in Array
let glob = castArray(isPlainObject(asset) ? asset.path : asset);
// TODO Temporary workaround for https://github.com/mrmlnc/fast-glob/issues/47
glob = uniq([...(await dirGlob(glob, {cwd})), ...glob]);
glob = uniq([...(await dirGlob(glob, { cwd })), ...glob]);

// Skip solo negated pattern (avoid to include every non js file with `!**/*.js`)
if (glob.length <= 1 && glob[0].startsWith('!')) {
if (glob.length <= 1 && glob[0].startsWith("!")) {
debug(
'skipping the negated glob %o as its alone in its group and would retrieve a large amount of files',
"skipping the negated glob %o as its alone in its group and would retrieve a large amount of files",
glob[0]
);
return [];
Expand All @@ -41,14 +42,14 @@ module.exports = async ({cwd}, assets) =>
// - `label` based on the actual file name (to avoid assets with duplicate `label`s)
// - `filepath` ignored (also to avoid duplicates)
// - other properties of the original asset definition
const {filepath, ...others} = asset;
return globbed.map((file) => ({...others, path: file, label: path.basename(file)}));
const { filepath, ...others } = asset;
return globbed.map((file) => ({ ...others, path: file, label: path.basename(file) }));
}

// If asset is an Object, output an Object definition with:
// - `path` of the matched file if there is one, or the original `path` definition (will be considered as a missing file)
// - other properties of the original asset definition
return {...asset, path: globbed[0] || asset.path};
return { ...asset, path: globbed[0] || asset.path };
}

if (globbed.length > 0) {
Expand Down
Loading