@ankhorage/devtools 1.15.2 → 1.15.3
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 +1 -1
- package/dist/owner/synchronizeRenovateOwnerAsync.d.ts +1 -0
- package/dist/owner/synchronizeRenovateOwnerAsync.js +12 -0
- package/dist/tools/package/index.d.ts +5 -0
- package/dist/tools/package/index.js +27 -22
- package/dist/tools/workflows/files/ci.yml +1 -1
- package/dist/tools/workflows/index.js +4 -0
- package/dist/tools/workflows/readCurrentDoctorVersion.d.ts +2 -0
- package/dist/tools/workflows/readCurrentDoctorVersion.js +15 -0
- package/dist/tools/workflows/renderWorkflowAsync.d.ts +2 -1
- package/dist/tools/workflows/renderWorkflowAsync.js +3 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/devtools
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Shared tooling, repository automation, runtime policies, and agent standards for Ankhorage TypeScript projects
|
|
9
9
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/*** Synchronize or validate Renovate-owned Devtools policy artifacts. */
|
|
1
2
|
export declare function synchronizeRenovateOwnerAsync(operation: OwnerSyncOperation, targetDirectory: string, options?: OwnerSyncOptions): Promise<void>;
|
|
2
3
|
type OwnerSyncOperation = 'status' | 'sync';
|
|
3
4
|
interface OwnerSyncOptions {
|
|
@@ -4,8 +4,10 @@ import { dirname, resolve } from 'node:path';
|
|
|
4
4
|
import { applyBunRuntimePolicy } from '../policy/applyBunRuntimePolicy.js';
|
|
5
5
|
import { nodeRuntimePolicy } from '../policy/bunRuntimePolicy.js';
|
|
6
6
|
import { renderBunPolicyDocumentation } from '../policy/renderBunPolicyDocumentation.js';
|
|
7
|
+
import { readCurrentDoctorVersion } from '../tools/workflows/readCurrentDoctorVersion.js';
|
|
7
8
|
import { renderRenovateWorkflowAsync } from '../tools/workflows/renderRenovateWorkflowAsync.js';
|
|
8
9
|
import { renderWorkflowAsync } from '../tools/workflows/renderWorkflowAsync.js';
|
|
10
|
+
/*** Synchronize or validate Renovate-owned Devtools policy artifacts. */
|
|
9
11
|
export async function synchronizeRenovateOwnerAsync(operation, targetDirectory, options = {}) {
|
|
10
12
|
const target = resolve(targetDirectory);
|
|
11
13
|
const policy = await readTargetBunPolicyAsync(target);
|
|
@@ -23,12 +25,14 @@ export async function synchronizeRenovateOwnerAsync(operation, targetDirectory,
|
|
|
23
25
|
await (options.runLockfileAsync ?? runBunLockfileAsync)(operation, target);
|
|
24
26
|
}
|
|
25
27
|
}
|
|
28
|
+
/*** Assert that Renovate owner synchronization targets the Devtools repository. */
|
|
26
29
|
async function assertDevtoolsTargetAsync(targetDirectory) {
|
|
27
30
|
const manifest = JSON.parse(await readFile(resolve(targetDirectory, 'package.json'), 'utf8'));
|
|
28
31
|
if (!isRecord(manifest) || manifest.name !== '@ankhorage/devtools') {
|
|
29
32
|
throw new Error('The Renovate owner sync target must be @ankhorage/devtools.');
|
|
30
33
|
}
|
|
31
34
|
}
|
|
35
|
+
/*** Build the canonical owner-managed artifact definitions for the target repository. */
|
|
32
36
|
async function createManagedDefinitionsAsync(targetDirectory, policy) {
|
|
33
37
|
const manifest = JSON.parse(await readFile(resolve(targetDirectory, 'package.json'), 'utf8'));
|
|
34
38
|
if (!isRecord(manifest)) {
|
|
@@ -37,6 +41,7 @@ async function createManagedDefinitionsAsync(targetDirectory, policy) {
|
|
|
37
41
|
const readme = await readFile(resolve(targetDirectory, 'README.md'), 'utf8');
|
|
38
42
|
const workflowPolicy = {
|
|
39
43
|
bunVersion: policy.version,
|
|
44
|
+
doctorVersion: readCurrentDoctorVersion(),
|
|
40
45
|
nodeVersion: nodeRuntimePolicy.setupVersion,
|
|
41
46
|
};
|
|
42
47
|
return [
|
|
@@ -62,6 +67,7 @@ async function createManagedDefinitionsAsync(targetDirectory, policy) {
|
|
|
62
67
|
},
|
|
63
68
|
];
|
|
64
69
|
}
|
|
70
|
+
/*** Return owner-managed artifact paths whose current bytes differ from policy output. */
|
|
65
71
|
async function getOutdatedPathsAsync(targetDirectory, definitions) {
|
|
66
72
|
const results = await Promise.all(definitions.map(async ({ contents, relativePath }) => {
|
|
67
73
|
const current = await readFile(resolve(targetDirectory, relativePath), 'utf8').catch((error) => {
|
|
@@ -73,12 +79,15 @@ async function getOutdatedPathsAsync(targetDirectory, definitions) {
|
|
|
73
79
|
}));
|
|
74
80
|
return results.filter((relativePath) => relativePath !== null);
|
|
75
81
|
}
|
|
82
|
+
/*** Narrow an unknown error to a Node error carrying an error code. */
|
|
76
83
|
function isNodeError(error) {
|
|
77
84
|
return error instanceof Error && 'code' in error;
|
|
78
85
|
}
|
|
86
|
+
/*** Narrow an unknown JSON-like value to a non-array record. */
|
|
79
87
|
function isRecord(value) {
|
|
80
88
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
81
89
|
}
|
|
90
|
+
/*** Read the target repository's canonical Bun policy literals. */
|
|
82
91
|
async function readTargetBunPolicyAsync(targetDirectory) {
|
|
83
92
|
const contents = await readFile(resolve(targetDirectory, 'src/policy/bunRuntimePolicy.ts'), 'utf8');
|
|
84
93
|
const matches = [...contents.matchAll(BUN_VERSION_PATTERN)];
|
|
@@ -97,6 +106,7 @@ async function readTargetBunPolicyAsync(targetDirectory) {
|
|
|
97
106
|
version,
|
|
98
107
|
};
|
|
99
108
|
}
|
|
109
|
+
/*** Synchronize or validate the target Bun lockfile through Bun itself. */
|
|
100
110
|
async function runBunLockfileAsync(operation, targetDirectory) {
|
|
101
111
|
const args = [
|
|
102
112
|
'install',
|
|
@@ -118,9 +128,11 @@ async function runBunLockfileAsync(operation, targetDirectory) {
|
|
|
118
128
|
});
|
|
119
129
|
});
|
|
120
130
|
}
|
|
131
|
+
/*** Serialize a package manifest using repository formatting. */
|
|
121
132
|
function serializePackageManifest(manifest) {
|
|
122
133
|
return `${JSON.stringify(manifest, null, 2)}\n`;
|
|
123
134
|
}
|
|
135
|
+
/*** Write changed owner-managed artifacts while preserving byte-identical files. */
|
|
124
136
|
async function syncDefinitionsAsync(targetDirectory, definitions) {
|
|
125
137
|
for (const { contents, relativePath } of definitions) {
|
|
126
138
|
const targetPath = resolve(targetDirectory, relativePath);
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { ManagedFileStatus, ManagedFileSyncResult } from '../shared/managedFiles.js';
|
|
2
|
+
/*** Inspect whether the Devtools-owned package manifest contract is current. */
|
|
2
3
|
export declare function inspectPackageManifest(targetDirectory: string, devtoolsVersion: string): Promise<ManagedFileStatus>;
|
|
4
|
+
/*** Synchronize the Devtools-owned package manifest fields. */
|
|
3
5
|
export declare function syncPackageManifest(targetDirectory: string, devtoolsVersion: string, options: {
|
|
4
6
|
readonly dryRun: boolean;
|
|
5
7
|
}): Promise<ManagedFileSyncResult>;
|
|
8
|
+
/*** Apply the Devtools-owned package scripts, dependencies, and Bun runtime policy. */
|
|
6
9
|
export declare function applyManagedPackageContract(manifest: Record<string, unknown>, devtoolsVersion: string, changesetsConfigExists?: boolean): Record<string, unknown>;
|
|
10
|
+
/*** Check whether the Devtools-owned package manifest fields match current policy. */
|
|
7
11
|
export declare function isManagedPackageContractCurrent(manifest: Record<string, unknown>, devtoolsVersion: string, changesetsConfigExists?: boolean): boolean;
|
|
12
|
+
/*** Read the current Devtools package version used for consumer synchronization. */
|
|
8
13
|
export declare function readCurrentDevtoolsVersion(): string;
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Synchronize the consumer `package.json` contract owned by `@ankhorage/devtools`.
|
|
3
3
|
*
|
|
4
4
|
* Package synchronization is merge-aware. It installs the current `@ankhorage/devtools` version
|
|
5
|
-
* as a development dependency for
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `format`, `format:check`, and `knip:check` scripts are written.
|
|
5
|
+
* as a development dependency for every consumer, including `@ankhorage/ankh`. Individually
|
|
6
|
+
* installed toolchain packages that devtools now owns are removed, and the canonical `lint`,
|
|
7
|
+
* `lint:fix`, `format`, `format:check`, and `knip:check` scripts are written.
|
|
9
8
|
* Unrelated manifest fields, scripts, dependencies, and metadata are preserved.
|
|
10
9
|
*
|
|
11
10
|
* The Bun runtime policy is shared by every repository, including devtools itself. Devtools skips
|
|
@@ -25,7 +24,6 @@ import { bunRuntimePolicy } from '../../policy/bunRuntimePolicy.js';
|
|
|
25
24
|
import { changesetsPolicy } from '../../policy/changesetsPolicy.js';
|
|
26
25
|
const PACKAGE_PATH = 'package.json';
|
|
27
26
|
const DEVTOOLS_PACKAGE_NAME = '@ankhorage/devtools';
|
|
28
|
-
const ANKH_PACKAGE_NAME = '@ankhorage/ankh';
|
|
29
27
|
const BUN_TYPES_PACKAGE_NAME = '@types/bun';
|
|
30
28
|
const CHANGESETS_CONFIG_PATH = '.changeset/config.json';
|
|
31
29
|
const STANDARD_SCRIPTS = {
|
|
@@ -51,6 +49,7 @@ const DEVTOOLS_OWNED_DEV_DEPENDENCIES = [
|
|
|
51
49
|
'prettier',
|
|
52
50
|
'typescript-eslint',
|
|
53
51
|
];
|
|
52
|
+
/*** Inspect whether the Devtools-owned package manifest contract is current. */
|
|
54
53
|
export async function inspectPackageManifest(targetDirectory, devtoolsVersion) {
|
|
55
54
|
const snapshot = await readPackageManifest(targetDirectory);
|
|
56
55
|
if (!snapshot.exists) {
|
|
@@ -63,6 +62,7 @@ export async function inspectPackageManifest(targetDirectory, devtoolsVersion) {
|
|
|
63
62
|
: 'outdated',
|
|
64
63
|
};
|
|
65
64
|
}
|
|
65
|
+
/*** Synchronize the Devtools-owned package manifest fields. */
|
|
66
66
|
export async function syncPackageManifest(targetDirectory, devtoolsVersion, options) {
|
|
67
67
|
const snapshot = await readPackageManifest(targetDirectory);
|
|
68
68
|
if (snapshot.exists &&
|
|
@@ -82,6 +82,7 @@ export async function syncPackageManifest(targetDirectory, devtoolsVersion, opti
|
|
|
82
82
|
action: snapshot.exists ? 'updated' : 'created',
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
+
/*** Apply the Devtools-owned package scripts, dependencies, and Bun runtime policy. */
|
|
85
86
|
export function applyManagedPackageContract(manifest, devtoolsVersion, changesetsConfigExists = false) {
|
|
86
87
|
if (manifest.name === DEVTOOLS_PACKAGE_NAME) {
|
|
87
88
|
return applyBunRuntimePolicy(manifest, bunRuntimePolicy);
|
|
@@ -97,7 +98,7 @@ export function applyManagedPackageContract(manifest, devtoolsVersion, changeset
|
|
|
97
98
|
const dependencies = toRecord(manifest.dependencies);
|
|
98
99
|
delete dependencies[changesetsPolicy.packageName];
|
|
99
100
|
delete devDependencies[changesetsPolicy.packageName];
|
|
100
|
-
applyDevtoolsDependencyPlacement(
|
|
101
|
+
applyDevtoolsDependencyPlacement(dependencies, devDependencies, devtoolsVersion);
|
|
101
102
|
return applyBunRuntimePolicy({
|
|
102
103
|
...manifest,
|
|
103
104
|
...normalizedDependencies(manifest, dependencies),
|
|
@@ -105,6 +106,7 @@ export function applyManagedPackageContract(manifest, devtoolsVersion, changeset
|
|
|
105
106
|
devDependencies,
|
|
106
107
|
}, bunRuntimePolicy);
|
|
107
108
|
}
|
|
109
|
+
/*** Check whether the Devtools-owned package manifest fields match current policy. */
|
|
108
110
|
export function isManagedPackageContractCurrent(manifest, devtoolsVersion, changesetsConfigExists = false) {
|
|
109
111
|
if (!hasCurrentBunRuntimePolicy(manifest)) {
|
|
110
112
|
return false;
|
|
@@ -121,8 +123,9 @@ export function isManagedPackageContractCurrent(manifest, devtoolsVersion, chang
|
|
|
121
123
|
dependencies[changesetsPolicy.packageName] === undefined &&
|
|
122
124
|
devDependencies[changesetsPolicy.packageName] === undefined &&
|
|
123
125
|
hasCurrentChangesetsScripts(scripts, changesetsEnabled) &&
|
|
124
|
-
hasCurrentDevtoolsDependencyPlacement(
|
|
126
|
+
hasCurrentDevtoolsDependencyPlacement(dependencies, devDependencies, devtoolsVersion));
|
|
125
127
|
}
|
|
128
|
+
/*** Read the current Devtools package version used for consumer synchronization. */
|
|
126
129
|
export function readCurrentDevtoolsVersion() {
|
|
127
130
|
const parsed = JSON.parse(readFileSync(new URL('../../../package.json', import.meta.url), 'utf8'));
|
|
128
131
|
if (!isRecord(parsed) || typeof parsed.version !== 'string' || parsed.version.trim() === '') {
|
|
@@ -130,6 +133,7 @@ export function readCurrentDevtoolsVersion() {
|
|
|
130
133
|
}
|
|
131
134
|
return parsed.version;
|
|
132
135
|
}
|
|
136
|
+
/*** Read one package manifest snapshot and Changesets applicability state. */
|
|
133
137
|
async function readPackageManifest(targetDirectory) {
|
|
134
138
|
const changesetsConfigExists = existsSync(resolve(targetDirectory, CHANGESETS_CONFIG_PATH));
|
|
135
139
|
try {
|
|
@@ -147,62 +151,63 @@ async function readPackageManifest(targetDirectory) {
|
|
|
147
151
|
throw error;
|
|
148
152
|
}
|
|
149
153
|
}
|
|
154
|
+
/*** Check the Bun package manager and Bun type dependency contract. */
|
|
150
155
|
function hasCurrentBunRuntimePolicy(manifest) {
|
|
151
156
|
const devDependencies = toRecord(manifest.devDependencies);
|
|
152
157
|
return (manifest.packageManager === bunRuntimePolicy.packageManager &&
|
|
153
158
|
devDependencies[BUN_TYPES_PACKAGE_NAME] === bunRuntimePolicy.typesRange);
|
|
154
159
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
dependencies[DEVTOOLS_PACKAGE_NAME] = versionRange;
|
|
159
|
-
delete devDependencies[DEVTOOLS_PACKAGE_NAME];
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
devDependencies[DEVTOOLS_PACKAGE_NAME] = versionRange;
|
|
160
|
+
/*** Place Devtools in development dependencies for every consuming repository. */
|
|
161
|
+
function applyDevtoolsDependencyPlacement(dependencies, devDependencies, devtoolsVersion) {
|
|
162
|
+
devDependencies[DEVTOOLS_PACKAGE_NAME] = `^${devtoolsVersion}`;
|
|
163
163
|
delete dependencies[DEVTOOLS_PACKAGE_NAME];
|
|
164
164
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return (dependencies[DEVTOOLS_PACKAGE_NAME] === versionRange &&
|
|
169
|
-
devDependencies[DEVTOOLS_PACKAGE_NAME] === undefined);
|
|
170
|
-
}
|
|
171
|
-
return (devDependencies[DEVTOOLS_PACKAGE_NAME] === versionRange &&
|
|
165
|
+
/*** Check that Devtools is development-only at the current synchronized version. */
|
|
166
|
+
function hasCurrentDevtoolsDependencyPlacement(dependencies, devDependencies, devtoolsVersion) {
|
|
167
|
+
return (devDependencies[DEVTOOLS_PACKAGE_NAME] === `^${devtoolsVersion}` &&
|
|
172
168
|
dependencies[DEVTOOLS_PACKAGE_NAME] === undefined);
|
|
173
169
|
}
|
|
170
|
+
/*** Remove direct development dependencies owned by the Devtools package. */
|
|
174
171
|
function removeOwnedDependencies(devDependencies) {
|
|
175
172
|
for (const dependencyName of DEVTOOLS_OWNED_DEV_DEPENDENCIES) {
|
|
176
173
|
delete devDependencies[dependencyName];
|
|
177
174
|
}
|
|
178
175
|
return devDependencies;
|
|
179
176
|
}
|
|
177
|
+
/*** Preserve an existing dependencies object or omit a newly empty one. */
|
|
180
178
|
function normalizedDependencies(manifest, dependencies) {
|
|
181
179
|
return Object.keys(dependencies).length === 0 && manifest.dependencies === undefined
|
|
182
180
|
? {}
|
|
183
181
|
: { dependencies };
|
|
184
182
|
}
|
|
183
|
+
/*** Check the canonical development-tool scripts. */
|
|
185
184
|
function hasStandardScripts(scripts) {
|
|
186
185
|
return (scripts.knip === undefined &&
|
|
187
186
|
Object.entries(STANDARD_SCRIPTS).every(([name, command]) => scripts[name] === command));
|
|
188
187
|
}
|
|
188
|
+
/*** Check Changesets scripts when the repository participates in Changesets. */
|
|
189
189
|
function hasCurrentChangesetsScripts(scripts, changesetsEnabled) {
|
|
190
190
|
return (!changesetsEnabled ||
|
|
191
191
|
Object.entries(changesetsPolicy.packageScripts).every(([name, command]) => scripts[name] === command));
|
|
192
192
|
}
|
|
193
|
+
/*** Determine whether the repository participates in Changesets synchronization. */
|
|
193
194
|
function isChangesetsEnabled(scripts, changesetsConfigExists) {
|
|
194
195
|
return (changesetsConfigExists ||
|
|
195
196
|
Object.keys(changesetsPolicy.packageScripts).some((scriptName) => scripts[scriptName] !== undefined));
|
|
196
197
|
}
|
|
198
|
+
/*** Serialize a package manifest using the repository formatting contract. */
|
|
197
199
|
function serializePackageManifest(manifest) {
|
|
198
200
|
return `${JSON.stringify(manifest, null, 2)}\n`;
|
|
199
201
|
}
|
|
202
|
+
/*** Copy a JSON-like value to a mutable record or return an empty record. */
|
|
200
203
|
function toRecord(value) {
|
|
201
204
|
return isRecord(value) ? { ...value } : {};
|
|
202
205
|
}
|
|
206
|
+
/*** Narrow an unknown JSON-like value to a non-array record. */
|
|
203
207
|
function isRecord(value) {
|
|
204
208
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
205
209
|
}
|
|
210
|
+
/*** Narrow an unknown error to a Node error carrying an error code. */
|
|
206
211
|
function isNodeError(error) {
|
|
207
212
|
return error instanceof Error && 'code' in error;
|
|
208
213
|
}
|
|
@@ -2,6 +2,7 @@ import { access } from 'node:fs/promises';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { resolveApmReleaseCommandAsync } from '../../features/apm-release-validation/adapters/outbound/resolveApmReleaseCommandAsync.js';
|
|
4
4
|
import { bunRuntimePolicy, nodeRuntimePolicy } from '../../policy/bunRuntimePolicy.js';
|
|
5
|
+
import { readCurrentDoctorVersion } from './readCurrentDoctorVersion.js';
|
|
5
6
|
import { renderRenovateWorkflowAsync } from './renderRenovateWorkflowAsync.js';
|
|
6
7
|
import { renderWorkflowAsync } from './renderWorkflowAsync.js';
|
|
7
8
|
export const workflowManagedFiles = [
|
|
@@ -27,6 +28,7 @@ export const workflowManagedFiles = [
|
|
|
27
28
|
mode: 'create-only',
|
|
28
29
|
},
|
|
29
30
|
];
|
|
31
|
+
/*** Create a managed workflow definition rendered from current shared runtime policies. */
|
|
30
32
|
function createWorkflowDefinition(relativePath, sourcePath) {
|
|
31
33
|
const sourceUrl = new URL(sourcePath, import.meta.url);
|
|
32
34
|
return {
|
|
@@ -34,6 +36,7 @@ function createWorkflowDefinition(relativePath, sourcePath) {
|
|
|
34
36
|
render: async (targetDirectory) => await renderWorkflowAsync(sourceUrl, {
|
|
35
37
|
apmReleaseCommand: await resolveApmReleaseCommandAsync(targetDirectory),
|
|
36
38
|
bunVersion: bunRuntimePolicy.version,
|
|
39
|
+
doctorVersion: readCurrentDoctorVersion(),
|
|
37
40
|
nodeVersion: nodeRuntimePolicy.setupVersion,
|
|
38
41
|
}),
|
|
39
42
|
};
|
|
@@ -46,6 +49,7 @@ function createRenovateWorkflowDefinition() {
|
|
|
46
49
|
render: async (targetDirectory) => await renderRenovateWorkflowAsync(sourceUrl, targetDirectory, {
|
|
47
50
|
apmReleaseCommand: await resolveApmReleaseCommandAsync(targetDirectory),
|
|
48
51
|
bunVersion: bunRuntimePolicy.version,
|
|
52
|
+
doctorVersion: readCurrentDoctorVersion(),
|
|
49
53
|
nodeVersion: nodeRuntimePolicy.setupVersion,
|
|
50
54
|
}),
|
|
51
55
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { isRecord } from '@ankhorage/utility/object';
|
|
3
|
+
const DOCTOR_PACKAGE_NAME = '@ankhorage/doctor';
|
|
4
|
+
/*** Read the exact Doctor version owned by the current Devtools package release. */
|
|
5
|
+
export function readCurrentDoctorVersion() {
|
|
6
|
+
const parsed = JSON.parse(readFileSync(new URL('../../../package.json', import.meta.url), 'utf8'));
|
|
7
|
+
if (!isRecord(parsed) || !isRecord(parsed.devDependencies)) {
|
|
8
|
+
throw new Error('Devtools package.json must define development dependencies.');
|
|
9
|
+
}
|
|
10
|
+
const version = parsed.devDependencies[DOCTOR_PACKAGE_NAME];
|
|
11
|
+
if (typeof version !== 'string' || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(version)) {
|
|
12
|
+
throw new Error(`Devtools must pin ${DOCTOR_PACKAGE_NAME} to one exact version.`);
|
|
13
|
+
}
|
|
14
|
+
return version;
|
|
15
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export interface WorkflowPolicy {
|
|
2
2
|
readonly bunVersion: string;
|
|
3
|
+
readonly doctorVersion: string;
|
|
3
4
|
readonly nodeVersion: string;
|
|
4
5
|
readonly apmReleaseCommand?: string;
|
|
5
6
|
}
|
|
6
|
-
/*** Renders one workflow template with the canonical runtime and Changesets policy. */
|
|
7
|
+
/*** Renders one workflow template with the canonical runtime, Doctor, and Changesets policy. */
|
|
7
8
|
export declare function renderWorkflowAsync(sourceUrl: URL, policy: WorkflowPolicy): Promise<string>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { changesetsPolicy } from '../../policy/changesetsPolicy.js';
|
|
3
|
-
/*** Renders one workflow template with the canonical runtime and Changesets policy. */
|
|
3
|
+
/*** Renders one workflow template with the canonical runtime, Doctor, and Changesets policy. */
|
|
4
4
|
export async function renderWorkflowAsync(sourceUrl, policy) {
|
|
5
5
|
const template = await readFile(sourceUrl, 'utf8');
|
|
6
6
|
return template
|
|
@@ -8,6 +8,7 @@ export async function renderWorkflowAsync(sourceUrl, policy) {
|
|
|
8
8
|
.replaceAll(CHANGESETS_PUBLISH_COMMAND_TOKEN, changesetsPolicy.workflowCommands.publish)
|
|
9
9
|
.replaceAll(CHANGESETS_STATUS_COMMAND_TOKEN, changesetsPolicy.workflowCommands.status)
|
|
10
10
|
.replaceAll(CHANGESETS_VERSION_COMMAND_TOKEN, changesetsPolicy.workflowCommands.version)
|
|
11
|
+
.replaceAll(DOCTOR_VERSION_TOKEN, policy.doctorVersion)
|
|
11
12
|
.replaceAll('__ANKH_APM_RELEASE_COMMAND__', policy.apmReleaseCommand ?? './node_modules/.bin/ankhorage-apm-release')
|
|
12
13
|
.replaceAll(NODE_VERSION_TOKEN, policy.nodeVersion);
|
|
13
14
|
}
|
|
@@ -15,4 +16,5 @@ const BUN_VERSION_TOKEN = '__ANKH_BUN_VERSION__';
|
|
|
15
16
|
const CHANGESETS_PUBLISH_COMMAND_TOKEN = '__ANKH_CHANGESETS_PUBLISH_COMMAND__';
|
|
16
17
|
const CHANGESETS_STATUS_COMMAND_TOKEN = '__ANKH_CHANGESETS_STATUS_COMMAND__';
|
|
17
18
|
const CHANGESETS_VERSION_COMMAND_TOKEN = '__ANKH_CHANGESETS_VERSION_COMMAND__';
|
|
19
|
+
const DOCTOR_VERSION_TOKEN = '__ANKH_DOCTOR_VERSION__';
|
|
18
20
|
const NODE_VERSION_TOKEN = '__ANKH_NODE_VERSION__';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/devtools",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.3",
|
|
4
4
|
"description": "Shared tooling, repository automation, runtime policies, and agent standards for Ankhorage TypeScript projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/devtools#readme",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"devDependencies": {
|
|
145
145
|
"@ankhorage/paradox": "^0.1.26",
|
|
146
146
|
"@ankhorage/ankh": "^0.8.11",
|
|
147
|
-
"@ankhorage/doctor": "0.10.
|
|
147
|
+
"@ankhorage/doctor": "0.10.14",
|
|
148
148
|
"@techstark/opencv-js": "^5.0.0-release.1",
|
|
149
149
|
"@types/bun": "^1.4.1",
|
|
150
150
|
"@types/node": "^26.4.1",
|