Skip to content

Commit 77dc201

Browse files
yxonicNathan Friend
andauthored
feat: support asset type and filepath (#242)
* feat: support asset permalink * fix: link_type default to undefined and fix test * fix: ignore filepath when uploading multiple assets Co-authored-by: Nathan Friend <[email protected]>
1 parent f85e388 commit 77dc201

File tree

5 files changed

+74
-6
lines changed

5 files changed

+74
-6
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ Can be a [glob](https://github.com/isaacs/node-glob#glob-primer) or and `Array`
7474
| -------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------ |
7575
| `path` | **Required.** A [glob](https://github.com/isaacs/node-glob#glob-primer) to identify the files to upload. | - |
7676
| `label` | Short description of the file displayed on the GitLab release. Ignored if `path` matches more than one file.| File name extracted from the `path`. |
77+
| `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` |
78+
| `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. | - |
7779

7880
Each entry in the `assets` `Array` is globbed individually. A [glob](https://github.com/isaacs/node-glob#glob-primer)
7981
can be a `String` (`"dist/**/*.js"` or `"dist/mylib.js"`) or an `Array` of `String`s that will be globbed together

lib/glob-assets.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ module.exports = async ({cwd}, assets) =>
3939
// Output an Object definition for each file matched and set each one with:
4040
// - `path` of the matched file
4141
// - `label` based on the actual file name (to avoid assets with duplicate `label`s)
42+
// - `filepath` ignored (also to avoid duplicates)
4243
// - other properties of the original asset definition
43-
return globbed.map(file => ({...asset, path: file, label: basename(file)}));
44+
const {filepath, ...others} = asset;
45+
return globbed.map(file => ({...others, path: file, label: basename(file)}));
4446
}
4547

4648
// If asset is an Object, output an Object definition with:

lib/publish.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ module.exports = async (pluginConfig, context) => {
3535

3636
await Promise.all(
3737
globbedAssets.map(async asset => {
38-
const {path, label} = isPlainObject(asset) ? asset : {path: asset};
38+
const {path, label, type, filepath} = isPlainObject(asset) ? asset : {path: asset};
3939
const file = resolve(cwd, path);
4040
let fileStat;
4141

@@ -53,6 +53,8 @@ module.exports = async (pluginConfig, context) => {
5353

5454
debug('file path: %o', path);
5555
debug('file label: %o', label);
56+
debug('file type: %o', type);
57+
debug('file filepath: %o', filepath);
5658

5759
// Uploaded assets to the project
5860
const form = new FormData();
@@ -61,7 +63,7 @@ module.exports = async (pluginConfig, context) => {
6163
.post(urlJoin(gitlabApiUrl, `/projects/${encodedRepoId}/uploads`), {...apiOptions, body: form})
6264
.json();
6365

64-
assetsList.push({label, alt, url});
66+
assetsList.push({label, alt, url, type, filepath});
6567

6668
logger.log('Uploaded file: %s', url);
6769
})
@@ -77,10 +79,12 @@ module.exports = async (pluginConfig, context) => {
7779
description: notes && notes.trim() ? notes : gitTag,
7880
milestones,
7981
assets: {
80-
links: assetsList.map(({label, alt, url}) => {
82+
links: assetsList.map(({label, alt, url, type, filepath}) => {
8183
return {
8284
name: label || alt,
8385
url: urlJoin(gitlabUrl, repoId, url),
86+
link_type: type,
87+
filepath,
8488
};
8589
}),
8690
},

test/glob-assets.test.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ test('Favor Object over String values when removing duplicates', async t => {
7070
'upload.txt',
7171
{path: 'upload.txt', name: 'upload_name'},
7272
'upload.txt',
73-
{path: 'upload_other.txt', name: 'upload_other_name'},
73+
{path: 'upload_other.txt', name: 'upload_other_name', filepath: '/path/to/other'},
7474
'upload.txt',
7575
'upload_other.txt',
7676
]);
@@ -79,7 +79,7 @@ test('Favor Object over String values when removing duplicates', async t => {
7979
sortAssets(globbedAssets),
8080
sortAssets([
8181
{path: 'upload.txt', name: 'upload_name'},
82-
{path: 'upload_other.txt', name: 'upload_other_name'},
82+
{path: 'upload_other.txt', name: 'upload_other_name', filepath: '/path/to/other'},
8383
])
8484
);
8585
});
@@ -138,6 +138,20 @@ test('Replace name by filename for Object that match multiple files', async t =>
138138
);
139139
});
140140

141+
test('Ignore filepath for Object that match multiple files', async t => {
142+
const cwd = tempy.directory();
143+
await copy(fixtures, cwd);
144+
const globbedAssets = await globAssets({cwd}, [{path: '*.txt', filepath: '/path/to/file'}]);
145+
146+
t.deepEqual(
147+
sortAssets(globbedAssets),
148+
sortAssets([
149+
{path: 'upload.txt', label: 'upload.txt'},
150+
{path: 'upload_other.txt', label: 'upload_other.txt'},
151+
])
152+
);
153+
});
154+
141155
test('Include dotfiles', async t => {
142156
const cwd = tempy.directory();
143157
await copy(fixtures, cwd);

test/publish.test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,52 @@ test.serial('Publish a release with assets', async t => {
8383
t.true(gitlab.isDone());
8484
});
8585

86+
test.serial('Publish a release with asset type and permalink', async t => {
87+
const cwd = 'test/fixtures/files';
88+
const owner = 'test_user';
89+
const repo = 'test_repo';
90+
const env = {GITLAB_TOKEN: 'gitlab_token'};
91+
const nextRelease = {gitHead: '123', gitTag: 'v1.0.0', notes: 'Test release note body'};
92+
const options = {repositoryUrl: `https://gitlab.com/${owner}/${repo}.git`};
93+
const encodedRepoId = encodeURIComponent(`${owner}/${repo}`);
94+
const encodedGitTag = encodeURIComponent(nextRelease.gitTag);
95+
const uploaded = {url: '/uploads/file.css', alt: 'file.css', link_type: 'package', filepath: '/dist/file.css'};
96+
const assets = [
97+
{
98+
path: ['**', '!**/*.txt', '!.dotfile'],
99+
type: 'package',
100+
filepath: '/dist/file.css',
101+
},
102+
];
103+
const gitlab = authenticate(env)
104+
.post(`/projects/${encodedRepoId}/releases`, {
105+
tag_name: nextRelease.gitTag,
106+
description: nextRelease.notes,
107+
assets: {
108+
links: [
109+
{
110+
name: uploaded.alt,
111+
url: `https://gitlab.com/${owner}/${repo}${uploaded.url}`,
112+
link_type: uploaded.link_type,
113+
filepath: uploaded.filepath,
114+
},
115+
],
116+
},
117+
})
118+
.reply(200);
119+
const gitlabUpload = authenticate(env)
120+
.post(`/projects/${encodedRepoId}/uploads`, /filename="file.css"/gm)
121+
.reply(200, uploaded);
122+
123+
const result = await publish({assets}, {env, cwd, options, nextRelease, logger: t.context.logger});
124+
125+
t.is(result.url, `https://gitlab.com/${encodedRepoId}/-/releases/${encodedGitTag}`);
126+
t.deepEqual(t.context.log.args[0], ['Uploaded file: %s', uploaded.url]);
127+
t.deepEqual(t.context.log.args[1], ['Published GitLab release: %s', nextRelease.gitTag]);
128+
t.true(gitlabUpload.isDone());
129+
t.true(gitlab.isDone());
130+
});
131+
86132
test.serial('Publish a release with a milestone', async t => {
87133
const owner = 'test_user';
88134
const repo = 'test_repo';

0 commit comments

Comments
 (0)