@aidc-toolkit/dev 0.9.17-beta → 0.9.19-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -23
- package/config/publish.json +20 -23
- package/dist/eslint-config-template.d.ts +1 -1
- package/dist/eslint-config-template.d.ts.map +1 -1
- package/dist/eslint-config-template.js +107 -89
- package/dist/eslint-config-template.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +18 -18
- package/src/eslint-config-template.ts +23 -13
- package/src/index.ts +0 -1
- package/src/publish/logger.ts +34 -0
- package/src/publish/publish-alpha.ts +144 -0
- package/src/publish/publish-beta.ts +293 -0
- package/src/publish/publish.ts +903 -0
- package/src/publish/type-helper.ts +51 -0
- package/tsconfig.json +2 -2
- package/typedoc.json +1 -0
- package/dist/utility.d.ts +0 -22
- package/dist/utility.d.ts.map +0 -1
- package/dist/utility.js +0 -57
- package/dist/utility.js.map +0 -1
- package/src/publish-external.ts +0 -332
- package/src/publish-internal.ts +0 -111
- package/src/publish.ts +0 -273
- package/src/utility.ts +0 -59
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create an object with omitted or picked entries.
|
|
3
|
+
*
|
|
4
|
+
* @param omitting
|
|
5
|
+
* True if omitting.
|
|
6
|
+
*
|
|
7
|
+
* @param o
|
|
8
|
+
* Object.
|
|
9
|
+
*
|
|
10
|
+
* @param keys
|
|
11
|
+
* Keys to omit or pick.
|
|
12
|
+
*
|
|
13
|
+
* @returns
|
|
14
|
+
* Edited object.
|
|
15
|
+
*/
|
|
16
|
+
function omitOrPick<Omitting extends boolean, T extends object, K extends keyof T>(omitting: Omitting, o: T, ...keys: K[]): Omitting extends true ? Omit<T, K> : Pick<T, K> {
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Key and value types are known.
|
|
18
|
+
return Object.fromEntries(Object.entries(o).filter(([key]) => keys.includes(key as K) !== omitting)) as ReturnType<typeof omitOrPick<Omitting, T, K>>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create an object with omitted entries.
|
|
23
|
+
*
|
|
24
|
+
* @param o
|
|
25
|
+
* Object.
|
|
26
|
+
*
|
|
27
|
+
* @param keys
|
|
28
|
+
* Keys to omit.
|
|
29
|
+
*
|
|
30
|
+
* @returns
|
|
31
|
+
* Edited object.
|
|
32
|
+
*/
|
|
33
|
+
export function omit<T extends object, K extends keyof T>(o: T, ...keys: K[]): Omit<T, K> {
|
|
34
|
+
return omitOrPick(true, o, ...keys);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Create an object with picked entries.
|
|
39
|
+
*
|
|
40
|
+
* @param o
|
|
41
|
+
* Object.
|
|
42
|
+
*
|
|
43
|
+
* @param keys
|
|
44
|
+
* Keys to pick.
|
|
45
|
+
*
|
|
46
|
+
* @returns
|
|
47
|
+
* Edited object.
|
|
48
|
+
*/
|
|
49
|
+
export function pick<T extends object, K extends keyof T>(o: T, ...keys: K[]): Pick<T, K> {
|
|
50
|
+
return omitOrPick(false, o, ...keys);
|
|
51
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"noPropertyAccessFromIndexSignature": true,
|
|
10
10
|
|
|
11
11
|
// Modules.
|
|
12
|
-
"module": "
|
|
12
|
+
"module": "es2022",
|
|
13
13
|
"moduleResolution": "bundler",
|
|
14
14
|
"resolveJsonModule": true,
|
|
15
15
|
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"forceConsistentCasingInFileNames": true,
|
|
22
22
|
|
|
23
23
|
// Language and environment.
|
|
24
|
-
"target": "
|
|
24
|
+
"target": "es2022",
|
|
25
25
|
|
|
26
26
|
// Completeness.
|
|
27
27
|
"skipLibCheck": true
|
package/typedoc.json
CHANGED
package/dist/utility.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Logger } from "tslog";
|
|
2
|
-
/**
|
|
3
|
-
* Logger with a default minimum level of Info.
|
|
4
|
-
*/
|
|
5
|
-
export declare const logger: Logger<unknown>;
|
|
6
|
-
/**
|
|
7
|
-
* Run a command and optionally capture its output.
|
|
8
|
-
*
|
|
9
|
-
* @param captureOutput
|
|
10
|
-
* If true, output is captured and returned.
|
|
11
|
-
*
|
|
12
|
-
* @param command
|
|
13
|
-
* Command to run.
|
|
14
|
-
*
|
|
15
|
-
* @param args
|
|
16
|
-
* Arguments to command.
|
|
17
|
-
*
|
|
18
|
-
* @returns
|
|
19
|
-
* Output if captured or empty array if not.
|
|
20
|
-
*/
|
|
21
|
-
export declare function run(captureOutput: boolean, command: string, ...args: string[]): string[];
|
|
22
|
-
//# sourceMappingURL=utility.d.ts.map
|
package/dist/utility.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utility.d.ts","sourceRoot":"","sources":["../src/utility.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAS/B;;GAEG;AACH,eAAO,MAAM,MAAM,iBAEjB,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,GAAG,CAAC,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA0BxF"}
|
package/dist/utility.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from "child_process";
|
|
2
|
-
import { Logger } from "tslog";
|
|
3
|
-
/**
|
|
4
|
-
* Log level.
|
|
5
|
-
*/
|
|
6
|
-
var LogLevel;
|
|
7
|
-
(function (LogLevel) {
|
|
8
|
-
LogLevel[LogLevel["Silly"] = 0] = "Silly";
|
|
9
|
-
LogLevel[LogLevel["Trace"] = 1] = "Trace";
|
|
10
|
-
LogLevel[LogLevel["Debug"] = 2] = "Debug";
|
|
11
|
-
LogLevel[LogLevel["Info"] = 3] = "Info";
|
|
12
|
-
LogLevel[LogLevel["Warn"] = 4] = "Warn";
|
|
13
|
-
LogLevel[LogLevel["Error"] = 5] = "Error";
|
|
14
|
-
LogLevel[LogLevel["Fatal"] = 6] = "Fatal";
|
|
15
|
-
})(LogLevel || (LogLevel = {}));
|
|
16
|
-
/**
|
|
17
|
-
* Logger with a default minimum level of Info.
|
|
18
|
-
*/
|
|
19
|
-
export const logger = new Logger({
|
|
20
|
-
minLevel: LogLevel.Info
|
|
21
|
-
});
|
|
22
|
-
/**
|
|
23
|
-
* Run a command and optionally capture its output.
|
|
24
|
-
*
|
|
25
|
-
* @param captureOutput
|
|
26
|
-
* If true, output is captured and returned.
|
|
27
|
-
*
|
|
28
|
-
* @param command
|
|
29
|
-
* Command to run.
|
|
30
|
-
*
|
|
31
|
-
* @param args
|
|
32
|
-
* Arguments to command.
|
|
33
|
-
*
|
|
34
|
-
* @returns
|
|
35
|
-
* Output if captured or empty array if not.
|
|
36
|
-
*/
|
|
37
|
-
export function run(captureOutput, command, ...args) {
|
|
38
|
-
logger.debug(`Running command "${command}" with arguments ${JSON.stringify(args)}.`);
|
|
39
|
-
const spawnResult = spawnSync(command, args, {
|
|
40
|
-
stdio: ["inherit", captureOutput ? "pipe" : "inherit", "inherit"]
|
|
41
|
-
});
|
|
42
|
-
if (spawnResult.error !== undefined) {
|
|
43
|
-
throw spawnResult.error;
|
|
44
|
-
}
|
|
45
|
-
if (spawnResult.status === null) {
|
|
46
|
-
throw new Error(`Terminated by signal ${spawnResult.signal}`);
|
|
47
|
-
}
|
|
48
|
-
if (spawnResult.status !== 0) {
|
|
49
|
-
throw new Error(`Failed with status ${spawnResult.status}`);
|
|
50
|
-
}
|
|
51
|
-
const output = captureOutput ? spawnResult.stdout.toString().split("\n").slice(0, -1) : [];
|
|
52
|
-
if (captureOutput) {
|
|
53
|
-
logger.debug(`Output is ${JSON.stringify(output)}.`);
|
|
54
|
-
}
|
|
55
|
-
return output;
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=utility.js.map
|
package/dist/utility.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utility.js","sourceRoot":"","sources":["../src/utility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,IAAK,QAEJ;AAFD,WAAK,QAAQ;IACT,yCAAK,CAAA;IAAE,yCAAK,CAAA;IAAE,yCAAK,CAAA;IAAE,uCAAI,CAAA;IAAE,uCAAI,CAAA;IAAE,yCAAK,CAAA;IAAE,yCAAK,CAAA;AACjD,CAAC,EAFI,QAAQ,KAAR,QAAQ,QAEZ;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC,IAAI;CAC1B,CAAC,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,GAAG,CAAC,aAAsB,EAAE,OAAe,EAAE,GAAG,IAAc;IAC1E,MAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,oBAAoB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAErF,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE;QACzC,KAAK,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC;KACpE,CAAC,CAAC;IAEH,IAAI,WAAW,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,WAAW,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,wBAAwB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,sBAAsB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3F,IAAI,aAAa,EAAE,CAAC;QAChB,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/src/publish-external.ts
DELETED
|
@@ -1,332 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import * as util from "node:util";
|
|
4
|
-
import { Octokit } from "octokit";
|
|
5
|
-
import { parse as yamlParse } from "yaml";
|
|
6
|
-
import {
|
|
7
|
-
anyChanges,
|
|
8
|
-
configuration,
|
|
9
|
-
organizationRepository, type PackageConfiguration,
|
|
10
|
-
publishRepositories,
|
|
11
|
-
type Repository,
|
|
12
|
-
saveConfiguration,
|
|
13
|
-
secureConfiguration
|
|
14
|
-
} from "./publish";
|
|
15
|
-
import { logger, run } from "./utility.js";
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Configuration layout of release.yml workflow (relevant attributes only).
|
|
19
|
-
*/
|
|
20
|
-
interface WorkflowConfiguration {
|
|
21
|
-
/**
|
|
22
|
-
* Workflow name.
|
|
23
|
-
*/
|
|
24
|
-
name: string;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Workflow trigger.
|
|
28
|
-
*/
|
|
29
|
-
on: {
|
|
30
|
-
/**
|
|
31
|
-
* Push trigger.
|
|
32
|
-
*/
|
|
33
|
-
push?: {
|
|
34
|
-
/**
|
|
35
|
-
* Push branches.
|
|
36
|
-
*/
|
|
37
|
-
branches?: string[];
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Release trigger.
|
|
42
|
-
*/
|
|
43
|
-
release?: {
|
|
44
|
-
/**
|
|
45
|
-
* Release types.
|
|
46
|
-
*/
|
|
47
|
-
types?: string[];
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Supported steps.
|
|
54
|
-
*/
|
|
55
|
-
type Step =
|
|
56
|
-
"skipped" | "install" | "build" | "commit" | "tag" | "push" | "workflow (push)" | "release" | "workflow (release)" | "restore alpha" | "complete";
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Execute a step.
|
|
60
|
-
*
|
|
61
|
-
* @param repository
|
|
62
|
-
* Repository.
|
|
63
|
-
*
|
|
64
|
-
* @param step
|
|
65
|
-
* State at which step takes place.
|
|
66
|
-
*
|
|
67
|
-
* @param callback
|
|
68
|
-
* Callback to execute step.
|
|
69
|
-
*
|
|
70
|
-
* @returns
|
|
71
|
-
* Promise.
|
|
72
|
-
*/
|
|
73
|
-
async function runStep(repository: Repository, step: Step, callback: () => (void | Promise<void>)): Promise<void> {
|
|
74
|
-
if (repository.publishExternalStep === undefined || repository.publishExternalStep === step) {
|
|
75
|
-
logger.debug(`Running step ${step}`);
|
|
76
|
-
|
|
77
|
-
repository.publishExternalStep = step;
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
const result = callback();
|
|
81
|
-
|
|
82
|
-
if (result instanceof Promise) {
|
|
83
|
-
await result;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
repository.publishExternalStep = undefined;
|
|
87
|
-
} finally {
|
|
88
|
-
saveConfiguration();
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
logger.debug(`Skipping step ${step}`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Update dependencies from the organization.
|
|
97
|
-
*
|
|
98
|
-
* @param restoreAlpha
|
|
99
|
-
* If true, restore "alpha" as the version for development.
|
|
100
|
-
*
|
|
101
|
-
* @param development
|
|
102
|
-
* True if updating development dependencies.
|
|
103
|
-
*
|
|
104
|
-
* @param internal
|
|
105
|
-
* True if the package is for internal use only and its version should not be used in dependencies.
|
|
106
|
-
*
|
|
107
|
-
* @param dependencies
|
|
108
|
-
* Dependencies.
|
|
109
|
-
*
|
|
110
|
-
* @returns
|
|
111
|
-
* True if any dependencies were updated.
|
|
112
|
-
*/
|
|
113
|
-
function updateDependencies(restoreAlpha: boolean, development: boolean, internal: boolean | undefined, dependencies: Record<string, string> | undefined): boolean {
|
|
114
|
-
let anyUpdated = false;
|
|
115
|
-
|
|
116
|
-
if (dependencies !== undefined) {
|
|
117
|
-
// eslint-disable-next-line guard-for-in -- Dependency record type is shallow.
|
|
118
|
-
for (const dependency in dependencies) {
|
|
119
|
-
const dependencyRepositoryName = organizationRepository(dependency);
|
|
120
|
-
|
|
121
|
-
if (dependencyRepositoryName !== null) {
|
|
122
|
-
const dependencyRepository = configuration.repositories[dependencyRepositoryName];
|
|
123
|
-
|
|
124
|
-
// Set to explicit version for external dependency.
|
|
125
|
-
if (dependencyRepository.dependencyType === "external") {
|
|
126
|
-
dependencies[dependency] = !restoreAlpha ? `^${dependencyRepository.lastExternalVersion}` : "alpha";
|
|
127
|
-
anyUpdated = true;
|
|
128
|
-
} else if (!restoreAlpha && !development && internal !== true) {
|
|
129
|
-
throw new Error("Internal dependency specified for external package");
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return anyUpdated;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const octokit = new Octokit({
|
|
139
|
-
auth: secureConfiguration.token,
|
|
140
|
-
userAgent: `${configuration.organization} release`
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
await publishRepositories(async (name, repository) => {
|
|
144
|
-
// Repository must be on main branch.
|
|
145
|
-
if (run(true, "git", "branch", "--show-current")[0] !== "main") {
|
|
146
|
-
throw new Error("Repository is not on main branch");
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const packageConfigurationPath = "package.json";
|
|
150
|
-
|
|
151
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Package configuration format is known.
|
|
152
|
-
const packageConfiguration: PackageConfiguration = JSON.parse(fs.readFileSync(packageConfigurationPath).toString());
|
|
153
|
-
|
|
154
|
-
let publish: boolean;
|
|
155
|
-
|
|
156
|
-
if (repository.publishExternalStep === undefined) {
|
|
157
|
-
publish = anyChanges(repository, true);
|
|
158
|
-
} else {
|
|
159
|
-
publish = true;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (packageConfiguration.version !== repository.lastExternalVersion) {
|
|
163
|
-
// Package version has already been updated, either manually or by previous failed run.
|
|
164
|
-
publish = true;
|
|
165
|
-
} else if (publish) {
|
|
166
|
-
const packageVersionSplits = packageConfiguration.version.split("-");
|
|
167
|
-
|
|
168
|
-
// Extract semantic version and pre-release identifier.
|
|
169
|
-
const semanticVersion = packageVersionSplits[0];
|
|
170
|
-
const preReleaseIdentifier = packageVersionSplits.length !== 1 ? `-${packageVersionSplits[1]}` : "";
|
|
171
|
-
|
|
172
|
-
// Parse semantic version into its components.
|
|
173
|
-
const [majorVersion, minorVersion, patchVersion] = semanticVersion.split(".").map(versionString => Number(versionString));
|
|
174
|
-
|
|
175
|
-
// Increment patch version number.
|
|
176
|
-
packageConfiguration.version = `${majorVersion}.${minorVersion}.${patchVersion + 1}${preReleaseIdentifier}`;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const tag = `v${packageConfiguration.version}`;
|
|
180
|
-
|
|
181
|
-
const octokitParameterBase = {
|
|
182
|
-
owner: configuration.organization,
|
|
183
|
-
repo: name
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
const internal = repository.dependencyType === "internal";
|
|
187
|
-
|
|
188
|
-
if (publish) {
|
|
189
|
-
if (repository.publishExternalStep === undefined) {
|
|
190
|
-
updateDependencies(false, true, internal, packageConfiguration.devDependencies);
|
|
191
|
-
updateDependencies(false, false, internal, packageConfiguration.dependencies);
|
|
192
|
-
|
|
193
|
-
fs.writeFileSync(packageConfigurationPath, `${JSON.stringify(packageConfiguration, null, 2)}\n`);
|
|
194
|
-
} else {
|
|
195
|
-
logger.debug(`Repository failed at step ${repository.publishExternalStep} on prior run`);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const workflowsPath = ".github/workflows/";
|
|
199
|
-
|
|
200
|
-
let hasPushWorkflow = false;
|
|
201
|
-
let hasReleaseWorkflow = false;
|
|
202
|
-
|
|
203
|
-
if (fs.existsSync(workflowsPath)) {
|
|
204
|
-
logger.debug("Checking workflows");
|
|
205
|
-
|
|
206
|
-
for (const workflowFile of fs.readdirSync(workflowsPath).filter(workflowFile => workflowFile.endsWith(".yml"))) {
|
|
207
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Workflow configuration format is known.
|
|
208
|
-
const workflowOn = (yamlParse(fs.readFileSync(path.resolve(workflowsPath, workflowFile)).toString()) as WorkflowConfiguration).on;
|
|
209
|
-
|
|
210
|
-
if (workflowOn.push !== undefined && (workflowOn.push.branches === undefined || workflowOn.push.branches.includes("main"))) {
|
|
211
|
-
logger.debug("Repository has push workflow");
|
|
212
|
-
|
|
213
|
-
hasPushWorkflow = true;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (workflowOn.release !== undefined && (workflowOn.release.types === undefined || workflowOn.release.types.includes("published"))) {
|
|
217
|
-
logger.debug("Repository has release workflow");
|
|
218
|
-
|
|
219
|
-
hasReleaseWorkflow = true;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Validate the workflow by waiting for it to complete.
|
|
226
|
-
*/
|
|
227
|
-
async function validateWorkflow(): Promise<void> {
|
|
228
|
-
const commitSHA = run(true, "git", "rev-parse", "HEAD")[0];
|
|
229
|
-
|
|
230
|
-
let completed = false;
|
|
231
|
-
let queryCount = 0;
|
|
232
|
-
let workflowRunID = -1;
|
|
233
|
-
|
|
234
|
-
do {
|
|
235
|
-
await util.promisify(setTimeout)(2000);
|
|
236
|
-
|
|
237
|
-
const response = await octokit.rest.actions.listWorkflowRunsForRepo({
|
|
238
|
-
...octokitParameterBase,
|
|
239
|
-
head_sha: commitSHA
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
for (const workflowRun of response.data.workflow_runs) {
|
|
243
|
-
if (workflowRun.status !== "completed") {
|
|
244
|
-
if (workflowRun.id === workflowRunID) {
|
|
245
|
-
process.stdout.write(".");
|
|
246
|
-
} else if (workflowRunID === -1) {
|
|
247
|
-
workflowRunID = workflowRun.id;
|
|
248
|
-
|
|
249
|
-
logger.info(`Workflow run ID ${workflowRunID}`);
|
|
250
|
-
} else {
|
|
251
|
-
throw new Error(`Parallel workflow runs for SHA ${commitSHA}`);
|
|
252
|
-
}
|
|
253
|
-
} else if (workflowRun.id === workflowRunID) {
|
|
254
|
-
process.stdout.write("\n");
|
|
255
|
-
|
|
256
|
-
if (workflowRun.conclusion !== "success") {
|
|
257
|
-
throw new Error(`Workflow ${workflowRun.conclusion}`);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
completed = true;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Abort if workflow run not started after 10 queries.
|
|
265
|
-
if (++queryCount === 10 && workflowRunID === -1) {
|
|
266
|
-
throw new Error(`Workflow run not started for SHA ${commitSHA}`);
|
|
267
|
-
}
|
|
268
|
-
} while (!completed);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
await runStep(repository, "install", () => {
|
|
272
|
-
run(false, "npm", "install");
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
await runStep(repository, "build", () => {
|
|
276
|
-
run(false, "npm", "run", "build", "--if-present");
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
await runStep(repository, "commit", () => {
|
|
280
|
-
run(false, "git", "commit", "--all", `--message=Updated to version ${packageConfiguration.version}.`);
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
await runStep(repository, "tag", () => {
|
|
284
|
-
run(false, "git", "tag", tag);
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
await runStep(repository, "push", () => {
|
|
288
|
-
run(false, "git", "push", "--atomic", "origin", "main", tag);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
if (hasPushWorkflow) {
|
|
292
|
-
await runStep(repository, "workflow (push)", async () => {
|
|
293
|
-
await validateWorkflow();
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
await runStep(repository, "release", async () => {
|
|
298
|
-
const versionSplit = packageConfiguration.version.split("-");
|
|
299
|
-
const prerelease = versionSplit.length !== 1;
|
|
300
|
-
|
|
301
|
-
await octokit.rest.repos.createRelease({
|
|
302
|
-
...octokitParameterBase,
|
|
303
|
-
tag_name: tag,
|
|
304
|
-
name: `${prerelease ? `${versionSplit[1].substring(0, 1).toUpperCase()}${versionSplit[1].substring(1)}` : "Production"} release ${versionSplit[0]}`,
|
|
305
|
-
prerelease
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
if (hasReleaseWorkflow) {
|
|
310
|
-
await runStep(repository, "workflow (release)", async () => {
|
|
311
|
-
await validateWorkflow();
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
await runStep(repository, "restore alpha", () => {
|
|
316
|
-
// Restore dependencies to "alpha" version for development.
|
|
317
|
-
const devDependenciesUpdated = updateDependencies(true, true, internal, packageConfiguration.devDependencies);
|
|
318
|
-
const dependenciesUpdated = updateDependencies(true, false, internal, packageConfiguration.dependencies);
|
|
319
|
-
|
|
320
|
-
if (devDependenciesUpdated || dependenciesUpdated) {
|
|
321
|
-
fs.writeFileSync(packageConfigurationPath, `${JSON.stringify(packageConfiguration, null, 2)}\n`);
|
|
322
|
-
run(false, "git", "commit", "--all", "--message=Restored alpha version.");
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
repository.lastExternalPublished = new Date().toISOString();
|
|
327
|
-
repository.lastExternalVersion = packageConfiguration.version;
|
|
328
|
-
repository.publishExternalStep = undefined;
|
|
329
|
-
}
|
|
330
|
-
}).catch((e: unknown) => {
|
|
331
|
-
logger.error(e);
|
|
332
|
-
});
|
package/src/publish-internal.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import { anyChanges, organizationRepository, type PackageConfiguration, publishRepositories } from "./publish";
|
|
3
|
-
import { logger, run } from "./utility.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Check dependencies for belonging to the organization; if not, check for updates and log a message if an update is
|
|
7
|
-
* available.
|
|
8
|
-
*
|
|
9
|
-
* @param dependencies
|
|
10
|
-
* Dependencies.
|
|
11
|
-
*
|
|
12
|
-
* @returns
|
|
13
|
-
* Dependencies belonging to the organization.
|
|
14
|
-
*/
|
|
15
|
-
function checkDependencyUpdates(dependencies?: Record<string, string>): string[] {
|
|
16
|
-
const organizationDependencies = [];
|
|
17
|
-
|
|
18
|
-
if (dependencies !== undefined) {
|
|
19
|
-
for (const [dependency, version] of Object.entries(dependencies)) {
|
|
20
|
-
if (organizationRepository(dependency) !== null) {
|
|
21
|
-
organizationDependencies.push(dependency);
|
|
22
|
-
} else if (version.startsWith("^")) {
|
|
23
|
-
const [latestVersion] = run(true, "npm", "view", dependency, "version");
|
|
24
|
-
|
|
25
|
-
if (latestVersion !== version.substring(1)) {
|
|
26
|
-
logger.info(`Dependency ${dependency}@${version} pending update to version ${latestVersion}.`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return organizationDependencies;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Convert a number to a zero-padded string.
|
|
37
|
-
*
|
|
38
|
-
* @param n
|
|
39
|
-
* Number.
|
|
40
|
-
*
|
|
41
|
-
* @param length
|
|
42
|
-
* Length of required string.
|
|
43
|
-
*
|
|
44
|
-
* @returns
|
|
45
|
-
* Zero-padded string.
|
|
46
|
-
*/
|
|
47
|
-
function zeroPadded(n: number, length: number): string {
|
|
48
|
-
return `${"0".repeat(length - 1)}${n}`.slice(-length);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
await publishRepositories((_name, repository) => {
|
|
52
|
-
const packageConfigurationPath = "package.json";
|
|
53
|
-
|
|
54
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Package configuration format is known.
|
|
55
|
-
const packageConfiguration: PackageConfiguration = JSON.parse(fs.readFileSync(packageConfigurationPath).toString());
|
|
56
|
-
|
|
57
|
-
// Check dependency updates, even if there are no changes.
|
|
58
|
-
const organizationDependencies = [...checkDependencyUpdates(packageConfiguration.devDependencies), ...checkDependencyUpdates(packageConfiguration.dependencies)];
|
|
59
|
-
|
|
60
|
-
if (organizationDependencies.length !== 0) {
|
|
61
|
-
logger.debug(`Updating organization dependencies ${JSON.stringify(organizationDependencies)}`);
|
|
62
|
-
|
|
63
|
-
run(false, "npm", "update", ...organizationDependencies);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Nothing further required if this repository is not a dependency.
|
|
67
|
-
if (repository.dependencyType !== "none" && anyChanges(repository, false)) {
|
|
68
|
-
const backupPackageConfigurationPath = ".package.json";
|
|
69
|
-
|
|
70
|
-
// Backup the package configuration file.
|
|
71
|
-
fs.renameSync(packageConfigurationPath, backupPackageConfigurationPath);
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
const now = new Date();
|
|
75
|
-
|
|
76
|
-
// Strip pre-release identifier if any.
|
|
77
|
-
const [semanticVersion] = packageConfiguration.version.split("-");
|
|
78
|
-
|
|
79
|
-
// Parse semantic version into its components.
|
|
80
|
-
const [majorVersion, minorVersion, patchVersion] = semanticVersion.split(".").map(versionString => Number(versionString));
|
|
81
|
-
|
|
82
|
-
// Set version to alpha version with incremental patch version number.
|
|
83
|
-
packageConfiguration.version = `${majorVersion}.${minorVersion}.${patchVersion + 1}-alpha.${now.getFullYear()}${zeroPadded(now.getMonth() + 1, 2)}${zeroPadded(now.getDate(), 2)}${zeroPadded(now.getHours(), 2)}${zeroPadded(now.getMinutes(), 2)}`;
|
|
84
|
-
|
|
85
|
-
// Update the package configuration for the build.
|
|
86
|
-
fs.writeFileSync(packageConfigurationPath, `${JSON.stringify(packageConfiguration, null, 2)}\n`);
|
|
87
|
-
|
|
88
|
-
// Run development build.
|
|
89
|
-
run(false, "npm", "run", "build:dev");
|
|
90
|
-
|
|
91
|
-
// Publish to development npm registry.
|
|
92
|
-
run(false, "npm", "publish", "--tag", "alpha");
|
|
93
|
-
|
|
94
|
-
// Unpublish all prior alpha versions.
|
|
95
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Output is a JSON array.
|
|
96
|
-
for (const version of JSON.parse(run(true, "npm", "view", packageConfiguration.name, "versions", "--json").join("\n")) as string[]) {
|
|
97
|
-
if (/^[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+$/.test(version) && version !== packageConfiguration.version) {
|
|
98
|
-
run(false, "npm", "unpublish", `${packageConfiguration.name}@${version}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
repository.lastInternalPublished = now.toISOString();
|
|
103
|
-
} finally {
|
|
104
|
-
// Restore the package configuration file.
|
|
105
|
-
fs.rmSync(packageConfigurationPath);
|
|
106
|
-
fs.renameSync(backupPackageConfigurationPath, packageConfigurationPath);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}).catch((e: unknown) => {
|
|
110
|
-
logger.error(e);
|
|
111
|
-
});
|