Skip to content

Commit 54399c9

Browse files
mcharrisMichael Link
and
Michael Link
authoredDec 17, 2024··
GitLab Generic Package Repository for assets (#1189)
* Add option to use generic package repository * Added name * some debugging messages * need projectId * okthen * actually use the id * added check on fail. * uploading wrong * remove setting id * remove manifest for testing * Cleanup and test * Cleaned up and setup tests --------- Co-authored-by: Michael Link <michael@thelink.family>
1 parent 04a36d2 commit 54399c9

File tree

7 files changed

+108
-19
lines changed

7 files changed

+108
-19
lines changed
 

‎config/release-it.json

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
"secure": null,
6767
"assets": null,
6868
"useIdsForUrls": false,
69+
"useGenericPackageRepositoryForAssets": false,
70+
"genericPackageRepositoryName": "release-it",
6971
"origin": null,
7072
"skipChecks": false
7173
}

‎docs/gitlab-releases.md

+15
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,21 @@ later), you should set the `useIdsForUrls` flag to `true`:
118118
}
119119
```
120120

121+
### Asset Location
122+
123+
By default release assets are uploaded to the project's Markdown uploads API. If you want to use GitLab's Generic packages Repository set `useGenericPackageRepositoryForAssets` flag to true. `useIdsForUrls` is ignored from this API. You can set the package name to be uploaded to using `genericPackageRepositoryName` by default the name is `release-it`.
124+
125+
```json
126+
{
127+
"gitlab": {
128+
"release": true,
129+
"useGenericPackageRepositoryForAssets": true,
130+
"genericPackageRepositoryName": "release-it",
131+
"assets": ["dist/*.dmg"]
132+
}
133+
}
134+
```
135+
121136
## Origin
122137

123138
The `origin` can be set to a string such as `"http://example.org:3000"` to use a different origin from what would be

‎lib/plugin/gitlab/GitLab.js

+41-19
Original file line numberDiff line numberDiff line change
@@ -257,25 +257,47 @@ class GitLab extends Release {
257257

258258
async uploadAsset(filePath) {
259259
const name = path.basename(filePath);
260-
const { useIdsForUrls } = this.options;
261-
const { id, origin, repo } = this.getContext();
262-
const endpoint = `projects/${id}/uploads`;
263-
264-
const body = new FormData();
265-
const rawData = await fs.promises.readFile(filePath);
266-
body.set('file', new Blob([rawData]), name);
267-
const options = { body };
268-
269-
try {
270-
const body = await this.request(endpoint, options);
271-
this.log.verbose(`gitlab releases#uploadAsset: done (${body.url})`);
272-
this.assets.push({
273-
name,
274-
url: useIdsForUrls ? `${origin}${body.full_path}` : `${origin}/${repo.repository}${body.url}`
275-
});
276-
} catch (err) {
277-
this.debug(err);
278-
throw err;
260+
const { useIdsForUrls, useGenericPackageRepositoryForAssets, genericPackageRepositoryName } = this.options;
261+
const { id, origin, repo, version, baseUrl } = this.getContext();
262+
const endpoint = useGenericPackageRepositoryForAssets
263+
? `projects/${id}/packages/generic/${genericPackageRepositoryName}/${version}/${name}`
264+
: `projects/${id}/uploads`;
265+
if (useGenericPackageRepositoryForAssets) {
266+
const options = {
267+
method: 'PUT',
268+
body: await fs.promises.readFile(filePath)
269+
};
270+
try {
271+
const body = await this.request(endpoint, options);
272+
if (!(body.message && body.message == '201 Created')) {
273+
throw new Error(`GitLab asset upload failed`);
274+
}
275+
this.log.verbose(`gitlab releases#uploadAsset: done (${endpoint})`);
276+
this.assets.push({
277+
name,
278+
url: `${baseUrl}/${endpoint}`
279+
});
280+
} catch (err) {
281+
this.debug(err);
282+
throw err;
283+
}
284+
} else {
285+
const body = new FormData();
286+
const rawData = await fs.promises.readFile(filePath);
287+
body.set('file', new Blob([rawData]), name);
288+
const options = { body };
289+
290+
try {
291+
const body = await this.request(endpoint, options);
292+
this.log.verbose(`gitlab releases#uploadAsset: done (${body.url})`);
293+
this.assets.push({
294+
name,
295+
url: useIdsForUrls ? `${origin}${body.full_path}` : `${origin}/${repo.repository}${body.url}`
296+
});
297+
} catch (err) {
298+
this.debug(err);
299+
throw err;
300+
}
279301
}
280302
}
281303

‎schema/gitlab.json

+8
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@
5656
"type": "boolean",
5757
"default": false
5858
},
59+
"useGenericPackageRepositoryForAssets": {
60+
"type": "boolean",
61+
"default": false
62+
},
63+
"genericPackageRepositoryName": {
64+
"type": "string",
65+
"default": "release-it"
66+
},
5967
"origin": {
6068
"type": "string",
6169
"default": null

‎test/gitlab.js

+27
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
interceptCollaborator,
1111
interceptPublish,
1212
interceptAsset,
13+
interceptAssetGeneric,
1314
interceptMilestones
1415
} from './stub/gitlab.js';
1516

@@ -142,6 +143,32 @@ test.serial('should upload assets with ID-based URLs too', async t => {
142143
t.is(gitlab.assets[0].url, `${host}/-/project/1234/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/file-v2.0.1.txt`);
143144
});
144145

146+
test.serial('should upload assets to generic repo', async t => {
147+
const host = 'https://gitlab.com';
148+
const pushRepo = `${host}/user/repo`;
149+
const options = {
150+
git: { pushRepo },
151+
gitlab: {
152+
tokenRef,
153+
release: true,
154+
assets: 'test/resources/file-v${version}.txt',
155+
useGenericPackageRepositoryForAssets: true,
156+
genericPackageRepositoryName: 'release-it'
157+
}
158+
};
159+
const gitlab = factory(GitLab, { options });
160+
sinon.stub(gitlab, 'getLatestVersion').resolves('2.0.0');
161+
162+
interceptUser();
163+
interceptCollaborator();
164+
interceptAssetGeneric();
165+
interceptPublish();
166+
167+
await runTasks(gitlab);
168+
169+
t.is(gitlab.assets[0].url, `${host}/api/v4/projects/user%2Frepo/packages/generic/release-it/2.0.1/file-v2.0.1.txt`);
170+
});
171+
145172
test.serial('should throw when release milestone is missing', async t => {
146173
const pushRepo = 'https://gitlab.com/user/repo';
147174
const options = {

‎test/stub/gitlab.js

+9
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,12 @@ export let interceptAsset = ({ host = 'https://gitlab.com', owner = 'user', proj
5252
}
5353
};
5454
});
55+
56+
export let interceptAssetGeneric = ({ host = 'https://gitlab.com', owner = 'user', project = 'repo' } = {}) =>
57+
nock(host)
58+
.put(`/api/v4/projects/${owner}%2F${project}/packages/generic/release-it/2.0.1/file-v2.0.1.txt`)
59+
.reply(200, () => {
60+
return {
61+
message: '201 Created'
62+
};
63+
});

‎types/config.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@ export interface Config {
190190
/** @default false */
191191
useIdsForUrls?: boolean;
192192

193+
/** @default false */
194+
useGenericPackageRepositoryForAssets?: boolean;
195+
196+
/** @default "release-it" */
197+
genericPackageRepositoryName?: string;
198+
193199
/** @default null */
194200
origin?: any;
195201

0 commit comments

Comments
 (0)
Please sign in to comment.