Skip to content

fix: added support for generic package name #879

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 6 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
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ The plugin can be configured in the [**semantic-release** configuration file](ht
"assets": [
{ "path": "dist/asset.min.css", "label": "CSS distribution" },
{ "path": "dist/asset.min.js", "label": "JS distribution", "target": "generic_package" },
{ "path": "file.css", "label": "Style package", "target": "generic_package", "packageName": "styles" },
{ "path": "dist/asset.min.js", "label": "v${nextRelease.version}.js" },
{ "url": "https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md", "label": "README.md" }
]
Expand Down Expand Up @@ -102,15 +103,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` | The name of the [generic package](https://docs.gitlab.com/ee/user/packages/generic_packages/) uploaded to the Gitlab package registry. Supports [Lodash templating](https://lodash.com/docs#template). | `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
4 changes: 2 additions & 2 deletions lib/definitions/constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const HOME_URL = 'https://github.com/semantic-release/semantic-release';
export const HOME_URL = "https://github.com/semantic-release/semantic-release";

export const RELEASE_NAME = 'GitLab release';
export const RELEASE_NAME = "GitLab release";
62 changes: 31 additions & 31 deletions lib/definitions/errors.js
Original file line number Diff line number Diff line change
@@ -1,88 +1,88 @@
import {inspect} from 'util';
import { inspect } from "util";
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);

const pkg = require("../../package.json");
const [homepage] = pkg.homepage.split('#');
const [homepage] = pkg.homepage.split("#");
const linkify = (file) => `${homepage}/blob/master/${file}`;
const stringify = (object) => inspect(object, {breakLength: Number.POSITIVE_INFINITY, depth: 2, maxArrayLength: 5});
const stringify = (object) => inspect(object, { breakLength: Number.POSITIVE_INFINITY, depth: 2, maxArrayLength: 5 });

