@mauvezero/azpipe-cli 0.2.0 → 0.4.0
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/dist/.tsbuildinfo +1 -1
- package/dist/bin.js +5 -0
- package/dist/bin.js.map +1 -1
- package/dist/cmd-bootstrap.d.ts +2 -0
- package/dist/cmd-bootstrap.d.ts.map +1 -0
- package/dist/cmd-bootstrap.js +502 -0
- package/dist/cmd-bootstrap.js.map +1 -0
- package/dist/cmd-build-import.js +1 -1
- package/dist/cmd-release-import.js +1 -1
- package/package.json +12 -8
package/dist/bin.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { runBuild } from './cmd-build.js';
|
|
3
3
|
import { runBuildImport } from './cmd-build-import.js';
|
|
4
4
|
import { runRelease } from './cmd-release.js';
|
|
5
|
+
import { runBootstrap } from './cmd-bootstrap.js';
|
|
5
6
|
function topLevelUsage() {
|
|
6
7
|
console.log(`azpipe <command> [options]
|
|
7
8
|
|
|
@@ -12,6 +13,7 @@ Commands:
|
|
|
12
13
|
release diff <entry.ts> Show what \`push\` would change
|
|
13
14
|
release push <entry.ts> Diff-first PUT (interactive by default)
|
|
14
15
|
release import <json> Convert a classic-release JSON to TypeScript
|
|
16
|
+
bootstrap Scaffold a pipelines/ directory in the current repo
|
|
15
17
|
|
|
16
18
|
Run \`azpipe <command> --help\` for command-specific options.`);
|
|
17
19
|
}
|
|
@@ -34,6 +36,9 @@ async function main() {
|
|
|
34
36
|
case 'release':
|
|
35
37
|
await runRelease(argv.slice(1));
|
|
36
38
|
return;
|
|
39
|
+
case 'bootstrap':
|
|
40
|
+
await runBootstrap(argv.slice(1));
|
|
41
|
+
return;
|
|
37
42
|
default:
|
|
38
43
|
console.error(`Unknown command: ${command}`);
|
|
39
44
|
topLevelUsage();
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,SAAS,aAAa;IACpB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;8DAWgD,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzD,aAAa,EAAE,CAAC;QAChB,OAAO;IACT,CAAC;IACD,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO;YACV,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACzB,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAChC,CAAC;YACD,OAAO;QACT,KAAK,SAAS;YACZ,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAChC,OAAO;QACT,KAAK,WAAW;YACd,MAAM,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,OAAO;QACT;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YAC7C,aAAa,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-bootstrap.d.ts","sourceRoot":"","sources":["../src/cmd-bootstrap.ts"],"names":[],"mappings":"AAgYA,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyKhE"}
|
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { createInterface } from 'node:readline';
|
|
4
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { yamlToTs } from '@mauvezero/azpipe-convert';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// CLI version — stamped into generated package.json
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const cliPkgJson = JSON.parse(readFileSync(resolve(here, '../package.json'), 'utf8'));
|
|
12
|
+
const CLI_VERSION = cliPkgJson.version;
|
|
13
|
+
function parseArgs(argv) {
|
|
14
|
+
const opts = { yes: false, outDir: 'pipelines', help: false };
|
|
15
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16
|
+
const a = argv[i];
|
|
17
|
+
if (a === '-h' || a === '--help')
|
|
18
|
+
opts.help = true;
|
|
19
|
+
else if (a === '--yes' || a === '-y')
|
|
20
|
+
opts.yes = true;
|
|
21
|
+
else if (a === '--out' || a === '-o')
|
|
22
|
+
opts.outDir = argv[++i] ?? opts.outDir;
|
|
23
|
+
else if (a.startsWith('-'))
|
|
24
|
+
throw new Error(`Unknown flag: ${a}`);
|
|
25
|
+
}
|
|
26
|
+
return opts;
|
|
27
|
+
}
|
|
28
|
+
function usage() {
|
|
29
|
+
console.log(`azpipe bootstrap [options]
|
|
30
|
+
|
|
31
|
+
Scaffold a pipelines/ directory in the current git repo with:
|
|
32
|
+
- pipelines/package.json (build / diff / push scripts)
|
|
33
|
+
- pipelines/tsconfig.json
|
|
34
|
+
- pipelines/README.md
|
|
35
|
+
- pipelines/azure-pipelines.ts (CI pipeline, converted from root yml if present)
|
|
36
|
+
- pipelines/release.ts (release definition stub)
|
|
37
|
+
- pipelines/release-sync.yml (YAML pipeline to diff/push releases)
|
|
38
|
+
- <root>/azure-pipelines.yml (generated from azure-pipelines.ts)
|
|
39
|
+
|
|
40
|
+
Options:
|
|
41
|
+
-o, --out <dir> Output directory relative to git root (default: pipelines)
|
|
42
|
+
-y, --yes Accept all defaults, skip interactive prompts
|
|
43
|
+
-h, --help Show this help`);
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Git helpers
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
function findGitRoot(from) {
|
|
49
|
+
let dir = isAbsolute(from) ? from : resolve(process.cwd(), from);
|
|
50
|
+
while (true) {
|
|
51
|
+
if (existsSync(join(dir, '.git')))
|
|
52
|
+
return dir;
|
|
53
|
+
const parent = dirname(dir);
|
|
54
|
+
if (parent === dir)
|
|
55
|
+
throw new Error('Not inside a git repository.');
|
|
56
|
+
dir = parent;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function tryExec(cmd) {
|
|
60
|
+
try {
|
|
61
|
+
return execSync(cmd, { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8' }).trim();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function detectDefaultBranch() {
|
|
68
|
+
const ref = tryExec('git symbolic-ref refs/remotes/origin/HEAD');
|
|
69
|
+
if (ref) {
|
|
70
|
+
const m = ref.match(/refs\/remotes\/origin\/(.+)/);
|
|
71
|
+
if (m?.[1])
|
|
72
|
+
return m[1];
|
|
73
|
+
}
|
|
74
|
+
// Fallback: look for common branch names
|
|
75
|
+
const branches = tryExec('git branch -r');
|
|
76
|
+
if (branches?.includes('origin/main'))
|
|
77
|
+
return 'main';
|
|
78
|
+
if (branches?.includes('origin/master'))
|
|
79
|
+
return 'master';
|
|
80
|
+
return 'main';
|
|
81
|
+
}
|
|
82
|
+
function detectFromGitRemote() {
|
|
83
|
+
const remote = tryExec('git remote get-url origin');
|
|
84
|
+
if (!remote)
|
|
85
|
+
return {};
|
|
86
|
+
// HTTPS: https://dev.azure.com/ORG/PROJECT/_git/REPO
|
|
87
|
+
const httpsMatch = remote.match(/dev\.azure\.com\/([^/]+)\/([^/]+)/);
|
|
88
|
+
if (httpsMatch)
|
|
89
|
+
return { org: httpsMatch[1], project: httpsMatch[2] };
|
|
90
|
+
// SSH: git@ssh.dev.azure.com:v3/ORG/PROJECT/REPO
|
|
91
|
+
const sshMatch = remote.match(/v3\/([^/]+)\/([^/]+)/);
|
|
92
|
+
if (sshMatch)
|
|
93
|
+
return { org: sshMatch[1], project: sshMatch[2] };
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
96
|
+
function makePrompter(rl) {
|
|
97
|
+
const prompt = (question, defaultValue) => new Promise((resolve) => {
|
|
98
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : '';
|
|
99
|
+
rl.question(` ${question}${suffix}: `, (answer) => {
|
|
100
|
+
resolve(answer.trim() || defaultValue || '');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
const yesNo = (question, defaultYes = true) => new Promise((resolve) => {
|
|
104
|
+
const suffix = defaultYes ? ' [Y/n]' : ' [y/N]';
|
|
105
|
+
rl.question(` ${question}${suffix}: `, (answer) => {
|
|
106
|
+
const a = answer.trim().toLowerCase();
|
|
107
|
+
if (a === '')
|
|
108
|
+
resolve(defaultYes);
|
|
109
|
+
else
|
|
110
|
+
resolve(a === 'y' || a === 'yes');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
return { prompt, yesNo };
|
|
114
|
+
}
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Template generators
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
function packageJsonTemplate(org, project) {
|
|
119
|
+
void org;
|
|
120
|
+
void project; // Reserved for future use (e.g. to embed metadata)
|
|
121
|
+
const deps = {
|
|
122
|
+
'@mauvezero/azpipe': CLI_VERSION,
|
|
123
|
+
'@mauvezero/azpipe-releases': CLI_VERSION,
|
|
124
|
+
'@mauvezero/azpipe-tasks': CLI_VERSION,
|
|
125
|
+
'@mauvezero/azpipe-utils': CLI_VERSION,
|
|
126
|
+
'@mauvezero/azpipe-cli': CLI_VERSION,
|
|
127
|
+
};
|
|
128
|
+
const pkg = {
|
|
129
|
+
name: 'pipelines',
|
|
130
|
+
private: true,
|
|
131
|
+
type: 'module',
|
|
132
|
+
scripts: {
|
|
133
|
+
build: 'azpipe build azure-pipelines.ts --out ../azure-pipelines.yml',
|
|
134
|
+
diff: 'azpipe release diff release.ts',
|
|
135
|
+
'push:dry': 'azpipe release push release.ts --dry-run',
|
|
136
|
+
push: 'azpipe release push release.ts',
|
|
137
|
+
},
|
|
138
|
+
dependencies: deps,
|
|
139
|
+
};
|
|
140
|
+
return JSON.stringify(pkg, null, 2) + '\n';
|
|
141
|
+
}
|
|
142
|
+
function tsconfigTemplate() {
|
|
143
|
+
return JSON.stringify({
|
|
144
|
+
compilerOptions: {
|
|
145
|
+
target: 'ES2022',
|
|
146
|
+
module: 'NodeNext',
|
|
147
|
+
moduleResolution: 'NodeNext',
|
|
148
|
+
lib: ['ES2022'],
|
|
149
|
+
strict: true,
|
|
150
|
+
noUncheckedIndexedAccess: true,
|
|
151
|
+
noImplicitOverride: true,
|
|
152
|
+
esModuleInterop: true,
|
|
153
|
+
forceConsistentCasingInFileNames: true,
|
|
154
|
+
skipLibCheck: true,
|
|
155
|
+
noEmit: true,
|
|
156
|
+
resolveJsonModule: true,
|
|
157
|
+
},
|
|
158
|
+
include: ['**/*.ts'],
|
|
159
|
+
}, null, 2) + '\n';
|
|
160
|
+
}
|
|
161
|
+
function pipelineStubTemplate() {
|
|
162
|
+
return `import { pipeline, script, checkout } from '@mauvezero/azpipe';
|
|
163
|
+
|
|
164
|
+
export default pipeline()
|
|
165
|
+
.name('CI $(Date:yyyyMMdd).$(Rev:r)')
|
|
166
|
+
.trigger({ branches: { include: ['main'] } })
|
|
167
|
+
.pr({ branches: { include: ['main'] } })
|
|
168
|
+
.pool({ vmImage: 'ubuntu-latest' })
|
|
169
|
+
.stage('Build', (s) =>
|
|
170
|
+
s.job('build', (j) =>
|
|
171
|
+
j
|
|
172
|
+
.step(checkout('self', { fetchDepth: 1 }))
|
|
173
|
+
.step(script('echo "Add your build steps here"', { displayName: 'Build' })),
|
|
174
|
+
),
|
|
175
|
+
);
|
|
176
|
+
`;
|
|
177
|
+
}
|
|
178
|
+
function releaseStubTemplate(org, project, releaseName) {
|
|
179
|
+
return `import { releasePipeline, buildArtifact } from '@mauvezero/azpipe-releases';
|
|
180
|
+
|
|
181
|
+
// Replace definitionId with the ID of your Azure Pipelines build pipeline.
|
|
182
|
+
const artifact = buildArtifact({
|
|
183
|
+
alias: 'drop',
|
|
184
|
+
definitionId: 0, // TODO: replace with your build pipeline's definition ID
|
|
185
|
+
defaultVersionType: 'latestType',
|
|
186
|
+
isPrimary: true,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
export default releasePipeline({
|
|
190
|
+
org: '${org}',
|
|
191
|
+
project: '${project}',
|
|
192
|
+
name: '${releaseName}',
|
|
193
|
+
releaseNameFormat: 'Release-$(rev:r)',
|
|
194
|
+
description: 'Managed by azpipe.',
|
|
195
|
+
})
|
|
196
|
+
.artifact(artifact)
|
|
197
|
+
.trigger(artifact)
|
|
198
|
+
.environment('staging', (e) =>
|
|
199
|
+
e.agentPhase((p) =>
|
|
200
|
+
p
|
|
201
|
+
.name('Deploy to staging')
|
|
202
|
+
.pool({ vmImage: 'ubuntu-latest' })
|
|
203
|
+
// TODO: add your deployment steps here
|
|
204
|
+
),
|
|
205
|
+
);
|
|
206
|
+
`;
|
|
207
|
+
}
|
|
208
|
+
function releaseSyncYmlTemplate(defaultBranch, syncPipelineName, org, project) {
|
|
209
|
+
return `# ============================================================
|
|
210
|
+
# Source: pipelines/release-sync.yml
|
|
211
|
+
# This file is NOT compiled from TypeScript — it IS the source.
|
|
212
|
+
#
|
|
213
|
+
# Pipeline name in Azure DevOps: ${syncPipelineName}
|
|
214
|
+
#
|
|
215
|
+
# Before registering this pipeline in Azure DevOps:
|
|
216
|
+
# 1. Set pipeline variables AZURE_DEVOPS_ORG and AZURE_DEVOPS_PROJECT
|
|
217
|
+
# in the Azure DevOps UI (or use the defaults below).
|
|
218
|
+
# 2. Ensure the service connection / service principal has
|
|
219
|
+
# "Release Definition Contributor" permission.
|
|
220
|
+
# ============================================================
|
|
221
|
+
name: ${syncPipelineName}
|
|
222
|
+
|
|
223
|
+
trigger:
|
|
224
|
+
branches:
|
|
225
|
+
include:
|
|
226
|
+
- ${defaultBranch}
|
|
227
|
+
paths:
|
|
228
|
+
include:
|
|
229
|
+
- pipelines/**
|
|
230
|
+
|
|
231
|
+
pr:
|
|
232
|
+
branches:
|
|
233
|
+
include:
|
|
234
|
+
- ${defaultBranch}
|
|
235
|
+
paths:
|
|
236
|
+
include:
|
|
237
|
+
- pipelines/**
|
|
238
|
+
|
|
239
|
+
pool:
|
|
240
|
+
vmImage: ubuntu-latest
|
|
241
|
+
|
|
242
|
+
variables:
|
|
243
|
+
AZURE_DEVOPS_ORG: '${org}'
|
|
244
|
+
AZURE_DEVOPS_PROJECT: '${project}'
|
|
245
|
+
|
|
246
|
+
steps:
|
|
247
|
+
- checkout: self
|
|
248
|
+
|
|
249
|
+
- task: NodeTool@0
|
|
250
|
+
inputs:
|
|
251
|
+
versionSpec: '20.x'
|
|
252
|
+
displayName: Install Node
|
|
253
|
+
|
|
254
|
+
- script: npm ci
|
|
255
|
+
workingDirectory: pipelines
|
|
256
|
+
displayName: Install dependencies
|
|
257
|
+
|
|
258
|
+
- script: npx azpipe release diff release.ts
|
|
259
|
+
workingDirectory: pipelines
|
|
260
|
+
displayName: Diff release definitions
|
|
261
|
+
# Non-zero exit means drift detected. On a PR this is expected and informational.
|
|
262
|
+
continueOnError: true
|
|
263
|
+
env:
|
|
264
|
+
AZURE_DEVOPS_ORG: $(AZURE_DEVOPS_ORG)
|
|
265
|
+
AZURE_DEVOPS_PROJECT: $(AZURE_DEVOPS_PROJECT)
|
|
266
|
+
|
|
267
|
+
- script: npx azpipe release push release.ts --yes
|
|
268
|
+
workingDirectory: pipelines
|
|
269
|
+
displayName: Push release definitions
|
|
270
|
+
# Only runs on the default branch, not on PRs.
|
|
271
|
+
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
|
|
272
|
+
env:
|
|
273
|
+
AZURE_DEVOPS_ORG: $(AZURE_DEVOPS_ORG)
|
|
274
|
+
AZURE_DEVOPS_PROJECT: $(AZURE_DEVOPS_PROJECT)
|
|
275
|
+
`;
|
|
276
|
+
}
|
|
277
|
+
const GENERATED_BANNER = `# ============================================================
|
|
278
|
+
# GENERATED FILE – do not edit by hand.
|
|
279
|
+
# Source: pipelines/azure-pipelines.ts
|
|
280
|
+
# Regenerate: cd pipelines && npm run build
|
|
281
|
+
# ============================================================
|
|
282
|
+
`;
|
|
283
|
+
function readmeTemplate(org, project, syncPipelineName, defaultBranch) {
|
|
284
|
+
return `# pipelines/
|
|
285
|
+
|
|
286
|
+
This directory is managed by [azpipe](https://github.com/mauve/releases).
|
|
287
|
+
It contains TypeScript sources for Azure Pipelines CI and Classic Release definitions.
|
|
288
|
+
|
|
289
|
+
## Contents
|
|
290
|
+
|
|
291
|
+
| File | Description |
|
|
292
|
+
|---|---|
|
|
293
|
+
| \`azure-pipelines.ts\` | CI pipeline source (TypeScript) |
|
|
294
|
+
| \`release.ts\` | Release definition source (TypeScript) |
|
|
295
|
+
| \`release-sync.yml\` | Azure Pipelines YAML that diffs and pushes release definitions |
|
|
296
|
+
| \`package.json\` | npm scripts to build, diff, and push |
|
|
297
|
+
| \`tsconfig.json\` | TypeScript config (self-contained) |
|
|
298
|
+
|
|
299
|
+
## Regenerate \`azure-pipelines.yml\`
|
|
300
|
+
|
|
301
|
+
The root \`azure-pipelines.yml\` is **generated** from \`azure-pipelines.ts\`. Never edit it by hand.
|
|
302
|
+
|
|
303
|
+
\`\`\`bash
|
|
304
|
+
cd pipelines
|
|
305
|
+
npm install
|
|
306
|
+
npm run build # writes ../azure-pipelines.yml
|
|
307
|
+
\`\`\`
|
|
308
|
+
|
|
309
|
+
Commit both \`azure-pipelines.ts\` and the regenerated \`azure-pipelines.yml\`.
|
|
310
|
+
|
|
311
|
+
## Managing release definitions
|
|
312
|
+
|
|
313
|
+
Release definitions are authored as TypeScript files and pushed to Azure DevOps via the CLI.
|
|
314
|
+
|
|
315
|
+
\`\`\`bash
|
|
316
|
+
cd pipelines
|
|
317
|
+
npm run diff # show drift between local and server
|
|
318
|
+
npm run push:dry # dry run – shows what would change
|
|
319
|
+
npm run push # interactive push
|
|
320
|
+
\`\`\`
|
|
321
|
+
|
|
322
|
+
## Adding a new release pipeline
|
|
323
|
+
|
|
324
|
+
1. Create a new \`.ts\` file (e.g. \`release-backend.ts\`) using \`releasePipeline()\`.
|
|
325
|
+
2. Add a \`diff\` and \`push\` step for it in \`release-sync.yml\`.
|
|
326
|
+
3. Open a PR — the \`${syncPipelineName}\` pipeline will diff and report drift.
|
|
327
|
+
4. On merge to \`${defaultBranch}\`, the pipeline pushes the definition automatically.
|
|
328
|
+
|
|
329
|
+
## Credentials
|
|
330
|
+
|
|
331
|
+
The \`release-sync.yml\` pipeline reads org/project from pipeline variables:
|
|
332
|
+
- \`AZURE_DEVOPS_ORG\` — set to \`${org}\`
|
|
333
|
+
- \`AZURE_DEVOPS_PROJECT\` — set to \`${project}\`
|
|
334
|
+
|
|
335
|
+
Authentication uses \`DefaultAzureCredential\` (managed identity or workload identity federation).
|
|
336
|
+
Ensure the identity has **Release Definition Contributor** permission in the project.
|
|
337
|
+
`;
|
|
338
|
+
}
|
|
339
|
+
// ---------------------------------------------------------------------------
|
|
340
|
+
// Main
|
|
341
|
+
// ---------------------------------------------------------------------------
|
|
342
|
+
export async function runBootstrap(argv) {
|
|
343
|
+
const opts = parseArgs(argv);
|
|
344
|
+
if (opts.help) {
|
|
345
|
+
usage();
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
// -- Detect git root -------------------------------------------------------
|
|
349
|
+
const gitRoot = findGitRoot(process.cwd());
|
|
350
|
+
console.log(`Detected repo root: ${gitRoot}`);
|
|
351
|
+
// -- Detect default branch -------------------------------------------------
|
|
352
|
+
const defaultBranch = detectDefaultBranch();
|
|
353
|
+
console.log(`Detected default branch: ${defaultBranch}`);
|
|
354
|
+
// -- Detect org / project --------------------------------------------------
|
|
355
|
+
const fromRemote = detectFromGitRemote();
|
|
356
|
+
const detectedOrg = process.env['AZURE_DEVOPS_ORG'] ?? fromRemote.org ?? '';
|
|
357
|
+
const detectedProject = process.env['AZURE_DEVOPS_PROJECT'] ?? fromRemote.project ?? '';
|
|
358
|
+
if (detectedOrg)
|
|
359
|
+
console.log(`Detected org: ${detectedOrg}`);
|
|
360
|
+
if (detectedProject)
|
|
361
|
+
console.log(`Detected project: ${detectedProject}`);
|
|
362
|
+
// -- Detect existing azure-pipelines.yml -----------------------------------
|
|
363
|
+
const rootYml = join(gitRoot, 'azure-pipelines.yml');
|
|
364
|
+
const hasRootYml = existsSync(rootYml);
|
|
365
|
+
if (hasRootYml)
|
|
366
|
+
console.log(`Detected existing azure-pipelines.yml at repo root.`);
|
|
367
|
+
// -- Interactive wizard ----------------------------------------------------
|
|
368
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
369
|
+
const { prompt, yesNo } = makePrompter(rl);
|
|
370
|
+
let org = detectedOrg;
|
|
371
|
+
let project = detectedProject;
|
|
372
|
+
let releaseName = '';
|
|
373
|
+
let syncPipelineName = '';
|
|
374
|
+
let convertYml = hasRootYml;
|
|
375
|
+
if (!opts.yes) {
|
|
376
|
+
org = await prompt('Azure DevOps org', detectedOrg || undefined);
|
|
377
|
+
project = await prompt('Azure DevOps project', detectedProject || undefined);
|
|
378
|
+
const defaultSyncName = project
|
|
379
|
+
? `${project.charAt(0).toUpperCase()}${project.slice(1)}ReleasesSync`
|
|
380
|
+
: 'ReleasesSync';
|
|
381
|
+
syncPipelineName = await prompt('Sync pipeline name (Azure DevOps display name)', defaultSyncName);
|
|
382
|
+
releaseName = await prompt('Release definition name (e.g. my-service-release)');
|
|
383
|
+
if (hasRootYml) {
|
|
384
|
+
convertYml = await yesNo('Convert existing azure-pipelines.yml to TypeScript?', true);
|
|
385
|
+
}
|
|
386
|
+
const proceed = await yesNo('Create/overwrite files in pipelines/?', true);
|
|
387
|
+
rl.close();
|
|
388
|
+
if (!proceed) {
|
|
389
|
+
console.log('Aborted.');
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
rl.close();
|
|
395
|
+
org = org || '';
|
|
396
|
+
project = project || '';
|
|
397
|
+
const defaultSyncName = project
|
|
398
|
+
? `${project.charAt(0).toUpperCase()}${project.slice(1)}ReleasesSync`
|
|
399
|
+
: 'ReleasesSync';
|
|
400
|
+
syncPipelineName = defaultSyncName;
|
|
401
|
+
releaseName = `${project || 'my-service'}-release`;
|
|
402
|
+
}
|
|
403
|
+
if (!org) {
|
|
404
|
+
console.error('Org is required. Set AZURE_DEVOPS_ORG or pass it when prompted.\n' +
|
|
405
|
+
'You can also edit pipelines/release.ts and pipelines/release-sync.yml manually.');
|
|
406
|
+
}
|
|
407
|
+
if (!project) {
|
|
408
|
+
console.error('Project is required. Set AZURE_DEVOPS_PROJECT or pass it when prompted.\n' +
|
|
409
|
+
'You can also edit pipelines/release.ts and pipelines/release-sync.yml manually.');
|
|
410
|
+
}
|
|
411
|
+
// -- Prepare output directory ----------------------------------------------
|
|
412
|
+
const outDir = isAbsolute(opts.outDir)
|
|
413
|
+
? opts.outDir
|
|
414
|
+
: join(gitRoot, opts.outDir);
|
|
415
|
+
mkdirSync(outDir, { recursive: true });
|
|
416
|
+
// -- Generate azure-pipelines.ts (convert or stub) -------------------------
|
|
417
|
+
let pipelineTs;
|
|
418
|
+
if (convertYml && hasRootYml) {
|
|
419
|
+
console.log('Converting azure-pipelines.yml → azure-pipelines.ts…');
|
|
420
|
+
const yamlText = readFileSync(rootYml, 'utf8');
|
|
421
|
+
const result = await yamlToTs(yamlText, {
|
|
422
|
+
prettier: true,
|
|
423
|
+
emitTemplates: false,
|
|
424
|
+
inlineTemplates: false,
|
|
425
|
+
entryFileName: 'azure-pipelines.ts',
|
|
426
|
+
outputDir: '.',
|
|
427
|
+
loadTemplate: () => undefined,
|
|
428
|
+
});
|
|
429
|
+
for (const w of result.warnings)
|
|
430
|
+
console.error(` warning: ${w}`);
|
|
431
|
+
pipelineTs = result.files[0]?.contents ?? pipelineStubTemplate();
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
pipelineTs = pipelineStubTemplate();
|
|
435
|
+
}
|
|
436
|
+
// -- Generate azure-pipelines.yml at repo root (stub pipeline serialized) --
|
|
437
|
+
// We do a best-effort in-process build using the stub as source.
|
|
438
|
+
// For the converted case, we don't re-emit from TS (that requires tsx at
|
|
439
|
+
// bootstrap time); instead we copy the original YAML with a banner prepended.
|
|
440
|
+
let rootYmlContent;
|
|
441
|
+
if (convertYml && hasRootYml) {
|
|
442
|
+
// Prepend the banner to the original YAML.
|
|
443
|
+
const originalYml = readFileSync(rootYml, 'utf8');
|
|
444
|
+
if (!originalYml.startsWith('# ===')) {
|
|
445
|
+
rootYmlContent = GENERATED_BANNER + originalYml;
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
rootYmlContent = originalYml; // Already has the banner
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
// Generate a minimal YAML for the stub pipeline.
|
|
453
|
+
rootYmlContent =
|
|
454
|
+
GENERATED_BANNER +
|
|
455
|
+
[
|
|
456
|
+
'name: CI $(Date:yyyyMMdd).$(Rev:r)',
|
|
457
|
+
'trigger:',
|
|
458
|
+
' branches:',
|
|
459
|
+
' include:',
|
|
460
|
+
' - main',
|
|
461
|
+
'pr:',
|
|
462
|
+
' branches:',
|
|
463
|
+
' include:',
|
|
464
|
+
' - main',
|
|
465
|
+
'pool:',
|
|
466
|
+
" vmImage: ubuntu-latest",
|
|
467
|
+
'stages:',
|
|
468
|
+
' - stage: Build',
|
|
469
|
+
' jobs:',
|
|
470
|
+
' - job: build',
|
|
471
|
+
' steps:',
|
|
472
|
+
" - checkout: self",
|
|
473
|
+
" - script: echo \"Add your build steps here\"",
|
|
474
|
+
' displayName: Build',
|
|
475
|
+
].join('\n') + '\n';
|
|
476
|
+
}
|
|
477
|
+
// -- Write all files -------------------------------------------------------
|
|
478
|
+
function write(filePath, content) {
|
|
479
|
+
writeFileSync(filePath, content, 'utf8');
|
|
480
|
+
console.log(` Wrote ${filePath}`);
|
|
481
|
+
}
|
|
482
|
+
write(join(outDir, 'package.json'), packageJsonTemplate(org, project));
|
|
483
|
+
write(join(outDir, 'tsconfig.json'), tsconfigTemplate());
|
|
484
|
+
write(join(outDir, 'README.md'), readmeTemplate(org, project, syncPipelineName, defaultBranch));
|
|
485
|
+
write(join(outDir, 'azure-pipelines.ts'), pipelineTs);
|
|
486
|
+
write(join(outDir, 'release.ts'), releaseStubTemplate(org, project, releaseName));
|
|
487
|
+
write(join(outDir, 'release-sync.yml'), releaseSyncYmlTemplate(defaultBranch, syncPipelineName, org, project));
|
|
488
|
+
write(rootYml, rootYmlContent);
|
|
489
|
+
console.log(`
|
|
490
|
+
Bootstrap complete!
|
|
491
|
+
|
|
492
|
+
Next steps:
|
|
493
|
+
1. cd ${opts.outDir} && npm install
|
|
494
|
+
2. npm run build # regenerate azure-pipelines.yml
|
|
495
|
+
3. Edit release.ts # add your artifact source and environments
|
|
496
|
+
4. npm run diff # check drift vs Azure DevOps
|
|
497
|
+
5. Register release-sync.yml in Azure DevOps as a new pipeline
|
|
498
|
+
(point it at: pipelines/release-sync.yml)
|
|
499
|
+
|
|
500
|
+
See pipelines/README.md for full documentation.`);
|
|
501
|
+
}
|
|
502
|
+
//# sourceMappingURL=cmd-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-bootstrap.js","sourceRoot":"","sources":["../src/cmd-bootstrap.ts"],"names":[],"mappings":"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"}
|
package/dist/cmd-build-import.js
CHANGED
|
@@ -39,7 +39,7 @@ function usage() {
|
|
|
39
39
|
console.log(`azpipe build import <azure-pipelines.yml> [options]
|
|
40
40
|
|
|
41
41
|
Convert an existing Azure Pipelines YAML file to TypeScript that uses
|
|
42
|
-
@
|
|
42
|
+
@mauvezero/azpipe builders.
|
|
43
43
|
|
|
44
44
|
Options:
|
|
45
45
|
-o, --out <file> Entry output file (default: pipeline.ts)
|
|
@@ -44,7 +44,7 @@ function usage() {
|
|
|
44
44
|
azpipe release import --name <name> --org <org> --project <project> [options]
|
|
45
45
|
|
|
46
46
|
Convert an existing classic-release JSON definition to TypeScript using
|
|
47
|
-
@
|
|
47
|
+
@mauvezero/azpipe-releases builders. Either pass a JSON file (typically
|
|
48
48
|
exported via \`azpipe release get\`) or fetch live by name.
|
|
49
49
|
|
|
50
50
|
Options:
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mauvezero/azpipe-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/mauve/releases.git"
|
|
7
|
+
},
|
|
4
8
|
"description": "CLI for compiling TS-authored Azure Pipelines into YAML/JSON.",
|
|
5
9
|
"type": "module",
|
|
6
10
|
"main": "./dist/bin.js",
|
|
@@ -13,13 +17,13 @@
|
|
|
13
17
|
"dependencies": {
|
|
14
18
|
"tsx": "^4.19.2",
|
|
15
19
|
"yaml": "^2.7.0",
|
|
16
|
-
"@mauvezero/azpipe": "0.
|
|
17
|
-
"@mauvezero/azpipe-
|
|
18
|
-
"@mauvezero/azpipe-core": "0.
|
|
19
|
-
"@mauvezero/azpipe-
|
|
20
|
-
"@mauvezero/azpipe-releases
|
|
21
|
-
"@mauvezero/azpipe-
|
|
22
|
-
"@mauvezero/azpipe-
|
|
20
|
+
"@mauvezero/azpipe": "0.4.0",
|
|
21
|
+
"@mauvezero/azpipe-convert": "0.4.0",
|
|
22
|
+
"@mauvezero/azpipe-core": "0.4.0",
|
|
23
|
+
"@mauvezero/azpipe-tasks": "0.4.0",
|
|
24
|
+
"@mauvezero/azpipe-releases": "0.4.0",
|
|
25
|
+
"@mauvezero/azpipe-utils": "0.4.0",
|
|
26
|
+
"@mauvezero/azpipe-releases-client": "0.4.0"
|
|
23
27
|
},
|
|
24
28
|
"devDependencies": {
|
|
25
29
|
"typescript": "^5.7.3",
|