@pagopa/dx-cli 0.20.1 → 0.21.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/README.md +12 -1
- package/bin/index.js +0 -20
- package/dist/adapters/azure/__tests__/cloud-account-service.test.js +132 -1
- package/dist/adapters/azure/cloud-account-service.d.ts +3 -2
- package/dist/adapters/azure/cloud-account-service.js +127 -39
- package/dist/adapters/commander/__tests__/error-reporting.test.d.ts +1 -0
- package/dist/adapters/commander/__tests__/error-reporting.test.js +63 -0
- package/dist/adapters/commander/__tests__/exit-with-error.test.d.ts +1 -0
- package/dist/adapters/commander/__tests__/exit-with-error.test.js +92 -0
- package/dist/adapters/commander/commands/add.d.ts +2 -0
- package/dist/adapters/commander/commands/add.js +8 -5
- package/dist/adapters/commander/commands/codemod.js +3 -2
- package/dist/adapters/commander/commands/init.js +2 -2
- package/dist/adapters/commander/commands/savemoney.js +6 -3
- package/dist/adapters/commander/error-reporting.d.ts +10 -0
- package/dist/adapters/commander/error-reporting.js +68 -0
- package/dist/adapters/commander/index.d.ts +17 -1
- package/dist/adapters/commander/index.js +23 -2
- package/dist/adapters/octokit/index.d.ts +2 -1
- package/dist/adapters/octokit/index.js +33 -0
- package/dist/adapters/plop/__tests__/run-actions.test.d.ts +1 -0
- package/dist/adapters/plop/__tests__/run-actions.test.js +68 -0
- package/dist/adapters/plop/actions/__tests__/init-cloud-accounts.test.js +24 -7
- package/dist/adapters/plop/actions/init-cloud-accounts.d.ts +3 -2
- package/dist/adapters/plop/actions/init-cloud-accounts.js +4 -4
- package/dist/adapters/plop/generators/environment/__tests__/actions.test.js +6 -1
- package/dist/adapters/plop/generators/environment/actions.js +12 -0
- package/dist/adapters/plop/generators/environment/index.d.ts +2 -1
- package/dist/adapters/plop/generators/environment/index.js +2 -2
- package/dist/adapters/plop/index.d.ts +5 -3
- package/dist/adapters/plop/index.js +20 -12
- package/dist/domain/cloud-account.d.ts +3 -2
- package/dist/domain/github.d.ts +13 -0
- package/dist/index.js +36 -0
- package/package.json +4 -2
- package/templates/environment/workflow/_release-terraform-apply-bootstrapper-{{env.name}}.yaml.hbs +19 -0
|
@@ -26,19 +26,27 @@ const validatePayload = async (payload, github) => {
|
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
export const getPlopInstance = async () => nodePlop();
|
|
29
|
-
const runActions = async (generator, payload) => {
|
|
29
|
+
export const runActions = async (generator, payload) => {
|
|
30
30
|
const logger = getLogger(["dx-cli", "init"]);
|
|
31
31
|
const result = await generator.runActions(payload);
|
|
32
32
|
if (result.failures.length > 0) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
// Collect every failure to report rich context. node-plop's failure
|
|
34
|
+
// objects have shape `{ type, path, error }` (the `error` property holds
|
|
35
|
+
// the original error's message — see node-plop's generator-runner.js).
|
|
36
|
+
const relevant = result.failures.filter((failure) => failure.error !== "Aborted due to previous action failure");
|
|
37
|
+
if (relevant.length === 0) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const summary = relevant
|
|
41
|
+
.map((failure) => `${failure.type || "action"}: ${failure.error ?? "unknown error"}`)
|
|
42
|
+
.join("; ");
|
|
43
|
+
for (const failure of relevant) {
|
|
44
|
+
logger.error("Error on {type} step: {error}", {
|
|
45
|
+
error: failure.error ?? "unknown error",
|
|
46
|
+
type: failure.type || "action",
|
|
39
47
|
});
|
|
40
|
-
throw new Error("One or more actions failed during generation.");
|
|
41
48
|
}
|
|
49
|
+
throw new Error(`One or more actions failed during generation (${summary}).`);
|
|
42
50
|
}
|
|
43
51
|
};
|
|
44
52
|
export const runMonorepoGenerator = async (plop, githubService) => {
|
|
@@ -62,8 +70,8 @@ export const runMonorepoGenerator = async (plop, githubService) => {
|
|
|
62
70
|
* uses the explicitly passed repository. When omitted (by add command),
|
|
63
71
|
* the generator infers it from the local git context.
|
|
64
72
|
*/
|
|
65
|
-
export const runDeploymentEnvironmentGenerator = async (plop, github) => {
|
|
66
|
-
setDeploymentEnvironmentGenerator(plop, github);
|
|
73
|
+
export const runDeploymentEnvironmentGenerator = async (plop, gitHubService, github) => {
|
|
74
|
+
setDeploymentEnvironmentGenerator(plop, gitHubService, github);
|
|
67
75
|
const generator = plop.getGenerator(PLOP_ENVIRONMENT_GENERATOR_NAME);
|
|
68
76
|
const answers = await generator.runPrompts();
|
|
69
77
|
const payload = environmentPayloadSchema.parse(answers);
|
|
@@ -82,10 +90,10 @@ export const runDeploymentEnvironmentGenerator = async (plop, github) => {
|
|
|
82
90
|
* uses the explicitly passed repository. When omitted (by add command),
|
|
83
91
|
* the generator infers it from the local git context.
|
|
84
92
|
*/
|
|
85
|
-
export const setDeploymentEnvironmentGenerator = (plop, github) => {
|
|
93
|
+
export const setDeploymentEnvironmentGenerator = (plop, gitHubService, github) => {
|
|
86
94
|
const credential = new AzureCliCredential();
|
|
87
95
|
const cloudAccountRepository = new AzureSubscriptionRepository(credential);
|
|
88
96
|
const cloudAccountService = new AzureCloudAccountService(credential);
|
|
89
97
|
const templatesPath = path.join(import.meta.dirname, "../../../templates/environment");
|
|
90
|
-
createDeploymentEnvironmentGenerator(plop, templatesPath, cloudAccountRepository, cloudAccountService, github);
|
|
98
|
+
createDeploymentEnvironmentGenerator(plop, templatesPath, cloudAccountRepository, cloudAccountService, gitHubService, github);
|
|
91
99
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
2
|
import { type EnvironmentId } from "./environment.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type GitHubRepo } from "./github-repo.js";
|
|
4
|
+
import { type GitHubAppCredentials, type GitHubService } from "./github.js";
|
|
4
5
|
import { TerraformBackend } from "./remote-backend.js";
|
|
5
6
|
export declare const cloudAccountSchema: z.ZodObject<{
|
|
6
7
|
csp: z.ZodDefault<z.ZodEnum<{
|
|
@@ -17,7 +18,7 @@ export type CloudAccountRepository = {
|
|
|
17
18
|
export type CloudAccountService = {
|
|
18
19
|
getTerraformBackend(cloudAccountId: CloudAccount["id"], environment: EnvironmentId): Promise<TerraformBackend | undefined>;
|
|
19
20
|
hasUserPermissionToInitialize(cloudAccountId: CloudAccount["id"]): Promise<boolean>;
|
|
20
|
-
initialize(cloudAccount: CloudAccount, environment: EnvironmentId, runnerAppCredentials: GitHubAppCredentials, tags?: Record<string, string>): Promise<void>;
|
|
21
|
+
initialize(cloudAccount: CloudAccount, environment: EnvironmentId, runnerAppCredentials: GitHubAppCredentials, github: GitHubRepo, gitHubService: GitHubService, tags?: Record<string, string>): Promise<void>;
|
|
21
22
|
isInitialized(cloudAccountId: CloudAccount["id"], environment: EnvironmentId): Promise<boolean>;
|
|
22
23
|
provisionTerraformBackend(cloudAccount: CloudAccount, environment: EnvironmentId, tags?: Record<string, string>): Promise<TerraformBackend>;
|
|
23
24
|
};
|
package/dist/domain/github.d.ts
CHANGED
|
@@ -5,6 +5,13 @@ export type CreateBranchParams = {
|
|
|
5
5
|
owner: string;
|
|
6
6
|
repo: string;
|
|
7
7
|
};
|
|
8
|
+
export type CreateOrUpdateEnvironmentSecretParams = {
|
|
9
|
+
environmentName: string;
|
|
10
|
+
owner: string;
|
|
11
|
+
repo: string;
|
|
12
|
+
secretName: string;
|
|
13
|
+
secretValue: string;
|
|
14
|
+
};
|
|
8
15
|
export type FileContent = {
|
|
9
16
|
content: string;
|
|
10
17
|
sha: string;
|
|
@@ -21,6 +28,12 @@ export interface GitHubService {
|
|
|
21
28
|
* @throws Error if branch creation fails
|
|
22
29
|
*/
|
|
23
30
|
createBranch(params: CreateBranchParams): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Creates or updates a secret in a GitHub repository environment.
|
|
33
|
+
* The value is automatically encrypted using the environment's public key.
|
|
34
|
+
* @throws Error if secret creation fails
|
|
35
|
+
*/
|
|
36
|
+
createOrUpdateEnvironmentSecret(params: CreateOrUpdateEnvironmentSecretParams): Promise<void>;
|
|
24
37
|
/**
|
|
25
38
|
* Creates a pull request in a GitHub repository.
|
|
26
39
|
* @throws Error if pull request creation fails
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "core-js/actual/set/index.js";
|
|
2
|
+
import { configure, getConsoleSink } from "@logtape/logtape";
|
|
2
3
|
import * as assert from "node:assert/strict";
|
|
3
4
|
import { Octokit } from "octokit";
|
|
4
5
|
import codemodRegistry from "./adapters/codemods/index.js";
|
|
@@ -13,7 +14,42 @@ import { getInfo } from "./domain/info.js";
|
|
|
13
14
|
import { applyCodemodById } from "./use-cases/apply-codemod.js";
|
|
14
15
|
import { listCodemods } from "./use-cases/list-codemods.js";
|
|
15
16
|
import { requestAuthorization } from "./use-cases/request-authorization.js";
|
|
17
|
+
/**
|
|
18
|
+
* Returns `true` when `-v` or `--verbose` is present in argv.
|
|
19
|
+
*
|
|
20
|
+
* We inspect argv directly — instead of relying on Commander — because the
|
|
21
|
+
* logtape configuration must be in place before any command handler runs
|
|
22
|
+
* (including the ones that emit debug logs while parsing prompts).
|
|
23
|
+
*/
|
|
24
|
+
const detectVerboseFromArgv = (argv) => argv.includes("-v") || argv.includes("--verbose");
|
|
25
|
+
const configureLogging = async (verbose) => {
|
|
26
|
+
const level = verbose ? "debug" : "info";
|
|
27
|
+
await configure({
|
|
28
|
+
loggers: [
|
|
29
|
+
{ category: ["dx-cli"], lowestLevel: level, sinks: ["console"] },
|
|
30
|
+
// The environment generator (`gen.env`) emits debug messages about
|
|
31
|
+
// provisioned Azure resources; surfacing them is the main value of
|
|
32
|
+
// `--verbose` when running `dx init` / `dx add environment`.
|
|
33
|
+
{ category: ["gen"], lowestLevel: level, sinks: ["console"] },
|
|
34
|
+
// `savemoney` already emits structured debug output by default.
|
|
35
|
+
{ category: ["savemoney"], lowestLevel: "debug", sinks: ["console"] },
|
|
36
|
+
{ category: ["json"], lowestLevel: "info", sinks: ["rawJson"] },
|
|
37
|
+
{
|
|
38
|
+
category: ["logtape", "meta"],
|
|
39
|
+
lowestLevel: "warning",
|
|
40
|
+
sinks: ["console"],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
sinks: {
|
|
44
|
+
console: getConsoleSink(),
|
|
45
|
+
rawJson(record) {
|
|
46
|
+
console.log(record.rawMessage);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
};
|
|
16
51
|
export const runCli = async (version) => {
|
|
52
|
+
await configureLogging(detectVerboseFromArgv(process.argv));
|
|
17
53
|
// Creating the adapters
|
|
18
54
|
const repositoryReader = makeRepositoryReader();
|
|
19
55
|
const packageJsonReader = makePackageJsonReader();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagopa/dx-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A CLI useful to manage DX tools.",
|
|
6
6
|
"repository": {
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"execa": "^9.6.1",
|
|
40
40
|
"glob": "^11.1.0",
|
|
41
41
|
"inquirer": "^9.3.8",
|
|
42
|
+
"libsodium-wrappers": "^0.8.2",
|
|
42
43
|
"neverthrow": "^8.2.0",
|
|
43
44
|
"node-plop": "^0.32.3",
|
|
44
45
|
"octokit": "^5.0.5",
|
|
@@ -52,10 +53,11 @@
|
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@tsconfig/node24": "24.0.4",
|
|
54
55
|
"@types/inquirer": "^9.0.9",
|
|
56
|
+
"@types/libsodium-wrappers": "^0.8.2",
|
|
55
57
|
"@types/node": "^22.19.17",
|
|
56
58
|
"@types/semver": "^7.7.1",
|
|
57
59
|
"@vitest/coverage-v8": "^3.2.4",
|
|
58
|
-
"eslint": "^10.2.
|
|
60
|
+
"eslint": "^10.2.1",
|
|
59
61
|
"memfs": "^4.57.1",
|
|
60
62
|
"plop": "^4.0.5",
|
|
61
63
|
"prettier": "3.8.3",
|
package/templates/environment/workflow/_release-terraform-apply-bootstrapper-{{env.name}}.yaml.hbs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: Release Bootstrapper Infrastructure - {{@root.env.name}}
|
|
2
|
+
on:
|
|
3
|
+
workflow_dispatch:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- "infra/bootstrapper/**"
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
release:
|
|
15
|
+
uses: pagopa/dx/.github/workflows/release-terraform-bootstrapper-v1.yaml@main
|
|
16
|
+
name: Release Bootstrapper ({{@root.env.name}})
|
|
17
|
+
secrets: inherit
|
|
18
|
+
with:
|
|
19
|
+
environment: '{{@root.env.name}}'
|