-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrelease-plugin.js
More file actions
110 lines (96 loc) · 3.74 KB
/
release-plugin.js
File metadata and controls
110 lines (96 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const underlyingPluginSpecifier = "@semantic-release/npm";
// We use the safe navigation operator because when this module
// is executed by jest, import.meta.resolve is unavailable.
const resolvedNpm = import.meta.resolve?.(underlyingPluginSpecifier);
const registryPlugins = {};
async function getChildPlugin(registryName) {
let plugin = registryPlugins[registryName];
if (!plugin) {
// What's going on here?
//
// @semantic-release/npm maintains some module-level state (specifically,
// a temporary file that acts as an npmrc), which means that we can't just
// call the same plugin lifecycle methods repeatedly because they would
// stomp on the shared state.
//
// Fortunately, node has a way to deliberately suppress its normal module
// caching behavior, which allows us to load multiple copies of a single module:
// by appending a query string to the specifier, node will load one copy of the
// module per query string.
//
// But there's a twist: node *doesn't* support this behavior on "bare specifiers",
// which is how we usually import other packages. In order to get around this,
// we must use import.meta.resolve in order to transform the bare specifier into
// a file url specifier.
//
// But then there's a double twist! Jest doesn't support import.meta.resolve, but
// it *does* support query strings on bare specifiers. So in order to be compatible
// with both tests and actual usage, we have this unsightly kludge.
const importSpecifier = `${resolvedNpm || underlyingPluginSpecifier}?registry=${encodeURIComponent(registryName)}`;
plugin = import(importSpecifier);
registryPlugins[registryName] = plugin;
}
return await plugin;
}
const __dirname = fileURLToPath(import.meta.url);
function createCallbackWrapper(callbackName) {
return async ({ registries, ...pluginConfig }, context) => {
const namesPkg = {
github: "@open-ui-kit/core",
devhub: "@open-ui-kit/core",
};
for (const [registryName, childConfig] of Object.entries(
registries || {},
)) {
const plugin = await getChildPlugin(registryName);
const callback = plugin[callbackName];
if (!callback) {
return;
}
context.logger.log(
`Performing ${callbackName} for registry ${registryName}`,
);
const environmentVariablePrefix = `${registryName.toUpperCase()}_`;
const { env } = context;
const childEnv = { ...env };
for (const variableName of [
"NPM_TOKEN",
"NPM_USERNAME",
"NPM_PASSWORD",
"NPM_EMAIL",
"NPM_CONFIG_REGISTRY",
"NPM_CONFIG_USERCONFIG",
]) {
const overridenValue = env[environmentVariablePrefix + variableName];
if (overridenValue) {
childEnv[variableName] = overridenValue;
}
}
if (callbackName === "publish") {
const packageJsonPath = path.resolve(
__dirname,
`../../${childConfig.pkgRoot}/package.json`,
);
const packageJson = JSON.parse(
fs.readFileSync(packageJsonPath, "utf-8"),
);
packageJson.name = namesPkg[registryName] || packageJson.name;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
context.logger.log("Updated package scope before publishing");
}
await callback(
{ ...childConfig, ...pluginConfig },
{ ...context, env: childEnv },
);
}
};
}
export default {
addChannel: createCallbackWrapper("addChannel"),
prepare: createCallbackWrapper("prepare"),
publish: createCallbackWrapper("publish"),
verifyConditions: createCallbackWrapper("verifyConditions"),
};