Skip to content

Commit

Permalink
GitLab Generic Package Repository for assets (#1189)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
mcharris and Michael Link authored Dec 17, 2024
1 parent 04a36d2 commit 54399c9
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 19 deletions.
2 changes: 2 additions & 0 deletions config/release-it.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
"secure": null,
"assets": null,
"useIdsForUrls": false,
"useGenericPackageRepositoryForAssets": false,
"genericPackageRepositoryName": "release-it",
"origin": null,
"skipChecks": false
}
Expand Down
15 changes: 15 additions & 0 deletions docs/gitlab-releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,21 @@ later), you should set the `useIdsForUrls` flag to `true`:
}
```

### Asset Location

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`.

```json
{
"gitlab": {
"release": true,
"useGenericPackageRepositoryForAssets": true,
"genericPackageRepositoryName": "release-it",
"assets": ["dist/*.dmg"]
}
}
```

## Origin

The `origin` can be set to a string such as `"http://example.org:3000"` to use a different origin from what would be
Expand Down
60 changes: 41 additions & 19 deletions lib/plugin/gitlab/GitLab.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,25 +257,47 @@ class GitLab extends Release {

async uploadAsset(filePath) {
const name = path.basename(filePath);
const { useIdsForUrls } = this.options;
const { id, origin, repo } = this.getContext();
const endpoint = `projects/${id}/uploads`;

const body = new FormData();
const rawData = await fs.promises.readFile(filePath);
body.set('file', new Blob([rawData]), name);
const options = { body };

try {
const body = await this.request(endpoint, options);
this.log.verbose(`gitlab releases#uploadAsset: done (${body.url})`);
this.assets.push({
name,
url: useIdsForUrls ? `${origin}${body.full_path}` : `${origin}/${repo.repository}${body.url}`
});
} catch (err) {
this.debug(err);
throw err;
const { useIdsForUrls, useGenericPackageRepositoryForAssets, genericPackageRepositoryName } = this.options;
const { id, origin, repo, version, baseUrl } = this.getContext();
const endpoint = useGenericPackageRepositoryForAssets
? `projects/${id}/packages/generic/${genericPackageRepositoryName}/${version}/${name}`
: `projects/${id}/uploads`;
if (useGenericPackageRepositoryForAssets) {
const options = {
method: 'PUT',
body: await fs.promises.readFile(filePath)
};
try {
const body = await this.request(endpoint, options);
if (!(body.message && body.message == '201 Created')) {
throw new Error(`GitLab asset upload failed`);
}
this.log.verbose(`gitlab releases#uploadAsset: done (${endpoint})`);
this.assets.push({
name,
url: `${baseUrl}/${endpoint}`
});
} catch (err) {
this.debug(err);
throw err;
}
} else {
const body = new FormData();
const rawData = await fs.promises.readFile(filePath);
body.set('file', new Blob([rawData]), name);
const options = { body };

try {
const body = await this.request(endpoint, options);
this.log.verbose(`gitlab releases#uploadAsset: done (${body.url})`);
this.assets.push({
name,
url: useIdsForUrls ? `${origin}${body.full_path}` : `${origin}/${repo.repository}${body.url}`
});
} catch (err) {
this.debug(err);
throw err;
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions schema/gitlab.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@
"type": "boolean",
"default": false
},
"useGenericPackageRepositoryForAssets": {
"type": "boolean",
"default": false
},
"genericPackageRepositoryName": {
"type": "string",
"default": "release-it"
},
"origin": {
"type": "string",
"default": null
Expand Down
27 changes: 27 additions & 0 deletions test/gitlab.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
interceptCollaborator,
interceptPublish,
interceptAsset,
interceptAssetGeneric,
interceptMilestones
} from './stub/gitlab.js';

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

test.serial('should upload assets to generic repo', async t => {
const host = 'https://gitlab.com';
const pushRepo = `${host}/user/repo`;
const options = {
git: { pushRepo },
gitlab: {
tokenRef,
release: true,
assets: 'test/resources/file-v${version}.txt',
useGenericPackageRepositoryForAssets: true,
genericPackageRepositoryName: 'release-it'
}
};
const gitlab = factory(GitLab, { options });
sinon.stub(gitlab, 'getLatestVersion').resolves('2.0.0');

interceptUser();
interceptCollaborator();
interceptAssetGeneric();
interceptPublish();

await runTasks(gitlab);

t.is(gitlab.assets[0].url, `${host}/api/v4/projects/user%2Frepo/packages/generic/release-it/2.0.1/file-v2.0.1.txt`);
});

test.serial('should throw when release milestone is missing', async t => {
const pushRepo = 'https://gitlab.com/user/repo';
const options = {
Expand Down
9 changes: 9 additions & 0 deletions test/stub/gitlab.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,12 @@ export let interceptAsset = ({ host = 'https://gitlab.com', owner = 'user', proj
}
};
});

export let interceptAssetGeneric = ({ host = 'https://gitlab.com', owner = 'user', project = 'repo' } = {}) =>
nock(host)
.put(`/api/v4/projects/${owner}%2F${project}/packages/generic/release-it/2.0.1/file-v2.0.1.txt`)
.reply(200, () => {
return {
message: '201 Created'
};
});
6 changes: 6 additions & 0 deletions types/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ export interface Config {
/** @default false */
useIdsForUrls?: boolean;

/** @default false */
useGenericPackageRepositoryForAssets?: boolean;

/** @default "release-it" */
genericPackageRepositoryName?: string;

/** @default null */
origin?: any;

Expand Down

0 comments on commit 54399c9

Please sign in to comment.