export default {
EINVALIDASSETS: ({assets}) => ({
message: 'Invalid `assets` option.',
EINVALIDASSETS: ({ assets }) => ({
message: "Invalid `assets` option.",
details: `The [assets option](${linkify(
'README.md#assets'
"README.md#assets"
)}) must be an \`Array\` of \`Strings\` or \`Objects\` with a \`path\` property.
Your configuration for the \`assets\` option is \`${stringify(assets)}\`.`,
}),
EINVALIDFAILTITLE: ({failTitle}) => ({
message: 'Invalid `failTitle` option.',
details: `The [failTitle option](${linkify('README.md#failtitle')}) if defined, must be a non empty \`String\`.
EINVALIDFAILTITLE: ({ failTitle }) => ({
message: "Invalid `failTitle` option.",
details: `The [failTitle option](${linkify("README.md#failtitle")}) if defined, must be a non empty \`String\`.

Your configuration for the \`failTitle\` option is \`${stringify(failTitle)}\`.`,
}),
EINVALIDFAILCOMMENT: ({failComment}) => ({
message: 'Invalid `failComment` option.',
details: `The [failComment option](${linkify('README.md#failcomment')}) if defined, must be a non empty \`String\`.
EINVALIDFAILCOMMENT: ({ failComment }) => ({
message: "Invalid `failComment` option.",
details: `The [failComment option](${linkify("README.md#failcomment")}) if defined, must be a non empty \`String\`.

Your configuration for the \`failComment\` option is \`${stringify(failComment)}\`.`,
}),
EINVALIDLABELS: ({labels}) => ({
message: 'Invalid `labels` option.',
details: `The [labels option](${linkify('README.md#labels')}) if defined, must be a non empty \`String\`.
EINVALIDLABELS: ({ labels }) => ({
message: "Invalid `labels` option.",
details: `The [labels option](${linkify("README.md#labels")}) if defined, must be a non empty \`String\`.

Your configuration for the \`labels\` option is \`${stringify(labels)}\`.`,
}),
EINVALIDASSIGNEE: ({assignee}) => ({
message: 'Invalid `assignee` option.',
details: `The [assignee option](${linkify('README.md#assignee')}) if defined, must be a non empty \`String\`.
EINVALIDASSIGNEE: ({ assignee }) => ({
message: "Invalid `assignee` option.",
details: `The [assignee option](${linkify("README.md#assignee")}) if defined, must be a non empty \`String\`.

Your configuration for the \`assignee\` option is \`${stringify(assignee)}\`.`,
}),
EINVALIDGITLABURL: () => ({
message: 'The git repository URL is not a valid GitLab URL.',
message: "The git repository URL is not a valid GitLab URL.",
details: `The **semantic-release** \`repositoryUrl\` option must a valid GitLab URL with the format \`<GitLab_URL>/<projectPath>.git\`.

By default the \`repositoryUrl\` option is retrieved from the \`repository\` property of your \`package.json\` or the [git origin url](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes) of the repository cloned by your CI environment.`,
}),
EINVALIDGLTOKEN: ({projectPath}) => ({
message: 'Invalid GitLab token.',
EINVALIDGLTOKEN: ({ projectPath }) => ({
message: "Invalid GitLab token.",
details: `The [GitLab token](${linkify(
'README.md#gitlab-authentication'
"README.md#gitlab-authentication"
)}) configured in the \`GL_TOKEN\` or \`GITLAB_TOKEN\` environment variable must be a valid [personal access token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html) allowing to push to the repository ${projectPath}.

Please make sure to set the \`GL_TOKEN\` or \`GITLAB_TOKEN\` environment variable in your CI with the exact value of the GitLab personal token.`,
}),
EMISSINGREPO: ({projectPath}) => ({
EMISSINGREPO: ({ projectPath }) => ({
message: `The repository ${projectPath} doesn't exist.`,
details: `The **semantic-release** \`repositoryUrl\` option must refer to your GitLab repository. The repository must be accessible with the [GitLab API](https://docs.gitlab.com/ce/api/README.html).

By default the \`repositoryUrl\` option is retrieved from the \`repository\` property of your \`package.json\` or the [git origin url](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes) of the repository cloned by your CI environment.

If you are using [GitLab Enterprise Edition](https://about.gitlab.com/gitlab-ee) please make sure to configure the \`gitlabUrl\` and \`gitlabApiPathPrefix\` [options](${linkify(
'README.md#options'
"README.md#options"
)}).`,
}),
EGLNOPUSHPERMISSION: ({projectPath}) => ({
EGLNOPUSHPERMISSION: ({ projectPath }) => ({
message: `The GitLab token doesn't allow to push on the repository ${projectPath}.`,
details: `The user associated with the [GitLab token](${linkify(
'README.md#gitlab-authentication'
"README.md#gitlab-authentication"
)}) configured in the \`GL_TOKEN\` or \`GITLAB_TOKEN\` environment variable must allows to push to the repository ${projectPath}.

Please make sure the GitLab user associated with the token has the [permission to push](https://docs.gitlab.com/ee/user/permissions.html#project-members-permissions) to the repository ${projectPath}.`,
}),
EGLNOPULLPERMISSION: ({projectPath}) => ({
EGLNOPULLPERMISSION: ({ projectPath }) => ({
message: `The GitLab token doesn't allow to pull from the repository ${projectPath}.`,
details: `The user associated with the [GitLab token](${linkify(
'README.md#gitlab-authentication'
"README.md#gitlab-authentication"
)}) configured in the \`GL_TOKEN\` or \`GITLAB_TOKEN\` environment variable must allow pull from the repository ${projectPath}.

Please make sure the GitLab user associated with the token has the [permission to push](https://docs.gitlab.com/ee/user/permissions.html#project-members-permissions) to the repository ${projectPath}.`,
}),
ENOGLTOKEN: ({repositoryUrl}) => ({
message: 'No GitLab token specified.',
ENOGLTOKEN: ({ repositoryUrl }) => ({
message: "No GitLab token specified.",
details: `A [GitLab personal access token](${linkify(
'README.md#gitlab-authentication'
"README.md#gitlab-authentication"
)}) must be created and set in the \`GL_TOKEN\` or \`GITLAB_TOKEN\` environment variable on your CI environment.

Please make sure to create a [GitLab personal access token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html) and to set it in the \`GL_TOKEN\` or \`GITLAB_TOKEN\` environment variable on your CI environment. The token must allow to push to the repository ${repositoryUrl}.`,
Expand Down
12 changes: 9 additions & 3 deletions lib/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export default async (pluginConfig, context) => {
const type = asset.type ? template(asset.type)(context) : undefined;
const filepath = asset.filepath ? template(asset.filepath)(context) : undefined;
const target = asset.target ? template(asset.target)(context) : undefined;
const packageName = asset.packageName ? template(asset.packageName)(context) : "release";
const status = asset.status ? template(asset.status)(context) : undefined;

if (_url) {
Expand Down Expand Up @@ -102,6 +103,7 @@ export default async (pluginConfig, context) => {
debug("file type: %o", type);
debug("file filepath: %o", filepath);
debug("file target: %o", target);
debug("file packageName: %o", packageName);
debug("file status: %o", status);

let uploadEndpoint;
Expand All @@ -110,10 +112,11 @@ export default async (pluginConfig, context) => {
if (target === "generic_package") {
// Upload generic packages
const encodedLabel = encodeURIComponent(label);
const encodedPackageName = encodeURIComponent(packageName);
// 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
3 changes: 2 additions & 1 deletion test/fixtures/files/file.css
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.test {}
.test {
}
20 changes: 10 additions & 10 deletions test/helpers/mock-gitlab.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import nock from 'nock';
import urlJoin from 'url-join';
import nock from "nock";
import urlJoin from "url-join";

/**
* Retun a `nock` object setup to respond to a GitLab authentication request. Other expectation and responses can be chained.
Expand All @@ -13,14 +13,14 @@ import urlJoin from 'url-join';
export default function (
env = {},
{
gitlabToken = env.GL_TOKEN || env.GITLAB_TOKEN || 'GL_TOKEN',
gitlabUrl = env.GL_URL || env.GITLAB_URL || 'https://gitlab.com',
gitlabApiPathPrefix = typeof env.GL_PREFIX === 'string'
gitlabToken = env.GL_TOKEN || env.GITLAB_TOKEN || "GL_TOKEN",
gitlabUrl = env.GL_URL || env.GITLAB_URL || "https://gitlab.com",
gitlabApiPathPrefix = typeof env.GL_PREFIX === "string"
? env.GL_PREFIX
: null || typeof env.GITLAB_PREFIX === 'string'
? env.GITLAB_PREFIX
: null || '/api/v4',
: null || typeof env.GITLAB_PREFIX === "string"
? env.GITLAB_PREFIX
: null || "/api/v4",
} = {}
) {
return nock(urlJoin(gitlabUrl, gitlabApiPathPrefix), {reqheaders: {'Private-Token': gitlabToken}});
};
return nock(urlJoin(gitlabUrl, gitlabApiPathPrefix), { reqheaders: { "Private-Token": gitlabToken } });
}
Loading