Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ Can be a [glob](https://github.com/isaacs/node-glob#glob-primer) or and `Array`
| `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)
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