Skip to content

Commit

Permalink
fix: correct release script
Browse files Browse the repository at this point in the history
  • Loading branch information
sebtiz13 committed Jul 8, 2024
1 parent 2eb5887 commit 35a3d1c
Show file tree
Hide file tree
Showing 10 changed files with 513 additions and 73 deletions.
29 changes: 29 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require("node:path");

module.exports = {
plugins: ["kuzzle", "jest"],
extends: [
"plugin:kuzzle/default",
"plugin:kuzzle/node",
"plugin:kuzzle/typescript",
"plugin:jest/recommended",
"plugin:jest/style",
],
parserOptions: {
project: path.join(__dirname, "tsconfig.test.json"),
},
overrides: [
{
files: [
".eslintrc.cjs",
"**/roles/*.ts",
"**/collections/*.ts",
"**tests/**/*.ts",
],
rules: {
"sort-keys": ["off"],
},
},
],
};
18 changes: 0 additions & 18 deletions .eslintrc.json

This file was deleted.

114 changes: 59 additions & 55 deletions releaseTypes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@ import path from "node:path";
import AggregateError from "aggregate-error";
import { temporaryFile } from "tempy";
import SemanticReleaseError from "@semantic-release/error";
import verifyNpmConfig from "@semantic-release/npm/lib/verify-config.js";
import getPkg from "@semantic-release/npm/lib/get-pkg.js";
import verifyNpmAuth from "@semantic-release/npm/lib/verify-auth.js";
import addChannelNpm from "@semantic-release/npm/lib/add-channel.js";
import prepareNpm from "@semantic-release/npm/lib/prepare.js";
import publishNpm from "@semantic-release/npm/lib/publish.js";
import { add } from "@semantic-release/git/lib/git.js";

import {
getError,
getPkg,
verifyNpmAuth,
npmVersion,
npmDistTag,
npmPublish,
} from "./scripts/npm/index.mjs";

/**
* @typedef {Object} OptionsContext
* @prop {import("semantic-release").GlobalConfig} options
* @typedef {import("./scripts/npm/types").PluginConfig} PluginConfig
*/

/**
* @typedef {Object} PluginConfig
* @prop {boolean} [npmPublish] Define if the package should be published on npm repository.
* @typedef {Object} OptionsContext
* @prop {import("semantic-release").GlobalConfig} options
*/

let verified = false;
Expand All @@ -36,6 +38,32 @@ function typeContext(context) {
return context;
}

/**
* Check if the plugin is defined before the plugin `@semantic-release/git` if it's defined.
*
* @param {import("semantic-release").VerifyConditionsContext & OptionsContext} context semantic-release context.
*/
function checkPluginsOrder(context) {
const pluginsList = context.options.plugins.map((plugin) =>
Array.isArray(plugin) ? plugin[0] : plugin,
);
const gitPluginIndex = pluginsList.indexOf("@semantic-release/git");

if (gitPluginIndex === -1) {
return;
}

const pluginIndex = pluginsList.findIndex((plugin) =>
plugin.includes(path.basename(import.meta.url)),
);
if (pluginIndex > gitPluginIndex) {
throw new SemanticReleaseError(
"This plugin should be defined before plugin `@semantic-release/git`",
"EINVALIDSETUP",
);
}
}

