From 3133b39e7bba8f5d2b526c8a484616da88153dbc Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 23 Jan 2022 14:11:21 +0800 Subject: [PATCH 01/23] feat: accept url from release setting for skipping upload --- lib/publish.js | 69 +++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/lib/publish.js b/lib/publish.js index c467067c..7e1211f1 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -37,48 +37,55 @@ module.exports = async (pluginConfig, context) => { await Promise.all( globbedAssets.map(async (asset) => { const {path, type, filepath} = isPlainObject(asset) ? asset : {path: asset}; - const file = pathlib.resolve(cwd, path); const label = asset.label ? template(asset.label)(context) : undefined; - let fileStat; + const _url = asset.url + if (_url) { + assetsList.push({ label, url: _url, type, filepath }); + debug('use link from release setting: %s', _url); + } else { + const file = pathlib.resolve(cwd, path); - try { - fileStat = await stat(file); - } catch { - logger.error('The asset %s cannot be read, and will be ignored.', path); - return; - } + let fileStat; - if (!fileStat || !fileStat.isFile()) { - logger.error('The asset %s is not a file, and will be ignored.', path); - return; - } + try { + fileStat = await stat(file); + } catch { + logger.error('The asset %s cannot be read, and will be ignored.', path); + return; + } - debug('file path: %o', path); - debug('file label: %o', label); - debug('file type: %o', type); - debug('file filepath: %o', filepath); + if (!fileStat || !fileStat.isFile()) { + logger.error('The asset %s is not a file, and will be ignored.', path); + return; + } - // Uploaded assets to the project - const form = new FormData(); - form.append('file', createReadStream(file)); + debug('file path: %o', path); + debug('file label: %o', label); + debug('file type: %o', type); + debug('file filepath: %o', filepath); - const uploadEndpoint = urlJoin(gitlabApiUrl, `/projects/${encodedRepoId}/uploads`); + // Uploaded assets to the project + const form = new FormData(); + form.append('file', createReadStream(file)); - debug('POST-ing the file %s to %s', file, uploadEndpoint); + const uploadEndpoint = urlJoin(gitlabApiUrl, `/projects/${encodedRepoId}/uploads`); - let response; - try { - response = await got.post(uploadEndpoint, {...apiOptions, ...proxy, body: form}).json(); - } catch (error) { - logger.error('An error occurred while uploading %s to the GitLab project uploads API:\n%O', file, error); - throw error; - } + debug('POST-ing the file %s to %s', file, uploadEndpoint); - const {url, alt} = response; + let response; + try { + response = await got.post(uploadEndpoint, { ...apiOptions, ...proxy, body: form }).json(); + } catch (error) { + logger.error('An error occurred while uploading %s to the GitLab project uploads API:\n%O', file, error); + throw error; + } - assetsList.push({label, alt, url, type, filepath}); + const { url, alt } = response; - logger.log('Uploaded file: %s', url); + assetsList.push({ label, alt, url, type, filepath }); + + logger.log('Uploaded file: %s', url); + } }) ); } From 0fc0cf9a137873361a921c3978a0577bc9c8211a Mon Sep 17 00:00:00 2001 From: awcjack Date: Sat, 16 Apr 2022 17:03:29 +0000 Subject: [PATCH 02/23] Update README.md Add example and description of path in asset --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 564e8ede..3777ed5d 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ The plugin can be configured in the [**semantic-release** configuration file](ht {"path": "dist/asset.min.css", "label": "CSS distribution"}, {"path": "dist/asset.min.js", "label": "JS distribution"}, {"path": "dist/asset.min.js", "label": "v${nextRelease.version}.js"} + {"url": "https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md"} ] }], ] @@ -95,7 +96,8 @@ Can be a [glob](https://github.com/isaacs/node-glob#glob-primer) or and `Array` | Property | Description | Default | | -------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `path` | **Required.** A [glob](https://github.com/isaacs/node-glob#glob-primer) to identify the files to upload. | - | +| `url` | **path or url is required.** This provides the ability to add links to releases. E.g. URLs to container images. | - | +| `path` | **path or url is required.** A [glob](https://github.com/isaacs/node-glob#glob-primer) to identify the files to upload. | - | | `label` | Short description of the file displayed on the GitLab release. Can be dynamically adjusted with [Lodash template](https://lodash.com/docs#template). Allows same variables as [`successComment`](#successComment). Ignored if `path` matches more than one file. | File name extracted from the `path`. | | `type` | Asset type displayed on the GitLab release. Can be `runbook`, `package`, `image` and `other` (see official documents on [release assets](https://docs.gitlab.com/ee/user/project/releases/#release-assets)). | `other` | | `filepath` | A filepath for creating a permalink pointing to the asset (requires GitLab 12.9+, see official documents on [permanent links](https://docs.gitlab.com/ee/user/project/releases/#permanent-links-to-release-assets)). Ignored if `path` matches more than one file. | - | From 571797b4f04f2b44b171672c01962110a6e2ac26 Mon Sep 17 00:00:00 2001 From: awcjack Date: Sat, 16 Apr 2022 17:05:02 +0000 Subject: [PATCH 03/23] update publish.js for syntax --- lib/publish.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/publish.js b/lib/publish.js index 7e1211f1..04922a13 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -40,7 +40,7 @@ module.exports = async (pluginConfig, context) => { const label = asset.label ? template(asset.label)(context) : undefined; const _url = asset.url if (_url) { - assetsList.push({ label, url: _url, type, filepath }); + assetsList.push({label, url: _url, type, filepath}); debug('use link from release setting: %s', _url); } else { const file = pathlib.resolve(cwd, path); From edcaa348f36b0971addf64782a3f83fd4aa81127 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 17 Apr 2022 09:10:03 +0800 Subject: [PATCH 04/23] fix: lint --- lib/publish.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/publish.js b/lib/publish.js index 04922a13..3dbd19b9 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -38,7 +38,7 @@ module.exports = async (pluginConfig, context) => { globbedAssets.map(async (asset) => { const {path, type, filepath} = isPlainObject(asset) ? asset : {path: asset}; const label = asset.label ? template(asset.label)(context) : undefined; - const _url = asset.url + const _url = asset.url; if (_url) { assetsList.push({label, url: _url, type, filepath}); debug('use link from release setting: %s', _url); @@ -80,9 +80,9 @@ module.exports = async (pluginConfig, context) => { throw error; } - const { url, alt } = response; + const {url, alt} = response; - assetsList.push({ label, alt, url, type, filepath }); + assetsList.push({label, alt, url, type, filepath}); logger.log('Uploaded file: %s', url); } From 0f2eeb002094afe4875640bd232cc03af84fb54e Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 17 Apr 2022 09:18:12 +0800 Subject: [PATCH 05/23] test: add unit test of publish release with asset link --- test/publish.test.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/publish.test.js b/test/publish.test.js index 27a083e8..0398a273 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -294,3 +294,42 @@ test.serial('Publish a release with missing release notes', async (t) => { t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); + +test.serial('Publish a release with an asset link', async t => { + const cwd = 'test/fixtures/files'; + const owner = 'test_user'; + const repo = 'test_repo'; + const env = {GITLAB_TOKEN: 'gitlab_token'}; + const nextRelease = {gitHead: '123', gitTag: 'v1.0.0', notes: 'Test release note body'}; + const options = {repositoryUrl: `https://gitlab.com/${owner}/${repo}.git`}; + const encodedRepoId = encodeURIComponent(`${owner}/${repo}`); + const encodedGitTag = encodeURIComponent(nextRelease.gitTag); + const link = { + path: 'file.css', + label: 'README.md', + type: 'other', + url: 'https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md', + }; + const assets = [link]; + const gitlab = authenticate(env) + .post(`/projects/${encodedRepoId}/releases`, { + tag_name: nextRelease.gitTag, + description: nextRelease.notes, + assets: { + links: [ + { + name: 'README.md', + url: `https://gitlab.com/${owner}/${repo}/https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, + link_type: 'other', + }, + ], + }, + }) + .reply(200); + + const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); + + t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`); + t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); + t.true(gitlab.isDone()); +}); From 54b91879262c4cdefcbab58dc335afd785ce8ddb Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 17 Apr 2022 09:34:32 +0800 Subject: [PATCH 06/23] fix: url asset skip glob --- lib/publish.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/publish.js b/lib/publish.js index 3dbd19b9..43d94c86 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -31,11 +31,19 @@ module.exports = async (pluginConfig, context) => { debug('milestones: %o', milestones); if (assets && assets.length > 0) { - const globbedAssets = await getAssets(context, assets); + // Skip glob if url is provided + const urlAssets = assets.filter(asset => asset.url); + debug('url assets: %o', urlAssets); + const globbedAssets = await getAssets( + context, + assets.filter(asset => !asset.url) + ); debug('globbed assets: %o', globbedAssets); + const allAssets = [...urlAssets, ...globbedAssets]; + debug('all assets: %o', allAssets); await Promise.all( - globbedAssets.map(async (asset) => { + allAssets.map(async (asset) => { const {path, type, filepath} = isPlainObject(asset) ? asset : {path: asset}; const label = asset.label ? template(asset.label)(context) : undefined; const _url = asset.url; From c2e11b4cb984b3bf843206db9a1ef14a47fa1228 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 17 Apr 2022 09:34:54 +0800 Subject: [PATCH 07/23] test: publish release with asset link allow empty path --- test/publish.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/publish.test.js b/test/publish.test.js index 0398a273..48c6d848 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -305,7 +305,6 @@ test.serial('Publish a release with an asset link', async t => { const encodedRepoId = encodeURIComponent(`${owner}/${repo}`); const encodedGitTag = encodeURIComponent(nextRelease.gitTag); const link = { - path: 'file.css', label: 'README.md', type: 'other', url: 'https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md', From c88e8725370b15f1d761c1918e8031dc1ae6375d Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 17 Apr 2022 09:39:02 +0800 Subject: [PATCH 08/23] fix: link asset should not join url with original gitlabUrl --- lib/publish.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/publish.js b/lib/publish.js index 43d94c86..e8cce105 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -48,7 +48,7 @@ module.exports = async (pluginConfig, context) => { const label = asset.label ? template(asset.label)(context) : undefined; const _url = asset.url; if (_url) { - assetsList.push({label, url: _url, type, filepath}); + assetsList.push({label, rawUrl: _url, type, filepath}); debug('use link from release setting: %s', _url); } else { const file = pathlib.resolve(cwd, path); @@ -108,10 +108,10 @@ module.exports = async (pluginConfig, context) => { description: notes && notes.trim() ? notes : gitTag, milestones, assets: { - links: assetsList.map(({label, alt, url, type, filepath}) => { + links: assetsList.map(({label, alt, url, type, filepath, rawUrl}) => { return { name: label || alt, - url: urlJoin(gitlabUrl, repoId, url), + url: rawUrl || urlJoin(gitlabUrl, repoId, url), link_type: type, filepath, }; From 1313bed6d137b9f87bf22c7a856099de1cdc32c9 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 17 Apr 2022 09:39:24 +0800 Subject: [PATCH 09/23] test: publish release with asset link testcase update --- test/publish.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/publish.test.js b/test/publish.test.js index 48c6d848..2e516c26 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -318,7 +318,7 @@ test.serial('Publish a release with an asset link', async t => { links: [ { name: 'README.md', - url: `https://gitlab.com/${owner}/${repo}/https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, + url: `https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, link_type: 'other', }, ], From 2b3ea8b26ee2fe0822e13cb143d6dd03b6669ba2 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 17 Apr 2022 10:33:36 +0800 Subject: [PATCH 10/23] feat: allow loading variable from release url --- lib/publish.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/publish.js b/lib/publish.js index e8cce105..06b10b75 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -48,6 +48,17 @@ module.exports = async (pluginConfig, context) => { const label = asset.label ? template(asset.label)(context) : undefined; const _url = asset.url; if (_url) { + // Allow loading variable from process.env load CI_JOB_ID for attaching CI artifact + const matchedVariables = _url.match(/\${[a-zA-Z].*}/); + if (matchedVariables) { + for (const matchedVariable of matchedVariables) { + const variableName = matchedVariable.slice(2, -1); + if (process.env[variableName]) { + _url = _url.replace(matchedVariable, process.env[variableName]); + } + } + } + assetsList.push({label, rawUrl: _url, type, filepath}); debug('use link from release setting: %s', _url); } else { From 48da5e801cb956c37b89492131e397bf3464a517 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Sun, 17 Apr 2022 10:33:55 +0800 Subject: [PATCH 11/23] test: unit test of public release with asset link with variable --- test/publish.test.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/publish.test.js b/test/publish.test.js index 2e516c26..9411f91a 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -332,3 +332,42 @@ test.serial('Publish a release with an asset link', async t => { t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); + +test.serial('Publish a release with an asset link with variable', async t => { + const cwd = 'test/fixtures/files'; + const owner = 'test_user'; + const repo = 'test_repo'; + process.env.repo = 'gitlab'; + const env = {GITLAB_TOKEN: 'gitlab_token'}; + const nextRelease = {gitHead: '123', gitTag: 'v1.0.0', notes: 'Test release note body'}; + const options = {repositoryUrl: `https://gitlab.com/${owner}/${repo}.git`}; + const encodedRepoId = encodeURIComponent(`${owner}/${repo}`); + const encodedGitTag = encodeURIComponent(nextRelease.gitTag); + const link = { + label: 'README.md', + type: 'other', + url: 'https://gitlab.com/gitlab-org/${repo}/-/blob/master/README.md', // eslint-disable-line no-template-curly-in-string + }; + const assets = [link]; + const gitlab = authenticate(env) + .post(`/projects/${encodedRepoId}/releases`, { + tag_name: nextRelease.gitTag, + description: nextRelease.notes, + assets: { + links: [ + { + name: 'README.md', + url: `https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, + link_type: 'other', + }, + ], + }, + }) + .reply(200); + + const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); + + t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`); + t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); + t.true(gitlab.isDone()); +}); From f3e6d81e390620d61d628a8e93f24a716e9d9baf Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Tue, 26 Apr 2022 08:32:22 +0800 Subject: [PATCH 12/23] docs: reorder assets path & url to weight path higher --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3777ed5d..9620883a 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,8 @@ Can be a [glob](https://github.com/isaacs/node-glob#glob-primer) or and `Array` | Property | Description | Default | | -------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `url` | **path or url is required.** This provides the ability to add links to releases. E.g. URLs to container images. | - | | `path` | **path or url is required.** A [glob](https://github.com/isaacs/node-glob#glob-primer) to identify the files to upload. | - | +| `url` | **path or url is required.** This provides the ability to add links to releases. E.g. URLs to container images. | - | | `label` | Short description of the file displayed on the GitLab release. Can be dynamically adjusted with [Lodash template](https://lodash.com/docs#template). Allows same variables as [`successComment`](#successComment). Ignored if `path` matches more than one file. | File name extracted from the `path`. | | `type` | Asset type displayed on the GitLab release. Can be `runbook`, `package`, `image` and `other` (see official documents on [release assets](https://docs.gitlab.com/ee/user/project/releases/#release-assets)). | `other` | | `filepath` | A filepath for creating a permalink pointing to the asset (requires GitLab 12.9+, see official documents on [permanent links](https://docs.gitlab.com/ee/user/project/releases/#permanent-links-to-release-assets)). Ignored if `path` matches more than one file. | - | From 3d4ad217cb41f2997c0122f2fb754ed732e5f1bc Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Tue, 26 Apr 2022 17:54:25 +0800 Subject: [PATCH 13/23] fix: typo in url variable regex --- lib/publish.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/publish.js b/lib/publish.js index 06b10b75..c3915b46 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -49,7 +49,7 @@ module.exports = async (pluginConfig, context) => { const _url = asset.url; if (_url) { // Allow loading variable from process.env load CI_JOB_ID for attaching CI artifact - const matchedVariables = _url.match(/\${[a-zA-Z].*}/); + const matchedVariables = _url.match(/\${\w+}/g); if (matchedVariables) { for (const matchedVariable of matchedVariables) { const variableName = matchedVariable.slice(2, -1); From a98c008196ca012d4ebcb2e43443d280c3d51222 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Tue, 26 Apr 2022 17:54:38 +0800 Subject: [PATCH 14/23] fix: url variable replace globally --- lib/publish.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/publish.js b/lib/publish.js index c3915b46..0a6f7183 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -11,6 +11,10 @@ const getRepoId = require('./get-repo-id'); const getAssets = require('./glob-assets'); const {RELEASE_NAME} = require('./definitions/constants'); +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + module.exports = async (pluginConfig, context) => { const { cwd, @@ -54,7 +58,7 @@ module.exports = async (pluginConfig, context) => { for (const matchedVariable of matchedVariables) { const variableName = matchedVariable.slice(2, -1); if (process.env[variableName]) { - _url = _url.replace(matchedVariable, process.env[variableName]); + _url = _url.replace(new RegExp(escapeRegExp(matchedVariable), 'g'), process.env[variableName]); } } } From 45968b3f0575034e1ca8e7c6037f72fa7b54ad17 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Tue, 26 Apr 2022 17:55:24 +0800 Subject: [PATCH 15/23] test: extra testcase for using same variable in url multiple time --- test/publish.test.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/publish.test.js b/test/publish.test.js index 9411f91a..d4137a60 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -371,3 +371,42 @@ test.serial('Publish a release with an asset link with variable', async t => { t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); + +test.serial('Publish a release with an asset link with same variable multiple time', async t => { + const cwd = 'test/fixtures/files'; + const owner = 'test_user'; + const repo = 'test_repo'; + process.env.repo = 'gitlab'; + const env = {GITLAB_TOKEN: 'gitlab_token'}; + const nextRelease = {gitHead: '123', gitTag: 'v1.0.0', notes: 'Test release note body'}; + const options = {repositoryUrl: `https://gitlab.com/${owner}/${repo}.git`}; + const encodedRepoId = encodeURIComponent(`${owner}/${repo}`); + const encodedGitTag = encodeURIComponent(nextRelease.gitTag); + const link = { + label: 'README.md', + type: 'other', + url: 'https://gitlab.com/${repo}-org/${repo}/-/blob/master/README.md', // eslint-disable-line no-template-curly-in-string + }; + const assets = [link]; + const gitlab = authenticate(env) + .post(`/projects/${encodedRepoId}/releases`, { + tag_name: nextRelease.gitTag, + description: nextRelease.notes, + assets: { + links: [ + { + name: 'README.md', + url: `https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, + link_type: 'other', + }, + ], + }, + }) + .reply(200); + + const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); + + t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`); + t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); + t.true(gitlab.isDone()); +}); From 9c48cbbe3b23b77886feca3396312e615001c5af Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Tue, 26 Apr 2022 17:55:46 +0800 Subject: [PATCH 16/23] test: extra testcase for using multiple variable in one url --- test/publish.test.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/publish.test.js b/test/publish.test.js index d4137a60..de2f3648 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -410,3 +410,43 @@ test.serial('Publish a release with an asset link with same variable multiple ti t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); + +test.serial('Publish a release with an asset link with multiple variable', async t => { + const cwd = 'test/fixtures/files'; + const owner = 'test_user'; + const repo = 'test_repo'; + process.env.repo = 'gitlab'; + process.env.group = 'gitlab-org'; + const env = {GITLAB_TOKEN: 'gitlab_token'}; + const nextRelease = {gitHead: '123', gitTag: 'v1.0.0', notes: 'Test release note body'}; + const options = {repositoryUrl: `https://gitlab.com/${owner}/${repo}.git`}; + const encodedRepoId = encodeURIComponent(`${owner}/${repo}`); + const encodedGitTag = encodeURIComponent(nextRelease.gitTag); + const link = { + label: 'README.md', + type: 'other', + url: 'https://gitlab.com/${group}/${repo}/-/blob/master/README.md', // eslint-disable-line no-template-curly-in-string + }; + const assets = [link]; + const gitlab = authenticate(env) + .post(`/projects/${encodedRepoId}/releases`, { + tag_name: nextRelease.gitTag, + description: nextRelease.notes, + assets: { + links: [ + { + name: 'README.md', + url: `https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, + link_type: 'other', + }, + ], + }, + }) + .reply(200); + + const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); + + t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`); + t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); + t.true(gitlab.isDone()); +}); From 1c15ed2edd2037aad67291e8a4ffd5f209089f4a Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Fri, 29 Apr 2022 08:22:20 +0800 Subject: [PATCH 17/23] test: url variable testcase format update prevent disable eslint --- test/publish.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/publish.test.js b/test/publish.test.js index de2f3648..2291caf5 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -346,7 +346,7 @@ test.serial('Publish a release with an asset link with variable', async t => { const link = { label: 'README.md', type: 'other', - url: 'https://gitlab.com/gitlab-org/${repo}/-/blob/master/README.md', // eslint-disable-line no-template-curly-in-string + url: `https://gitlab.com/gitlab-org/\${repo}/-/blob/master/README.md`, }; const assets = [link]; const gitlab = authenticate(env) @@ -385,7 +385,7 @@ test.serial('Publish a release with an asset link with same variable multiple ti const link = { label: 'README.md', type: 'other', - url: 'https://gitlab.com/${repo}-org/${repo}/-/blob/master/README.md', // eslint-disable-line no-template-curly-in-string + url: `https://gitlab.com/\${repo}-org/\${repo}/-/blob/master/README.md`, }; const assets = [link]; const gitlab = authenticate(env) @@ -425,7 +425,7 @@ test.serial('Publish a release with an asset link with multiple variable', async const link = { label: 'README.md', type: 'other', - url: 'https://gitlab.com/${group}/${repo}/-/blob/master/README.md', // eslint-disable-line no-template-curly-in-string + url: `https://gitlab.com/\${group}/\${repo}/-/blob/master/README.md`, }; const assets = [link]; const gitlab = authenticate(env) From aafa9e24b4455523c7b636f9be72c350e0631d9f Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Thu, 12 May 2022 23:06:21 +0800 Subject: [PATCH 18/23] fix: merge error --- lib/publish.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/publish.js b/lib/publish.js index 0a6f7183..a0e783b2 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -50,7 +50,7 @@ module.exports = async (pluginConfig, context) => { allAssets.map(async (asset) => { const {path, type, filepath} = isPlainObject(asset) ? asset : {path: asset}; const label = asset.label ? template(asset.label)(context) : undefined; - const _url = asset.url; + let _url = asset.url; if (_url) { // Allow loading variable from process.env load CI_JOB_ID for attaching CI artifact const matchedVariables = _url.match(/\${\w+}/g); From acf006dcc1d7f052fe17db75399ef3ea84ddebf6 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Thu, 12 May 2022 23:07:15 +0800 Subject: [PATCH 19/23] test: fix testcase link asset release url compare --- test/publish.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/publish.test.js b/test/publish.test.js index 2291caf5..63215d36 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -328,7 +328,7 @@ test.serial('Publish a release with an asset link', async t => { const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); - t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`); + t.is(result.url, `https://gitlab.com/${owner}/${repo}/-/releases/${encodedGitTag}`); t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); @@ -367,7 +367,7 @@ test.serial('Publish a release with an asset link with variable', async t => { const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); - t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`); + t.is(result.url, `https://gitlab.com/${owner}/${repo}/-/releases/${encodedGitTag}`); t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); @@ -406,7 +406,7 @@ test.serial('Publish a release with an asset link with same variable multiple ti const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); - t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`); + t.is(result.url, `https://gitlab.com/${owner}/${repo}/-/releases/${encodedGitTag}`); t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); @@ -446,7 +446,7 @@ test.serial('Publish a release with an asset link with multiple variable', async const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); - t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`); + t.is(result.url, `https://gitlab.com/${owner}/${repo}/-/releases/${encodedGitTag}`); t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); From 240a7a1f38c161ac59f553e42db73f1ac2856070 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Thu, 12 May 2022 23:10:49 +0800 Subject: [PATCH 20/23] fix: link asset remove variable replacement code --- lib/publish.js | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/lib/publish.js b/lib/publish.js index a0e783b2..e8cce105 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -11,10 +11,6 @@ const getRepoId = require('./get-repo-id'); const getAssets = require('./glob-assets'); const {RELEASE_NAME} = require('./definitions/constants'); -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - module.exports = async (pluginConfig, context) => { const { cwd, @@ -50,19 +46,8 @@ module.exports = async (pluginConfig, context) => { allAssets.map(async (asset) => { const {path, type, filepath} = isPlainObject(asset) ? asset : {path: asset}; const label = asset.label ? template(asset.label)(context) : undefined; - let _url = asset.url; + const _url = asset.url; if (_url) { - // Allow loading variable from process.env load CI_JOB_ID for attaching CI artifact - const matchedVariables = _url.match(/\${\w+}/g); - if (matchedVariables) { - for (const matchedVariable of matchedVariables) { - const variableName = matchedVariable.slice(2, -1); - if (process.env[variableName]) { - _url = _url.replace(new RegExp(escapeRegExp(matchedVariable), 'g'), process.env[variableName]); - } - } - } - assetsList.push({label, rawUrl: _url, type, filepath}); debug('use link from release setting: %s', _url); } else { From b0e27bb320b934e73fe85253f9eda9a6402e43bd Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Thu, 12 May 2022 23:11:20 +0800 Subject: [PATCH 21/23] test: remove link asset variable replacement testcase --- test/publish.test.js | 118 ------------------------------------------- 1 file changed, 118 deletions(-) diff --git a/test/publish.test.js b/test/publish.test.js index 63215d36..92244e82 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -332,121 +332,3 @@ test.serial('Publish a release with an asset link', async t => { t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); t.true(gitlab.isDone()); }); - -test.serial('Publish a release with an asset link with variable', async t => { - const cwd = 'test/fixtures/files'; - const owner = 'test_user'; - const repo = 'test_repo'; - process.env.repo = 'gitlab'; - const env = {GITLAB_TOKEN: 'gitlab_token'}; - const nextRelease = {gitHead: '123', gitTag: 'v1.0.0', notes: 'Test release note body'}; - const options = {repositoryUrl: `https://gitlab.com/${owner}/${repo}.git`}; - const encodedRepoId = encodeURIComponent(`${owner}/${repo}`); - const encodedGitTag = encodeURIComponent(nextRelease.gitTag); - const link = { - label: 'README.md', - type: 'other', - url: `https://gitlab.com/gitlab-org/\${repo}/-/blob/master/README.md`, - }; - const assets = [link]; - const gitlab = authenticate(env) - .post(`/projects/${encodedRepoId}/releases`, { - tag_name: nextRelease.gitTag, - description: nextRelease.notes, - assets: { - links: [ - { - name: 'README.md', - url: `https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, - link_type: 'other', - }, - ], - }, - }) - .reply(200); - - const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); - - t.is(result.url, `https://gitlab.com/${owner}/${repo}/-/releases/${encodedGitTag}`); - t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); - t.true(gitlab.isDone()); -}); - -test.serial('Publish a release with an asset link with same variable multiple time', async t => { - const cwd = 'test/fixtures/files'; - const owner = 'test_user'; - const repo = 'test_repo'; - process.env.repo = 'gitlab'; - const env = {GITLAB_TOKEN: 'gitlab_token'}; - const nextRelease = {gitHead: '123', gitTag: 'v1.0.0', notes: 'Test release note body'}; - const options = {repositoryUrl: `https://gitlab.com/${owner}/${repo}.git`}; - const encodedRepoId = encodeURIComponent(`${owner}/${repo}`); - const encodedGitTag = encodeURIComponent(nextRelease.gitTag); - const link = { - label: 'README.md', - type: 'other', - url: `https://gitlab.com/\${repo}-org/\${repo}/-/blob/master/README.md`, - }; - const assets = [link]; - const gitlab = authenticate(env) - .post(`/projects/${encodedRepoId}/releases`, { - tag_name: nextRelease.gitTag, - description: nextRelease.notes, - assets: { - links: [ - { - name: 'README.md', - url: `https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, - link_type: 'other', - }, - ], - }, - }) - .reply(200); - - const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); - - t.is(result.url, `https://gitlab.com/${owner}/${repo}/-/releases/${encodedGitTag}`); - t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); - t.true(gitlab.isDone()); -}); - -test.serial('Publish a release with an asset link with multiple variable', async t => { - const cwd = 'test/fixtures/files'; - const owner = 'test_user'; - const repo = 'test_repo'; - process.env.repo = 'gitlab'; - process.env.group = 'gitlab-org'; - const env = {GITLAB_TOKEN: 'gitlab_token'}; - const nextRelease = {gitHead: '123', gitTag: 'v1.0.0', notes: 'Test release note body'}; - const options = {repositoryUrl: `https://gitlab.com/${owner}/${repo}.git`}; - const encodedRepoId = encodeURIComponent(`${owner}/${repo}`); - const encodedGitTag = encodeURIComponent(nextRelease.gitTag); - const link = { - label: 'README.md', - type: 'other', - url: `https://gitlab.com/\${group}/\${repo}/-/blob/master/README.md`, - }; - const assets = [link]; - const gitlab = authenticate(env) - .post(`/projects/${encodedRepoId}/releases`, { - tag_name: nextRelease.gitTag, - description: nextRelease.notes, - assets: { - links: [ - { - name: 'README.md', - url: `https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md`, - link_type: 'other', - }, - ], - }, - }) - .reply(200); - - const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger}); - - t.is(result.url, `https://gitlab.com/${owner}/${repo}/-/releases/${encodedGitTag}`); - t.deepEqual(t.context.log.args[0], ['Published GitLab release: %s', nextRelease.gitTag]); - t.true(gitlab.isDone()); -}); From 868f303d2c7a8ecec53e023792bc182f7ea31e49 Mon Sep 17 00:00:00 2001 From: Jack Chan Date: Fri, 13 May 2022 13:16:15 +0800 Subject: [PATCH 22/23] style: lint link asset code --- lib/publish.js | 6 +++--- test/publish.test.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/publish.js b/lib/publish.js index e8cce105..eb2c408a 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -32,11 +32,11 @@ module.exports = async (pluginConfig, context) => { if (assets && assets.length > 0) { // Skip glob if url is provided - const urlAssets = assets.filter(asset => asset.url); + const urlAssets = assets.filter((asset) => asset.url); debug('url assets: %o', urlAssets); const globbedAssets = await getAssets( context, - assets.filter(asset => !asset.url) + assets.filter((asset) => !asset.url) ); debug('globbed assets: %o', globbedAssets); const allAssets = [...urlAssets, ...globbedAssets]; @@ -82,7 +82,7 @@ module.exports = async (pluginConfig, context) => { let response; try { - response = await got.post(uploadEndpoint, { ...apiOptions, ...proxy, body: form }).json(); + response = await got.post(uploadEndpoint, {...apiOptions, ...proxy, body: form}).json(); } catch (error) { logger.error('An error occurred while uploading %s to the GitLab project uploads API:\n%O', file, error); throw error; diff --git a/test/publish.test.js b/test/publish.test.js index 92244e82..2fa7d98b 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -295,7 +295,7 @@ test.serial('Publish a release with missing release notes', async (t) => { t.true(gitlab.isDone()); }); -test.serial('Publish a release with an asset link', async t => { +test.serial('Publish a release with an asset link', async (t) => { const cwd = 'test/fixtures/files'; const owner = 'test_user'; const repo = 'test_repo'; From 9ec0365c10263890494cacd064f1ed1fd51cfa86 Mon Sep 17 00:00:00 2001 From: Florian Greinacher Date: Mon, 16 May 2022 10:24:06 +0200 Subject: [PATCH 23/23] docs: simplify option description --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9620883a..38830f9d 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,8 @@ Can be a [glob](https://github.com/isaacs/node-glob#glob-primer) or and `Array` | Property | Description | Default | | -------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `path` | **path or url is required.** A [glob](https://github.com/isaacs/node-glob#glob-primer) to identify the files to upload. | - | -| `url` | **path or url is required.** This provides the ability to add links to releases. E.g. URLs to container images. | - | +| `path` | **Required**, unless `url` is set. A [glob](https://github.com/isaacs/node-glob#glob-primer) to identify the files to upload. | - | +| `url` | Alternative to setting `path` this provides the ability to add links to releases, e.g. URLs to container images. | - | | `label` | Short description of the file displayed on the GitLab release. Can be dynamically adjusted with [Lodash template](https://lodash.com/docs#template). Allows same variables as [`successComment`](#successComment). Ignored if `path` matches more than one file. | File name extracted from the `path`. | | `type` | Asset type displayed on the GitLab release. Can be `runbook`, `package`, `image` and `other` (see official documents on [release assets](https://docs.gitlab.com/ee/user/project/releases/#release-assets)). | `other` | | `filepath` | A filepath for creating a permalink pointing to the asset (requires GitLab 12.9+, see official documents on [permanent links](https://docs.gitlab.com/ee/user/project/releases/#permanent-links-to-release-assets)). Ignored if `path` matches more than one file. | - |