Skip to content

fix: allow custom package name when uploading generic_package assets #607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
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 [release assets](https://docs.gitlab.com/ee/user/project/releases/#release-assets)). 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/ee/user/project/releases/#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/ee/api/projects.html#upload-a-file) or `generic_package` for storing the file as [generic package](https://docs.gitlab.com/ee/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/ee/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 [release assets](https://docs.gitlab.com/ee/user/project/releases/#release-assets)). 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/ee/user/project/releases/#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/ee/api/projects.html#upload-a-file) or `generic_package` for storing the file as [generic package](https://docs.gitlab.com/ee/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/ee/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,17 +103,20 @@ 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") {
// Upload generic packages
const encodedVersion = encodeURIComponent(version);
const encodedPackageName = encodeURIComponent(packageName);
const encodedLabel = encodeURIComponent(label);
// 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 @@ -128,9 +131,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, alt: "release", url, type: "package", filepath });
assetsList.push({ label, alt: packageName, url, type: "package", filepath });

logger.log("Uploaded file: %s (%s)", url, response.file.url);
} else {
Expand Down
102 changes: 102 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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 and external storage provider (http)", async (t) => {
const cwd = "test/fixtures/files";
const owner = "test_user";
Expand Down