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
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,16 @@ If you need to bypass the proxy for some hosts, configure the `NO_PROXY` environ
Can be a [glob](https://github.com/isaacs/node-glob#glob-primer) or and `Array` of
[globs](https://github.com/isaacs/node-glob#glob-primer) and `Object`s with the following properties:

| Property | Description | Default |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `path` | **Required**, unless `url` is set. A [glob](https://github.com/isaacs/node-glob#glob-primer) to identify the files to upload. Supports [Lodash templating](https://lodash.com/docs#template). | - |
| `url` | Alternative to setting `path` this provides the ability to add links to releases, e.g. URLs to container images. Supports [Lodash templating](https://lodash.com/docs#template). | - |
| `label` | Short description of the file displayed on the GitLab release. Ignored if `path` matches more than one file. Supports [Lodash templating](https://lodash.com/docs#template). | 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 [link types](https://docs.gitlab.com/user/project/releases/release_fields/#link-types)). Supports [Lodash templating](https://lodash.com/docs#template). | `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/user/project/releases/release_fields/#permanent-links-to-release-assets)). Ignored if `path` matches more than one file. Supports [Lodash templating](https://lodash.com/docs#template). | - |
| `target` | Controls where the file is uploaded to. Can be set to `project_upload` for storing the file as [project upload](https://docs.gitlab.com/api/project_markdown_uploads/#upload-a-file) or `generic_package` for storing the file as [generic package](https://docs.gitlab.com/user/packages/generic_packages/). | `project_upload` |
| `status` | This is only applied, if `target` is set to `generic_package`. The generic package status. Can be `default` and `hidden` (see official documents on [generic packages](https://docs.gitlab.com/user/packages/generic_packages/)). | `default` |
| Property | Description | Default |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `path` | **Required**, unless `url` is set. A [glob](https://github.com/isaacs/node-glob#glob-primer) to identify the files to upload. Supports [Lodash templating](https://lodash.com/docs#template). | - |
| `url` | Alternative to setting `path` this provides the ability to add links to releases, e.g. URLs to container images. Supports [Lodash templating](https://lodash.com/docs#template). | - |
| `label` | Short description of the file displayed on the GitLab release. Ignored if `path` matches more than one file. Supports [Lodash templating](https://lodash.com/docs#template). | 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 [link types](https://docs.gitlab.com/user/project/releases/release_fields/#link-types)). Supports [Lodash templating](https://lodash.com/docs#template). | `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/user/project/releases/release_fields/#permanent-links-to-release-assets)). Ignored if `path` matches more than one file. Supports [Lodash templating](https://lodash.com/docs#template). | - |
| `target` | Controls where the file is uploaded to. Can be set to `project_upload` for storing the file as [project upload](https://docs.gitlab.com/api/project_markdown_uploads/#upload-a-file) or `generic_package` for storing the file as [generic package](https://docs.gitlab.com/user/packages/generic_packages/). | `project_upload` |
| `packageName` | This is only applied if `target` is set to `generic_package`. It defines the package name (`:package_name`) to upload asset file to. More information could be found at [Publish a package](https://docs.gitlab.com/user/packages/generic_packages/#publish-a-package) | `release` |
| `status` | This is only applied, if `target` is set to `generic_package`. The generic package status. Can be `default` and `hidden` (see official documents on [generic packages](https://docs.gitlab.com/user/packages/generic_packages/)). | `default` |

Each entry in the `assets` `Array` is globbed individually. A [glob](https://github.com/isaacs/node-glob#glob-primer)
can be a `String` (`"dist/**/*.js"` or `"dist/mylib.js"`) or an `Array` of `String`s that will be globbed together
Expand Down
14 changes: 10 additions & 4 deletions lib/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default async (pluginConfig, context) => {
const { projectPath, projectApiUrl } = getProjectContext(context, gitlabUrl, gitlabApiUrl, repositoryUrl);

const encodedGitTag = encodeURIComponent(gitTag);
const encodedVersion = encodeURIComponent(version);
const apiOptions = {
headers: {
"PRIVATE-TOKEN": gitlabToken,
Expand Down Expand Up @@ -76,6 +75,7 @@ export default async (pluginConfig, context) => {
const filepath = asset.filepath ? template(asset.filepath)(context) : undefined;
const target = asset.target ? template(asset.target)(context) : undefined;
const status = asset.status ? template(asset.status)(context) : undefined;
const packageName = asset.packageName ? template(asset.packageName)(context) : "release";

if (_url) {
assetsList.push({ label, rawUrl: _url, type, filepath });
Expand Down Expand Up @@ -103,18 +103,21 @@ export default async (pluginConfig, context) => {
debug("file filepath: %o", filepath);
debug("file target: %o", target);
debug("file status: %o", status);
debug("package name: %o", packageName);

let uploadEndpoint;
let response;

if (target === "generic_package") {
const finalLabel = label ?? pathlib.basename(file);
// Upload generic packages
const encodedVersion = encodeURIComponent(version);
const encodedPackageName = encodeURIComponent(packageName);
const encodedLabel = encodeURIComponent(finalLabel);
// https://docs.gitlab.com/ee/user/packages/generic_packages/#publish-a-package-file
uploadEndpoint = urlJoin(
projectApiUrl,
`packages/generic/release/${encodedVersion}/${encodedLabel}?${
`packages/generic/${encodedPackageName}/${encodedVersion}/${encodedLabel}?${
status ? `status=${status}&` : ""
}select=package_file`
);
Expand All @@ -129,9 +132,12 @@ export default async (pluginConfig, context) => {
}

// https://docs.gitlab.com/ee/user/packages/generic_packages/#download-package-file
const url = urlJoin(projectApiUrl, `packages/generic/release/${encodedVersion}/${encodedLabel}`);
const url = urlJoin(
projectApiUrl,
`packages/generic/${encodedPackageName}/${encodedVersion}/${encodedLabel}`
);

assetsList.push({ label: finalLabel, alt: "release", url, type: "package", filepath });
assetsList.push({ label: finalLabel, alt: packageName, url, type: "package", filepath });

logger.log("Uploaded file: %s (%s)", url, response.file.url);
} else {
Expand Down
111 changes: 111 additions & 0 deletions test/publish.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,117 @@ test.serial("Publish a release with generics", async (t) => {
t.true(gitlab.isDone());
});

test.serial("Publish a release with generics: with asset.packageName (fixed text)", 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", version: "1.0.0" };
const options = { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` };
const encodedProjectPath = encodeURIComponent(`${owner}/${repo}`);
const encodedGitTag = encodeURIComponent(nextRelease.gitTag);
const encodedVersion = encodeURIComponent(nextRelease.version);
const uploaded = { file: { url: "/uploads/file.css" } };
const generic = {
path: "file.css",
label: "Style package",
target: "generic_package",
status: "hidden",
packageName: "microk8s",
};
const assets = [generic];
const encodedLabel = encodeURIComponent(generic.label);
const encodedPackageName = encodeURIComponent(generic.packageName);
const expectedUrl = `https://gitlab.com/api/v4/projects/${encodedProjectPath}/packages/generic/${encodedPackageName}/${encodedVersion}/${encodedLabel}`;
const gitlab = authenticate(env)
.post(`/projects/${encodedProjectPath}/releases`, {
tag_name: nextRelease.gitTag,
description: nextRelease.notes,
assets: {
links: [
{
name: "Style package",
url: expectedUrl,
link_type: "package",
},
],
},
})
.reply(200);
const gitlabUpload = authenticate(env)
.put(
`/projects/${encodedProjectPath}/packages/generic/${encodedPackageName}/${encodedVersion}/${encodedLabel}?status=${generic.status}&select=package_file`,
/\.test\s\{\}/gm
)
.reply(200, uploaded);

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], ["Uploaded file: %s (%s)", expectedUrl, uploaded.file.url]);
t.deepEqual(t.context.log.args[1], ["Published GitLab release: %s", nextRelease.gitTag]);
t.true(gitlabUpload.isDone());
t.true(gitlab.isDone());
});

test.serial("Publish a release with generics: with asset.packageName (template)", 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-alpha.1",
notes: "Test release note body",
version: "1.0.0-alpha.1",
channel: "alpha",
};
const options = { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` };
const encodedProjectPath = encodeURIComponent(`${owner}/${repo}`);
const encodedGitTag = encodeURIComponent(nextRelease.gitTag);
const encodedVersion = encodeURIComponent(nextRelease.version);
const uploaded = { file: { url: "/uploads/file.css" } };
const generic = {
path: "file.css",
label: "Style package",
target: "generic_package",
status: "hidden",
packageName: "${nextRelease.channel}",
};
const assets = [generic];
const encodedLabel = encodeURIComponent(generic.label);
const expectedUrl = `https://gitlab.com/api/v4/projects/${encodedProjectPath}/packages/generic/alpha/${encodedVersion}/${encodedLabel}`;
const gitlab = authenticate(env)
.post(`/projects/${encodedProjectPath}/releases`, {
tag_name: nextRelease.gitTag,
description: nextRelease.notes,
assets: {
links: [
{
name: "Style package",
url: expectedUrl,
link_type: "package",
},
],
},
})
.reply(200);
const gitlabUpload = authenticate(env)
.put(
`/projects/${encodedProjectPath}/packages/generic/alpha/${encodedVersion}/${encodedLabel}?status=${generic.status}&select=package_file`,
/\.test\s\{\}/gm
)
.reply(200, uploaded);

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], ["Uploaded file: %s (%s)", expectedUrl, uploaded.file.url]);
t.deepEqual(t.context.log.args[1], ["Published GitLab release: %s", nextRelease.gitTag]);
t.true(gitlabUpload.isDone());
t.true(gitlab.isDone());
});

test.serial("Publish a release with generics (without label - issue #823)", async (t) => {
const cwd = "test/fixtures/files";
const owner = "test_user";
Expand Down
Loading