/**
* Verify the npm configuration and plugin setup:
* - The plugin should be define before the plugin `@semantic-release/git` if it's defined.
Expand All @@ -45,31 +73,26 @@ function typeContext(context) {
*/
export async function verifyConditions(pluginConfig, ctx) {
const context = typeContext(ctx);
const errors = verifyNpmConfig(pluginConfig);
const errors = [];

const pluginsList = context.options.plugins.map((plugin) =>
Array.isArray(plugin) ? plugin[0] : plugin
);
const gitPluginIndex = pluginsList.indexOf("@semantic-release/git");
try {
checkPluginsOrder(context);
} catch (error) {
errors.push(error);
}

if (gitPluginIndex !== -1) {
const pluginIndex = pluginsList.findIndex((plugin) =>
plugin.includes(path.basename(import.meta.url))
);
if (pluginIndex > gitPluginIndex) {
errors.push(
new SemanticReleaseError(
"This plugin should be defined before plugin `@semantic-release/git`",
"EINVALIDSETUP"
)
);
}
// ? Check if `npmPublish` is boolean
if (
pluginConfig.npmPublish !== undefined &&
pluginConfig.npmPublish !== true &&
pluginConfig.npmPublish !== false
) {
errors.push(getError("EINVALIDNPMPUBLISH", pluginConfig));
}

try {
const pkg = await getPkg(pluginConfig, context);

if (pluginConfig.npmPublish !== false) {
const pkg = await getPkg(pluginConfig, context);
await verifyNpmAuth(npmrc, pkg, context);
}
} catch (error) {
Expand All @@ -92,7 +115,7 @@ export async function verifyConditions(pluginConfig, ctx) {
export async function prepare(pluginConfig, ctx) {
const context = typeContext(ctx);
const { env, cwd } = context;
await prepareNpm(npmrc, pluginConfig, context);
await npmVersion(npmrc, context);

// ? Can't modify assets configuration in a plugin, so manually add modified `package.json` in git index
// ? `@semantic-release/git` make release commit with the other assets files after, this is why this plugin should be defined before him
Expand All @@ -111,13 +134,13 @@ export async function publish(pluginConfig, ctx) {
const context = typeContext(ctx);
if (pluginConfig.npmPublish === false) {
context.logger.log(
`Skip publishing to npm registry as npmPublish is false`
`Skip publishing to npm registry as npmPublish is false`,
);
return false;
}

let pkg;
const errors = verified ? [] : verifyNpmConfig(pluginConfig);
const errors = [];

try {
// Reload package.json in case a previous external step updated it
Expand All @@ -141,7 +164,7 @@ export async function publish(pluginConfig, ctx) {
await prepare(pluginConfig, context);
}

return publishNpm(npmrc, pluginConfig, pkg, context);
return npmPublish(npmrc, pluginConfig, pkg, context);
}

/**
Expand All @@ -152,26 +175,7 @@ export async function publish(pluginConfig, ctx) {
*/
export async function addChannel(pluginConfig, ctx) {
const context = typeContext(ctx);
let pkg;
const errors = verified ? [] : verifyNpmConfig(pluginConfig);

try {
// Reload package.json in case a previous external step updated it
pkg = await getPkg(pluginConfig, context);
if (
!verified &&
pluginConfig.npmPublish !== false &&
pkg.private !== true
) {
await verifyNpmAuth(npmrc, pkg, context);
}
} catch (error) {
errors.push(...error.errors);
}

if (errors.length > 0) {
throw new AggregateError(errors);
}

return addChannelNpm(npmrc, pluginConfig, pkg, context);
// Reload package.json in case a previous external step updated it
const pkg = await getPkg(pluginConfig, context);
return npmDistTag(npmrc, pluginConfig, pkg, context);
}
7 changes: 7 additions & 0 deletions scripts/npm/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"trailingComma": "all",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"semi": true
}
54 changes: 54 additions & 0 deletions scripts/npm/error.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* eslint-disable sort-keys */
import SemanticReleaseError from '@semantic-release/error';

export const ERROR_DEFINITIONS = {
EINVALIDNPMPUBLISH({ npmPublish }) {
return {
message: 'Invalid `npmPublish` option.',
details: `If the npmPublish option defined, must be a \`Boolean\`.
Your configuration for the \`npmPublish\` option is \`${npmPublish}\`.`,
};
},
ENONPMTOKEN({ registry }) {
return {
message: 'No npm token specified.',
details: `An npm token must be created and set in the \`NPM_TOKEN\` environment variable on your CI environment.
Please make sure to create an [npm token](https://docs.npmjs.com/getting-started/working_with_tokens#how-to-create-new-tokens) and to set it in the \`NPM_TOKEN\` environment variable on your CI environment. The token must allow to publish to the registry \`${registry}\`.`,
};
},
EINVALIDNPMTOKEN({ registry }) {
return {
message: 'Invalid npm token.',
details: `The npm token configured in the \`NPM_TOKEN\` environment variable must be a valid [token](https://docs.npmjs.com/getting-started/working_with_tokens) allowing to publish to the registry \`${registry}\`.
If you are using Two Factor Authentication for your account, set its level to ["Authorization only"](https://docs.npmjs.com/getting-started/using-two-factor-authentication#levels-of-authentication) in your account settings. **semantic-release** cannot publish with the default "
Authorization and writes" level.
Please make sure to set the \`NPM_TOKEN\` environment variable in your CI with the exact value of the npm token.`,
};
},
ENOPKGNAME() {
return {
message: 'Missing `name` property in `package.json`.',
details: `The \`package.json\`'s [name](https://docs.npmjs.com/files/package.json#name) property is required in order to publish a package to the npm registry.
Please make sure to add a valid \`name\` for your package in your \`package.json\`.`,
};
},
ENOPKG() {
return {
message: 'Missing `package.json` file.',
details: `A [package.json file](https://docs.npmjs.com/files/package.json) at the root of your project is required to release on npm.
Please follow the [npm guideline](https://docs.npmjs.com/getting-started/creating-node-modules) to create a valid \`package.json\` file.`,
};
},
};

export function getError(code, ctx = {}) {
const { message, details } = ERROR_DEFINITIONS[code](ctx);

return new SemanticReleaseError(message, code, details);
}
3 changes: 3 additions & 0 deletions scripts/npm/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './error.mjs';
export * from './package.mjs';
export * from './registry.mjs';
Loading

0 comments on commit 35a3d1c

Please sign in to comment.