@aidc-toolkit/dev 0.9.18-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 -30
- 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 -96
- 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 +13 -11
- 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 -58
- package/dist/utility.js.map +0 -1
- package/src/publish-external.ts +0 -362
- package/src/publish-internal.ts +0 -174
- package/src/publish.ts +0 -287
- package/src/utility.ts +0 -60
|
@@ -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,CA2BxF"}
|
package/dist/utility.js
DELETED
|
@@ -1,58 +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.trace(`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
|
-
// Last line is also terminated by newline and split() places empty string at the end, so use slice() to remove it.
|
|
52
|
-
const output = captureOutput ? spawnResult.stdout.toString().split("\n").slice(0, -1) : [];
|
|
53
|
-
if (captureOutput) {
|
|
54
|
-
logger.trace(`Output is ${JSON.stringify(output)}.`);
|
|
55
|
-
}
|
|
56
|
-
return output;
|
|
57
|
-
}
|
|
58
|
-
//# 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,mHAAmH;IACnH,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,362 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { setTimeout } from "node:timers/promises";
|
|
4
|
-
import { Octokit } from "octokit";
|
|
5
|
-
import { parse as yamlParse } from "yaml";
|
|
6
|
-
import {
|
|
7
|
-
anyChanges,
|
|
8
|
-
commitConfiguration,
|
|
9
|
-
configuration,
|
|
10
|
-
organizationRepository,
|
|
11
|
-
type PackageConfiguration,
|
|
12
|
-
publishRepositories,
|
|
13
|
-
type Repository,
|
|
14
|
-
saveConfiguration,
|
|
15
|
-
secureConfiguration
|
|
16
|
-
} from "./publish";
|
|
17
|
-
import { logger, run } from "./utility.js";
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Configuration layout of release.yml workflow (relevant attributes only).
|
|
21
|
-
*/
|
|
22
|
-
interface WorkflowConfiguration {
|
|
23
|
-
/**
|
|
24
|
-
* Workflow name.
|
|
25
|
-
*/
|
|
26
|
-
name: string;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Workflow trigger.
|
|
30
|
-
*/
|
|
31
|
-
on: {
|
|
32
|
-
/**
|
|
33
|
-
* Push trigger.
|
|
34
|
-
*/
|
|
35
|
-
push?: {
|
|
36
|
-
/**
|
|
37
|
-
* Push branches.
|
|
38
|
-
*/
|
|
39
|
-
branches?: string[];
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Release trigger.
|
|
44
|
-
*/
|
|
45
|
-
release?: {
|
|
46
|
-
/**
|
|
47
|
-
* Release types.
|
|
48
|
-
*/
|
|
49
|
-
types?: string[];
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Supported steps.
|
|
56
|
-
*/
|
|
57
|
-
type Step = "skipped" | "install" | "build" | "commit" | "tag" | "push" | "workflow (push)" | "release" | "workflow (release)" | "restore alpha" | "complete";
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Execute a step.
|
|
61
|
-
*
|
|
62
|
-
* @param repository
|
|
63
|
-
* Repository.
|
|
64
|
-
*
|
|
65
|
-
* @param step
|
|
66
|
-
* State at which step takes place.
|
|
67
|
-
*
|
|
68
|
-
* @param callback
|
|
69
|
-
* Callback to execute step.
|
|
70
|
-
*
|
|
71
|
-
* @returns
|
|
72
|
-
* Promise.
|
|
73
|
-
*/
|
|
74
|
-
async function runStep(repository: Repository, step: Step, callback: () => (void | Promise<void>)): Promise<void> {
|
|
75
|
-
if (repository.publishExternalStep === undefined || repository.publishExternalStep === step) {
|
|
76
|
-
logger.debug(`Running step ${step}`);
|
|
77
|
-
|
|
78
|
-
repository.publishExternalStep = step;
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
const result = callback();
|
|
82
|
-
|
|
83
|
-
if (result instanceof Promise) {
|
|
84
|
-
await result;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
repository.publishExternalStep = undefined;
|
|
88
|
-
} finally {
|
|
89
|
-
saveConfiguration();
|
|
90
|
-
}
|
|
91
|
-
} else {
|
|
92
|
-
logger.debug(`Skipping step ${step}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Update dependencies from the organization.
|
|
98
|
-
*
|
|
99
|
-
* @param restoreAlpha
|
|
100
|
-
* If true, restore "alpha" as the version for development.
|
|
101
|
-
*
|
|
102
|
-
* @param development
|
|
103
|
-
* True if updating development dependencies.
|
|
104
|
-
*
|
|
105
|
-
* @param internal
|
|
106
|
-
* True if the package is for internal use only and its version should not be used in dependencies.
|
|
107
|
-
*
|
|
108
|
-
* @param dependencies
|
|
109
|
-
* Dependencies.
|
|
110
|
-
*
|
|
111
|
-
* @returns
|
|
112
|
-
* True if any dependencies were updated.
|
|
113
|
-
*/
|
|
114
|
-
function updateDependencies(restoreAlpha: boolean, development: boolean, internal: boolean | undefined, dependencies: Record<string, string> | undefined): boolean {
|
|
115
|
-
let anyUpdated = false;
|
|
116
|
-
|
|
117
|
-
if (dependencies !== undefined) {
|
|
118
|
-
// eslint-disable-next-line guard-for-in -- Dependency record type is shallow.
|
|
119
|
-
for (const dependency in dependencies) {
|
|
120
|
-
const dependencyRepositoryName = organizationRepository(dependency);
|
|
121
|
-
|
|
122
|
-
if (dependencyRepositoryName !== null) {
|
|
123
|
-
const dependencyRepository = configuration.repositories[dependencyRepositoryName];
|
|
124
|
-
|
|
125
|
-
// Set to explicit version for external dependency.
|
|
126
|
-
if (dependencyRepository.dependencyType === "external") {
|
|
127
|
-
dependencies[dependency] = !restoreAlpha ? `^${dependencyRepository.lastExternalVersion}` : "alpha";
|
|
128
|
-
anyUpdated = true;
|
|
129
|
-
} else if (!restoreAlpha && !development && internal !== true) {
|
|
130
|
-
throw new Error("Internal dependency specified for external package");
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return anyUpdated;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const octokit = new Octokit({
|
|
140
|
-
auth: secureConfiguration.token,
|
|
141
|
-
userAgent: `${configuration.organization} release`
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
await publishRepositories(async (name, repository) => {
|
|
145
|
-
const packageConfigurationPath = "package.json";
|
|
146
|
-
|
|
147
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Package configuration format is known.
|
|
148
|
-
const packageConfiguration = JSON.parse(fs.readFileSync(packageConfigurationPath).toString()) as PackageConfiguration;
|
|
149
|
-
|
|
150
|
-
let packageVersion = packageConfiguration.version;
|
|
151
|
-
|
|
152
|
-
const packageVersionSplits = packageVersion.split("-");
|
|
153
|
-
|
|
154
|
-
// Extract semantic version and pre-release identifier.
|
|
155
|
-
const semanticVersion = packageVersionSplits[0];
|
|
156
|
-
const preReleaseIdentifier = packageVersionSplits.length !== 1 ? `-${packageVersionSplits[1]}` : "";
|
|
157
|
-
|
|
158
|
-
// Parse semantic version into its components.
|
|
159
|
-
const [majorVersion, minorVersion, patchVersion] = semanticVersion.split(".").map(versionString => Number(versionString));
|
|
160
|
-
|
|
161
|
-
// Local code must be on branch matching version.
|
|
162
|
-
const branch = run(true, "git", "branch", "--show-current")[0];
|
|
163
|
-
if (branch !== `v${majorVersion}.${minorVersion}`) {
|
|
164
|
-
throw new Error(`Repository must be on version branch ${branch}`);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
let publish: boolean;
|
|
168
|
-
|
|
169
|
-
switch (repository.publishExternalStep) {
|
|
170
|
-
case undefined:
|
|
171
|
-
// Check for publish external always is done afterward so that check for uncommitted files can be done.
|
|
172
|
-
publish = anyChanges(repository, true) || repository.publishExternalAlways === true;
|
|
173
|
-
|
|
174
|
-
if (publish && anyChanges(repository, false)) {
|
|
175
|
-
throw new Error("Repository has internal changes that have not been published");
|
|
176
|
-
}
|
|
177
|
-
break;
|
|
178
|
-
|
|
179
|
-
case "complete":
|
|
180
|
-
// Previous publication succeeded but subsequent repository failed; skip this repository.
|
|
181
|
-
publish = false;
|
|
182
|
-
break;
|
|
183
|
-
|
|
184
|
-
default:
|
|
185
|
-
// Previous publication failed.
|
|
186
|
-
publish = true;
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (packageVersion !== repository.lastExternalVersion) {
|
|
191
|
-
// Package version has already been updated, either manually or by previous failed run.
|
|
192
|
-
publish = true;
|
|
193
|
-
} else if (publish) {
|
|
194
|
-
// Increment patch version number.
|
|
195
|
-
packageVersion = `${majorVersion}.${minorVersion}.${patchVersion + 1}${preReleaseIdentifier}`;
|
|
196
|
-
packageConfiguration.version = packageVersion;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const tag = `v${packageVersion}`;
|
|
200
|
-
|
|
201
|
-
const octokitParameterBase = {
|
|
202
|
-
owner: configuration.organization,
|
|
203
|
-
repo: name
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const internal = repository.dependencyType === "internal";
|
|
207
|
-
|
|
208
|
-
if (publish) {
|
|
209
|
-
if (repository.publishExternalStep === undefined) {
|
|
210
|
-
updateDependencies(false, true, internal, packageConfiguration.devDependencies);
|
|
211
|
-
updateDependencies(false, false, internal, packageConfiguration.dependencies);
|
|
212
|
-
|
|
213
|
-
fs.writeFileSync(packageConfigurationPath, `${JSON.stringify(packageConfiguration, null, 2)}\n`);
|
|
214
|
-
} else {
|
|
215
|
-
logger.debug(`Repository failed at step ${repository.publishExternalStep} on prior run`);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const workflowsPath = ".github/workflows/";
|
|
219
|
-
|
|
220
|
-
let hasPushWorkflow = false;
|
|
221
|
-
let hasReleaseWorkflow = false;
|
|
222
|
-
|
|
223
|
-
if (fs.existsSync(workflowsPath)) {
|
|
224
|
-
logger.debug("Checking workflows");
|
|
225
|
-
|
|
226
|
-
for (const workflowFile of fs.readdirSync(workflowsPath).filter(workflowFile => workflowFile.endsWith(".yml"))) {
|
|
227
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Workflow configuration format is known.
|
|
228
|
-
const workflowOn = (yamlParse(fs.readFileSync(path.resolve(workflowsPath, workflowFile)).toString()) as WorkflowConfiguration).on;
|
|
229
|
-
|
|
230
|
-
if (workflowOn.push !== undefined && (workflowOn.push.branches === undefined || workflowOn.push.branches.includes("v*"))) {
|
|
231
|
-
logger.debug("Repository has push workflow");
|
|
232
|
-
|
|
233
|
-
hasPushWorkflow = true;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (workflowOn.release !== undefined && (workflowOn.release.types === undefined || workflowOn.release.types.includes("published"))) {
|
|
237
|
-
logger.debug("Repository has release workflow");
|
|
238
|
-
|
|
239
|
-
hasReleaseWorkflow = true;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Validate the workflow by waiting for it to complete.
|
|
246
|
-
*/
|
|
247
|
-
async function validateWorkflow(): Promise<void> {
|
|
248
|
-
const commitSHA = run(true, "git", "rev-parse", "HEAD")[0];
|
|
249
|
-
|
|
250
|
-
let completed = false;
|
|
251
|
-
let queryCount = 0;
|
|
252
|
-
let workflowRunID = -1;
|
|
253
|
-
|
|
254
|
-
do {
|
|
255
|
-
await setTimeout(2000);
|
|
256
|
-
|
|
257
|
-
const response = await octokit.rest.actions.listWorkflowRunsForRepo({
|
|
258
|
-
...octokitParameterBase,
|
|
259
|
-
head_sha: commitSHA
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
for (const workflowRun of response.data.workflow_runs) {
|
|
263
|
-
if (workflowRun.status !== "completed") {
|
|
264
|
-
if (workflowRun.id === workflowRunID) {
|
|
265
|
-
process.stdout.write(".");
|
|
266
|
-
} else if (workflowRunID === -1) {
|
|
267
|
-
workflowRunID = workflowRun.id;
|
|
268
|
-
|
|
269
|
-
logger.info(`Workflow run ID ${workflowRunID}`);
|
|
270
|
-
} else {
|
|
271
|
-
throw new Error(`Parallel workflow runs for SHA ${commitSHA}`);
|
|
272
|
-
}
|
|
273
|
-
} else if (workflowRun.id === workflowRunID) {
|
|
274
|
-
process.stdout.write("\n");
|
|
275
|
-
|
|
276
|
-
if (workflowRun.conclusion !== "success") {
|
|
277
|
-
throw new Error(`Workflow ${workflowRun.conclusion}`);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
completed = true;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Abort if workflow run not started after 10 queries.
|
|
285
|
-
if (++queryCount === 10 && workflowRunID === -1) {
|
|
286
|
-
throw new Error(`Workflow run not started for SHA ${commitSHA}`);
|
|
287
|
-
}
|
|
288
|
-
} while (!completed);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
await runStep(repository, "install", () => {
|
|
292
|
-
run(false, "npm", "install");
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
await runStep(repository, "build", () => {
|
|
296
|
-
run(false, "npm", "run", "build:release", "--if-present");
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
await runStep(repository, "commit", () => {
|
|
300
|
-
run(false, "git", "commit", "--all", "--message", `Updated to version ${packageVersion}.`);
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
await runStep(repository, "tag", () => {
|
|
304
|
-
run(false, "git", "tag", tag);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
await runStep(repository, "push", () => {
|
|
308
|
-
run(false, "git", "push", "--atomic", "origin", branch, tag);
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
if (hasPushWorkflow) {
|
|
312
|
-
await runStep(repository, "workflow (push)", async () => {
|
|
313
|
-
await validateWorkflow();
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
await runStep(repository, "release", async () => {
|
|
318
|
-
const versionSplit = packageVersion.split("-");
|
|
319
|
-
const prerelease = versionSplit.length !== 1;
|
|
320
|
-
|
|
321
|
-
await octokit.rest.repos.createRelease({
|
|
322
|
-
...octokitParameterBase,
|
|
323
|
-
tag_name: tag,
|
|
324
|
-
name: `${prerelease ? `${versionSplit[1].substring(0, 1).toUpperCase()}${versionSplit[1].substring(1)}` : "Production"} release ${versionSplit[0]}`,
|
|
325
|
-
prerelease
|
|
326
|
-
});
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
if (hasReleaseWorkflow) {
|
|
330
|
-
await runStep(repository, "workflow (release)", async () => {
|
|
331
|
-
await validateWorkflow();
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
await runStep(repository, "restore alpha", () => {
|
|
336
|
-
// Restore dependencies to "alpha" version for development.
|
|
337
|
-
const devDependenciesUpdated = updateDependencies(true, true, internal, packageConfiguration.devDependencies);
|
|
338
|
-
const dependenciesUpdated = updateDependencies(true, false, internal, packageConfiguration.dependencies);
|
|
339
|
-
|
|
340
|
-
if (devDependenciesUpdated || dependenciesUpdated) {
|
|
341
|
-
fs.writeFileSync(packageConfigurationPath, `${JSON.stringify(packageConfiguration, null, 2)}\n`);
|
|
342
|
-
|
|
343
|
-
run(false, "git", "commit", packageConfigurationPath, "--message", "Restored alpha versions to organization dependencies.");
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
repository.lastExternalPublished = new Date().toISOString();
|
|
348
|
-
repository.lastExternalVersion = packageVersion;
|
|
349
|
-
repository.publishExternalStep = "complete";
|
|
350
|
-
}
|
|
351
|
-
}).then(() => {
|
|
352
|
-
// Publication complete; reset steps to undefined for next run.
|
|
353
|
-
for (const repository of Object.values(configuration.repositories)) {
|
|
354
|
-
repository.publishExternalStep = undefined;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
saveConfiguration();
|
|
358
|
-
|
|
359
|
-
commitConfiguration(true);
|
|
360
|
-
}).catch((e: unknown) => {
|
|
361
|
-
logger.error(e);
|
|
362
|
-
});
|