@git.zone/cli 2.18.1 → 2.19.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/.smartconfig.json +2 -1
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/helpers.smartconfigmigrations.js +20 -3
- package/dist_ts/helpers.workflow.d.ts +12 -2
- package/dist_ts/helpers.workflow.js +9 -2
- package/dist_ts/mod_config/index.js +206 -22
- package/dist_ts/mod_release/index.js +50 -23
- package/package.json +1 -1
- package/readme.md +20 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/helpers.smartconfigmigrations.ts +20 -2
- package/ts/helpers.workflow.ts +20 -3
- package/ts/mod_config/index.ts +219 -21
- package/ts/mod_release/index.ts +46 -23
package/ts/mod_config/index.ts
CHANGED
|
@@ -793,7 +793,7 @@ async function handleRelease(mode: ICliMode): Promise<void> {
|
|
|
793
793
|
choices: [
|
|
794
794
|
{ name: "git - push branch and tags", value: "git" },
|
|
795
795
|
{ name: "npm - publish package registries", value: "npm" },
|
|
796
|
-
{ name: "docker - build and push
|
|
796
|
+
{ name: "docker - build and push through tsdocker", value: "docker" },
|
|
797
797
|
],
|
|
798
798
|
default: getDefaultEnabledTargets(currentTargets),
|
|
799
799
|
});
|
|
@@ -860,21 +860,49 @@ async function handleRelease(mode: ICliMode): Promise<void> {
|
|
|
860
860
|
}
|
|
861
861
|
|
|
862
862
|
if (enabledTargets.includes("docker")) {
|
|
863
|
-
const
|
|
863
|
+
const patterns = await askValue<string>(interactInstance, {
|
|
864
864
|
type: "input",
|
|
865
|
-
name: "
|
|
866
|
-
message: "
|
|
867
|
-
default: Array.isArray(currentTargets.docker?.
|
|
868
|
-
? currentTargets.docker.
|
|
865
|
+
name: "dockerPatterns",
|
|
866
|
+
message: "tsdocker Dockerfile patterns (comma-separated, empty means all):",
|
|
867
|
+
default: Array.isArray(currentTargets.docker?.patterns)
|
|
868
|
+
? currentTargets.docker.patterns.join(", ")
|
|
869
869
|
: "",
|
|
870
870
|
});
|
|
871
|
+
const cached = await askValue<boolean>(interactInstance, {
|
|
872
|
+
type: "confirm",
|
|
873
|
+
name: "dockerCached",
|
|
874
|
+
message: "Use tsdocker cached builds?",
|
|
875
|
+
default: currentTargets.docker?.cached ?? false,
|
|
876
|
+
});
|
|
877
|
+
const parallel = await askValue<string>(interactInstance, {
|
|
878
|
+
type: "input",
|
|
879
|
+
name: "dockerParallel",
|
|
880
|
+
message: "tsdocker parallel mode (false, true, or concurrency number):",
|
|
881
|
+
default: formatDockerParallel(currentTargets.docker?.parallel ?? false),
|
|
882
|
+
});
|
|
883
|
+
const context = await askValue<string>(interactInstance, {
|
|
884
|
+
type: "input",
|
|
885
|
+
name: "dockerContext",
|
|
886
|
+
message: "Docker context for tsdocker (empty for default):",
|
|
887
|
+
default: currentTargets.docker?.context || "",
|
|
888
|
+
});
|
|
889
|
+
const noBuild = await askValue<boolean>(interactInstance, {
|
|
890
|
+
type: "confirm",
|
|
891
|
+
name: "dockerNoBuild",
|
|
892
|
+
message: "Skip tsdocker build and only push existing local registry images?",
|
|
893
|
+
default: currentTargets.docker?.noBuild ?? false,
|
|
894
|
+
});
|
|
871
895
|
releaseTargets.docker = {
|
|
872
|
-
...(currentTargets.docker || {}),
|
|
873
896
|
enabled: true,
|
|
874
|
-
|
|
897
|
+
engine: "tsdocker",
|
|
898
|
+
patterns: parseCsv(patterns),
|
|
899
|
+
cached,
|
|
900
|
+
parallel: parseDockerParallel(parallel),
|
|
901
|
+
context: context.trim() || undefined,
|
|
902
|
+
noBuild,
|
|
875
903
|
};
|
|
876
904
|
} else {
|
|
877
|
-
releaseTargets.docker = {
|
|
905
|
+
releaseTargets.docker = { enabled: false, engine: "tsdocker" };
|
|
878
906
|
}
|
|
879
907
|
|
|
880
908
|
setCliConfigValueInData(smartconfigData, "schemaVersion", CURRENT_GITZONE_CLI_SCHEMA_VERSION);
|
|
@@ -1043,7 +1071,7 @@ async function collectDoctorFindings(): Promise<IDoctorFinding[]> {
|
|
|
1043
1071
|
await validateDetectedProjectType(cliConfig, findings);
|
|
1044
1072
|
|
|
1045
1073
|
validateCommitConfig(cliConfig.commit || {}, findings);
|
|
1046
|
-
await validateReleaseConfig(cliConfig.release || {}, findings);
|
|
1074
|
+
await validateReleaseConfig(cliConfig.release || {}, smartconfigData, findings);
|
|
1047
1075
|
|
|
1048
1076
|
return findings;
|
|
1049
1077
|
}
|
|
@@ -1291,9 +1319,14 @@ function formatTarget(enabled: unknown, targetConfig: any): string {
|
|
|
1291
1319
|
details.push(`registries=${targetConfig.registries.length}`);
|
|
1292
1320
|
}
|
|
1293
1321
|
if (targetConfig.accessLevel) details.push(`access=${targetConfig.accessLevel}`);
|
|
1294
|
-
if (
|
|
1295
|
-
|
|
1296
|
-
|
|
1322
|
+
if (targetConfig.engine) details.push(`engine=${targetConfig.engine}`);
|
|
1323
|
+
if (Array.isArray(targetConfig.patterns)) {
|
|
1324
|
+
details.push(`patterns=${targetConfig.patterns.length}`);
|
|
1325
|
+
}
|
|
1326
|
+
if (targetConfig.cached) details.push("cached=true");
|
|
1327
|
+
if (targetConfig.parallel) details.push(`parallel=${targetConfig.parallel}`);
|
|
1328
|
+
if (targetConfig.context) details.push(`context=${targetConfig.context}`);
|
|
1329
|
+
if (targetConfig.noBuild) details.push("noBuild=true");
|
|
1297
1330
|
return details.length > 0 ? `${state} (${details.join(", ")})` : state;
|
|
1298
1331
|
}
|
|
1299
1332
|
|
|
@@ -1338,6 +1371,29 @@ function parseCsv(value: string): string[] {
|
|
|
1338
1371
|
return result;
|
|
1339
1372
|
}
|
|
1340
1373
|
|
|
1374
|
+
function formatDockerParallel(value: unknown): string {
|
|
1375
|
+
if (value === true) return "true";
|
|
1376
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
1377
|
+
return String(Math.floor(value));
|
|
1378
|
+
}
|
|
1379
|
+
return "false";
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
function parseDockerParallel(value: string): boolean | number {
|
|
1383
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
1384
|
+
if (!normalizedValue || ["false", "no", "off", "0"].includes(normalizedValue)) {
|
|
1385
|
+
return false;
|
|
1386
|
+
}
|
|
1387
|
+
if (["true", "yes", "on"].includes(normalizedValue)) {
|
|
1388
|
+
return true;
|
|
1389
|
+
}
|
|
1390
|
+
const numericValue = Number(normalizedValue);
|
|
1391
|
+
if (Number.isFinite(numericValue) && numericValue > 0) {
|
|
1392
|
+
return Math.floor(numericValue);
|
|
1393
|
+
}
|
|
1394
|
+
return false;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1341
1397
|
function normalizeRegistryUrl(url: string): string {
|
|
1342
1398
|
let normalizedUrl = url.trim();
|
|
1343
1399
|
if (!normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://")) {
|
|
@@ -1391,6 +1447,7 @@ function buildConfigFixPrompt(
|
|
|
1391
1447
|
`- Use schemaVersion ${CURRENT_GITZONE_CLI_SCHEMA_VERSION} for ` +
|
|
1392
1448
|
"`@git.zone/cli`.",
|
|
1393
1449
|
"- Use target-based release config: `release.targets.git`, `release.targets.npm`, and `release.targets.docker`.",
|
|
1450
|
+
"- Docker release targets must use `release.targets.docker.engine = \"tsdocker\"`; Docker registries belong under `@git.zone/tsdocker`.",
|
|
1394
1451
|
"- Keep npm registries only at `@git.zone/cli.release.targets.npm.registries`.",
|
|
1395
1452
|
"- Do not add runtime legacy compatibility code. If legacy config exists, migrate it explicitly.",
|
|
1396
1453
|
"- Do not commit, release, install dependencies, or modify unrelated files.",
|
|
@@ -1514,6 +1571,7 @@ function validateCommitConfig(
|
|
|
1514
1571
|
|
|
1515
1572
|
async function validateReleaseConfig(
|
|
1516
1573
|
releaseConfig: Record<string, any>,
|
|
1574
|
+
smartconfigData: Record<string, any>,
|
|
1517
1575
|
findings: IDoctorFinding[],
|
|
1518
1576
|
): Promise<void> {
|
|
1519
1577
|
const confirmation = releaseConfig.confirmation;
|
|
@@ -1554,7 +1612,7 @@ async function validateReleaseConfig(
|
|
|
1554
1612
|
const targets = releaseConfig.targets || {};
|
|
1555
1613
|
await validateGitTarget(targets.git || {}, findings);
|
|
1556
1614
|
await validateNpmTarget(targets.npm || {}, findings);
|
|
1557
|
-
validateDockerTarget(targets.docker || {}, findings);
|
|
1615
|
+
await validateDockerTarget(targets.docker || {}, smartconfigData, findings);
|
|
1558
1616
|
}
|
|
1559
1617
|
|
|
1560
1618
|
async function validateGitTarget(
|
|
@@ -1718,31 +1776,171 @@ async function validateNpmAuth(
|
|
|
1718
1776
|
}
|
|
1719
1777
|
}
|
|
1720
1778
|
|
|
1721
|
-
function validateDockerTarget(
|
|
1779
|
+
async function validateDockerTarget(
|
|
1722
1780
|
dockerTarget: Record<string, any>,
|
|
1781
|
+
smartconfigData: Record<string, any>,
|
|
1723
1782
|
findings: IDoctorFinding[],
|
|
1724
|
-
): void {
|
|
1783
|
+
): Promise<void> {
|
|
1784
|
+
if ("images" in dockerTarget) {
|
|
1785
|
+
findings.push({
|
|
1786
|
+
level: "error",
|
|
1787
|
+
message: "Docker release target still uses removed images config",
|
|
1788
|
+
fix: "Remove release.targets.docker.images and configure @git.zone/tsdocker instead.",
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1725
1792
|
const enabled = dockerTarget.enabled ?? false;
|
|
1726
1793
|
if (!enabled) {
|
|
1727
1794
|
findings.push({ level: "ok", message: "Docker release target is disabled" });
|
|
1728
1795
|
return;
|
|
1729
1796
|
}
|
|
1730
1797
|
|
|
1731
|
-
if (
|
|
1798
|
+
if (dockerTarget.engine !== "tsdocker") {
|
|
1732
1799
|
findings.push({
|
|
1733
1800
|
level: "error",
|
|
1734
|
-
message: "Docker release target
|
|
1735
|
-
fix: "Set release.targets.docker.
|
|
1801
|
+
message: "Docker release target must use tsdocker",
|
|
1802
|
+
fix: "Set release.targets.docker.engine to tsdocker.",
|
|
1736
1803
|
});
|
|
1737
|
-
return;
|
|
1738
1804
|
}
|
|
1739
1805
|
|
|
1806
|
+
if (dockerTarget.patterns !== undefined && !Array.isArray(dockerTarget.patterns)) {
|
|
1807
|
+
findings.push({
|
|
1808
|
+
level: "error",
|
|
1809
|
+
message: "Docker release target patterns must be an array",
|
|
1810
|
+
fix: "Set release.targets.docker.patterns to an array of Dockerfile patterns or remove it.",
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
if (!isValidDockerParallel(dockerTarget.parallel)) {
|
|
1815
|
+
findings.push({
|
|
1816
|
+
level: "error",
|
|
1817
|
+
message: `Invalid tsdocker parallel setting: ${formatValue(dockerTarget.parallel)}`,
|
|
1818
|
+
fix: "Use false, true, or a positive concurrency number.",
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
const tsdockerConfig = smartconfigData["@git.zone/tsdocker"];
|
|
1823
|
+
if (!isPlainObject(tsdockerConfig)) {
|
|
1824
|
+
findings.push({
|
|
1825
|
+
level: "error",
|
|
1826
|
+
message: "Docker release target is enabled but @git.zone/tsdocker config is missing",
|
|
1827
|
+
fix: "Add @git.zone/tsdocker.registries and optional registryRepoMap/platforms config.",
|
|
1828
|
+
});
|
|
1829
|
+
} else {
|
|
1830
|
+
validateTsdockerProjectConfig(tsdockerConfig, findings);
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
await validateTsdockerCommand(findings);
|
|
1834
|
+
|
|
1740
1835
|
findings.push({
|
|
1741
1836
|
level: "ok",
|
|
1742
|
-
message: `Docker release target
|
|
1837
|
+
message: `Docker release target uses tsdocker (${formatDockerPatterns(dockerTarget.patterns)})`,
|
|
1743
1838
|
});
|
|
1744
1839
|
}
|
|
1745
1840
|
|
|
1841
|
+
function formatDockerPatterns(patterns: unknown): string {
|
|
1842
|
+
return Array.isArray(patterns) && patterns.length > 0
|
|
1843
|
+
? patterns.map((pattern) => String(pattern)).join(", ")
|
|
1844
|
+
: "all Dockerfiles";
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
function isPlainObject(value: unknown): value is Record<string, any> {
|
|
1848
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
function isValidDockerParallel(value: unknown): boolean {
|
|
1852
|
+
return value === undefined ||
|
|
1853
|
+
value === false ||
|
|
1854
|
+
value === true ||
|
|
1855
|
+
(typeof value === "number" && Number.isFinite(value) && value > 0);
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
function validateTsdockerProjectConfig(
|
|
1859
|
+
tsdockerConfig: Record<string, any>,
|
|
1860
|
+
findings: IDoctorFinding[],
|
|
1861
|
+
): void {
|
|
1862
|
+
const registries = Array.isArray(tsdockerConfig.registries)
|
|
1863
|
+
? tsdockerConfig.registries
|
|
1864
|
+
: [];
|
|
1865
|
+
if (registries.length === 0) {
|
|
1866
|
+
findings.push({
|
|
1867
|
+
level: "error",
|
|
1868
|
+
message: "@git.zone/tsdocker.registries is empty",
|
|
1869
|
+
fix: "Set @git.zone/tsdocker.registries to registry hosts such as registry.gitlab.com.",
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
for (const registry of registries) {
|
|
1874
|
+
if (typeof registry !== "string" || !registry.trim()) {
|
|
1875
|
+
findings.push({
|
|
1876
|
+
level: "error",
|
|
1877
|
+
message: `Invalid tsdocker registry: ${formatValue(registry)}`,
|
|
1878
|
+
fix: "Use registry hosts such as registry.gitlab.com.",
|
|
1879
|
+
});
|
|
1880
|
+
continue;
|
|
1881
|
+
}
|
|
1882
|
+
if (registry.startsWith("http://") || registry.startsWith("https://")) {
|
|
1883
|
+
findings.push({
|
|
1884
|
+
level: "error",
|
|
1885
|
+
message: `tsdocker registry must not include a protocol: ${registry}`,
|
|
1886
|
+
fix: `Use ${registry.replace(/^https?:\/\//, "")}`,
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
const registryRepoMap = tsdockerConfig.registryRepoMap;
|
|
1892
|
+
if (registryRepoMap !== undefined && !isPlainObject(registryRepoMap)) {
|
|
1893
|
+
findings.push({
|
|
1894
|
+
level: "error",
|
|
1895
|
+
message: "@git.zone/tsdocker.registryRepoMap must be an object",
|
|
1896
|
+
});
|
|
1897
|
+
} else if (isPlainObject(registryRepoMap)) {
|
|
1898
|
+
for (const registry of Object.keys(registryRepoMap)) {
|
|
1899
|
+
if (registry.startsWith("http://") || registry.startsWith("https://")) {
|
|
1900
|
+
findings.push({
|
|
1901
|
+
level: "error",
|
|
1902
|
+
message: `tsdocker registryRepoMap key must not include a protocol: ${registry}`,
|
|
1903
|
+
fix: `Use ${registry.replace(/^https?:\/\//, "")}`,
|
|
1904
|
+
});
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1909
|
+
findings.push({
|
|
1910
|
+
level: "ok",
|
|
1911
|
+
message: `@git.zone/tsdocker has ${registries.length} registries`,
|
|
1912
|
+
});
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
async function validateTsdockerCommand(findings: IDoctorFinding[]): Promise<void> {
|
|
1916
|
+
const smartshellInstance = new plugins.smartshell.Smartshell({
|
|
1917
|
+
executor: "bash",
|
|
1918
|
+
sourceFilePaths: [],
|
|
1919
|
+
});
|
|
1920
|
+
try {
|
|
1921
|
+
const result = await smartshellInstance.execSpawn(
|
|
1922
|
+
"tsdocker",
|
|
1923
|
+
["--version"],
|
|
1924
|
+
{ silent: true, timeout: 8000 },
|
|
1925
|
+
);
|
|
1926
|
+
if (result.exitCode === 0) {
|
|
1927
|
+
findings.push({ level: "ok", message: "tsdocker command is available" });
|
|
1928
|
+
} else {
|
|
1929
|
+
findings.push({
|
|
1930
|
+
level: "error",
|
|
1931
|
+
message: "tsdocker command is not available",
|
|
1932
|
+
fix: "Install @git.zone/tsdocker globally or make it available on PATH.",
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
} catch (error) {
|
|
1936
|
+
findings.push({
|
|
1937
|
+
level: "error",
|
|
1938
|
+
message: "Could not execute tsdocker",
|
|
1939
|
+
fix: error instanceof Error ? error.message : String(error),
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1746
1944
|
async function validateDetectedProjectType(
|
|
1747
1945
|
cliConfig: Record<string, any>,
|
|
1748
1946
|
findings: IDoctorFinding[],
|
package/ts/mod_release/index.ts
CHANGED
|
@@ -107,7 +107,7 @@ export const run = async (argvArg: any) => {
|
|
|
107
107
|
npmResults.push(...(await runNpmTarget(smartshellInstance, workflow)));
|
|
108
108
|
}
|
|
109
109
|
if (workflow.targets.includes("docker")) {
|
|
110
|
-
dockerResults.push(...(await runDockerTarget(smartshellInstance, workflow
|
|
110
|
+
dockerResults.push(...(await runDockerTarget(smartshellInstance, workflow)));
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
printReleaseSummary(newVersion, gitResults, npmResults, dockerResults);
|
|
@@ -262,31 +262,43 @@ async function runNpmTarget(
|
|
|
262
262
|
async function runDockerTarget(
|
|
263
263
|
smartshellInstance: plugins.smartshell.Smartshell,
|
|
264
264
|
workflow: IResolvedReleaseWorkflow,
|
|
265
|
-
newVersion: string,
|
|
266
265
|
): Promise<ITargetResult[]> {
|
|
267
266
|
if (!workflow.dockerEnabled) {
|
|
268
267
|
return [{ target: "docker", status: "skipped", message: "disabled" }];
|
|
269
268
|
}
|
|
270
|
-
if (workflow.dockerImages.length === 0) {
|
|
271
|
-
return [{ target: "docker", status: "failed", message: "no images configured" }];
|
|
272
|
-
}
|
|
273
269
|
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
270
|
+
const command = buildTsdockerPushCommand(workflow);
|
|
271
|
+
const result = await smartshellInstance.exec(command);
|
|
272
|
+
const output = `${result.stdout || ""}\n${(result as any).stderr || ""}\n${(result as any).combinedOutput || ""}`;
|
|
273
|
+
return [{
|
|
274
|
+
target: workflow.dockerPatterns.length > 0
|
|
275
|
+
? `tsdocker:${workflow.dockerPatterns.join(",")}`
|
|
276
|
+
: "tsdocker",
|
|
277
|
+
status: result.exitCode === 0 ? "success" : "failed",
|
|
278
|
+
message: result.exitCode === 0 ? undefined : firstMeaningfulLine(output),
|
|
279
|
+
}];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function buildTsdockerPushCommand(workflow: IResolvedReleaseWorkflow): string {
|
|
283
|
+
const commandParts = ["tsdocker", "push"];
|
|
284
|
+
if (workflow.dockerNoBuild) {
|
|
285
|
+
commandParts.push("--no-build");
|
|
288
286
|
}
|
|
289
|
-
|
|
287
|
+
if (workflow.dockerCached) {
|
|
288
|
+
commandParts.push("--cached");
|
|
289
|
+
}
|
|
290
|
+
if (workflow.dockerParallel === true) {
|
|
291
|
+
commandParts.push("--parallel");
|
|
292
|
+
} else if (typeof workflow.dockerParallel === "number" && Number.isFinite(workflow.dockerParallel) && workflow.dockerParallel > 0) {
|
|
293
|
+
commandParts.push(`--parallel=${Math.floor(workflow.dockerParallel)}`);
|
|
294
|
+
}
|
|
295
|
+
if (workflow.dockerContext) {
|
|
296
|
+
commandParts.push(`--context=${shellQuote(workflow.dockerContext)}`);
|
|
297
|
+
}
|
|
298
|
+
for (const pattern of workflow.dockerPatterns) {
|
|
299
|
+
commandParts.push(shellQuote(pattern));
|
|
300
|
+
}
|
|
301
|
+
return commandParts.join(" ");
|
|
290
302
|
}
|
|
291
303
|
|
|
292
304
|
function isAlreadyPublishedOutput(output: string): boolean {
|
|
@@ -315,11 +327,22 @@ function printReleasePlan(workflow: IResolvedReleaseWorkflow): void {
|
|
|
315
327
|
console.log(`npm registries: ${workflow.npmRegistries.length > 0 ? workflow.npmRegistries.join(", ") : "none"}`);
|
|
316
328
|
}
|
|
317
329
|
if (workflow.targets.includes("docker")) {
|
|
318
|
-
console.log(`docker
|
|
330
|
+
console.log(`docker engine: ${workflow.dockerEngine}`);
|
|
331
|
+
console.log(`docker patterns: ${workflow.dockerPatterns.length > 0 ? workflow.dockerPatterns.join(", ") : "all Dockerfiles"}`);
|
|
332
|
+
console.log(`docker options: ${formatDockerOptions(workflow)}`);
|
|
319
333
|
}
|
|
320
334
|
console.log("");
|
|
321
335
|
}
|
|
322
336
|
|
|
337
|
+
function formatDockerOptions(workflow: IResolvedReleaseWorkflow): string {
|
|
338
|
+
const options: string[] = [];
|
|
339
|
+
if (workflow.dockerCached) options.push("cached");
|
|
340
|
+
if (workflow.dockerParallel) options.push(`parallel=${workflow.dockerParallel === true ? "true" : workflow.dockerParallel}`);
|
|
341
|
+
if (workflow.dockerNoBuild) options.push("no-build");
|
|
342
|
+
if (workflow.dockerContext) options.push(`context=${workflow.dockerContext}`);
|
|
343
|
+
return options.length > 0 ? options.join(", ") : "default";
|
|
344
|
+
}
|
|
345
|
+
|
|
323
346
|
function printReleaseSummary(
|
|
324
347
|
newVersion: string,
|
|
325
348
|
gitResults: ITargetResult[],
|
|
@@ -365,7 +388,7 @@ export function showHelp(mode?: ICliMode): void {
|
|
|
365
388
|
{ flag: "-p, --push", description: "Enable the git release target" },
|
|
366
389
|
{ flag: "--target <names>", description: "Release only selected targets: git,npm,docker" },
|
|
367
390
|
{ flag: "--npm", description: "Enable the npm release target" },
|
|
368
|
-
{ flag: "--docker", description: "Enable the
|
|
391
|
+
{ flag: "--docker", description: "Enable the tsdocker release target" },
|
|
369
392
|
{ flag: "--no-publish", description: "Run release core and git target only" },
|
|
370
393
|
{ flag: "--plan", description: "Show resolved workflow without mutating files" },
|
|
371
394
|
],
|
|
@@ -385,7 +408,7 @@ export function showHelp(mode?: ICliMode): void {
|
|
|
385
408
|
console.log(" -p, --push Enable the git release target");
|
|
386
409
|
console.log(" --target <names> Release only selected targets: git,npm,docker");
|
|
387
410
|
console.log(" --npm Enable the npm release target");
|
|
388
|
-
console.log(" --docker Enable the
|
|
411
|
+
console.log(" --docker Enable the tsdocker release target");
|
|
389
412
|
console.log(" --no-publish Run release core and git target only");
|
|
390
413
|
console.log(" --major|--minor|--patch Override inferred semver level");
|
|
391
414
|
console.log(" --plan Show resolved workflow without mutating files");
|