@pagopa/dx-cli 0.16.0 → 0.16.2

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.
@@ -5,6 +5,7 @@ import { $, ExecaError } from "execa";
5
5
  import { okAsync, ResultAsync } from "neverthrow";
6
6
  import * as path from "node:path";
7
7
  import { oraPromise } from "ora";
8
+ import { z } from "zod";
8
9
  import { Repository, } from "../../../domain/github.js";
9
10
  import { tf$ } from "../../execa/terraform.js";
10
11
  import { getPlopInstance, runDeploymentEnvironmentGenerator, runMonorepoGenerator, } from "../../plop/index.js";
@@ -34,8 +35,20 @@ const displaySummary = (initResult) => {
34
35
  console.log(`Please, manually create a Pull Request in the GitHub repository to review the scaffolded code.\n`);
35
36
  }
36
37
  };
37
- const checkTerraformCliIsInstalled = () => withSpinner("Checking Terraform installation...", "Terraform is installed!", "Please install terraform CLI before running this command.", tf$ `terraform -version`);
38
- const checkAzLogin = () => withSpinner("Check Azure login status...", "You are logged in to Azure", "Please log in to Azure CLI using `az login` before running this command.", tf$ `az account show`);
38
+ const checkTerraformCliIsInstalled = () => withSpinner("Checking Terraform installation...", "Terraform is installed!", "Please install terraform CLI before running this command. If you use tfenv, run: tfenv install latest && tfenv use latest", tf$ `terraform -version`);
39
+ const azureAccountSchema = z.object({
40
+ user: z.object({
41
+ name: z.string().min(1),
42
+ }),
43
+ });
44
+ const ensureAzLogin = async () => {
45
+ const { stdout } = await tf$ `az account show`;
46
+ await tf$ `az group list`;
47
+ const parsed = JSON.parse(stdout);
48
+ const { user } = azureAccountSchema.parse(parsed);
49
+ return user.name;
50
+ };
51
+ const checkAzLogin = () => withSpinner("Check Azure login status...", (userName) => `You are logged in to Azure (${userName})`, "Please log in to Azure CLI using `az login` before running this command.", ensureAzLogin());
39
52
  const checkPreconditions = () => checkTerraformCliIsInstalled().andThen(() => checkAzLogin());
40
53
  const createRemoteRepository = ({ repoName, repoOwner, }) => {
41
54
  const logger = getLogger(["dx-cli", "init"]);
@@ -110,7 +123,10 @@ export const makeInitCommand = ({ gitHubService, }) => new Command()
110
123
  process.chdir(payload.repoName);
111
124
  console.log(chalk.blue.bold("\nCloud Environment"));
112
125
  })
113
- .andThen((payload) => ResultAsync.fromPromise(runDeploymentEnvironmentGenerator(plop), handleGeneratorError).map(() => payload)))
126
+ .andThen((payload) => ResultAsync.fromPromise(runDeploymentEnvironmentGenerator(plop, {
127
+ owner: payload.repoOwner,
128
+ repo: payload.repoName,
129
+ }), handleGeneratorError).map(() => payload)))
114
130
  .andTee(() => console.log()) // Print a new line before the gh repo creation logs
115
131
  .andThen((payload) => handleNewGitHubRepository(gitHubService)(payload))
116
132
  .match(displaySummary, exitWithError(this));
@@ -9,7 +9,7 @@ export declare const makeMockPackageJson: (overrides?: Partial<PackageJson>) =>
9
9
  typescript: string;
10
10
  };
11
11
  name: string;
12
- scripts: Map<string & import("zod/v4").$brand<"ScriptName">, string> | {
12
+ scripts: Map<string & import("zod").$brand<"ScriptName">, string> | {
13
13
  build: string;
14
14
  "code-review": string;
15
15
  };
@@ -1,6 +1,7 @@
1
1
  import { type NodePlopAPI } from "node-plop";
2
2
  import { CloudAccountRepository, CloudAccountService } from "../../../../domain/cloud-account.js";
3
+ import { GitHubRepo } from "../../../../domain/github-repo.js";
3
4
  import { Payload, payloadSchema } from "./prompts.js";
4
5
  export declare const PLOP_ENVIRONMENT_GENERATOR_NAME = "DX_DeploymentEnvironment";
5
6
  export { Payload, payloadSchema };
6
- export default function (plop: NodePlopAPI, templatesPath: string, cloudAccountRepository: CloudAccountRepository, cloudAccountService: CloudAccountService): void;
7
+ export default function (plop: NodePlopAPI, templatesPath: string, cloudAccountRepository: CloudAccountRepository, cloudAccountService: CloudAccountService, github?: GitHubRepo): void;
@@ -8,7 +8,7 @@ import getActions from "./actions.js";
8
8
  import getPrompts, { payloadSchema } from "./prompts.js";
9
9
  export const PLOP_ENVIRONMENT_GENERATOR_NAME = "DX_DeploymentEnvironment";
10
10
  export { payloadSchema };
11
- export default function (plop, templatesPath, cloudAccountRepository, cloudAccountService) {
11
+ export default function (plop, templatesPath, cloudAccountRepository, cloudAccountService, github) {
12
12
  setEnvShortHelper(plop);
13
13
  setResourcePrefixHelper(plop);
14
14
  setEqHelper(plop);
@@ -18,6 +18,10 @@ export default function (plop, templatesPath, cloudAccountRepository, cloudAccou
18
18
  plop.setGenerator(PLOP_ENVIRONMENT_GENERATOR_NAME, {
19
19
  actions: getActions(templatesPath),
20
20
  description: "Generate a new deployment environment",
21
- prompts: getPrompts({ cloudAccountRepository, cloudAccountService }),
21
+ prompts: getPrompts({
22
+ cloudAccountRepository,
23
+ cloudAccountService,
24
+ github,
25
+ }),
22
26
  });
23
27
  }
@@ -6,6 +6,7 @@ type InquirerChoice<T> = inquirer.Separator | {
6
6
  value: T;
7
7
  };
8
8
  import { z } from "zod/v4";
9
+ import { GitHubRepo } from "../../../../domain/github-repo.js";
9
10
  export declare const workspaceSchema: z.ZodObject<{
10
11
  domain: z.ZodDefault<z.ZodString>;
11
12
  }, z.core.$strip>;
@@ -59,6 +60,7 @@ export type Payload = z.infer<typeof payloadSchema>;
59
60
  export type PromptsDependencies = {
60
61
  cloudAccountRepository: CloudAccountRepository;
61
62
  cloudAccountService: CloudAccountService;
63
+ github?: GitHubRepo;
62
64
  };
63
65
  declare const prompts: (deps: PromptsDependencies) => DynamicPromptsFunction;
64
66
  export declare const getCloudAccountChoices: (cloudAccounts: CloudAccount[]) => InquirerChoice<CloudAccount>[];
@@ -4,7 +4,7 @@ import { environmentSchema, getInitializationStatus, hasUserPermissionToInitiali
4
4
  import * as azure from "../../../azure/locations.js";
5
5
  import { getLogger } from "@logtape/logtape";
6
6
  import { z } from "zod/v4";
7
- import { githubRepoSchema } from "../../../../domain/github-repo.js";
7
+ import { githubRepoSchema, } from "../../../../domain/github-repo.js";
8
8
  import { getGithubRepo } from "../../../github/github-repo.js";
9
9
  const initSchema = z.object({
10
10
  cloudAccountsToInitialize: z.array(cloudAccountSchema),
@@ -27,7 +27,7 @@ export const payloadSchema = z.object({
27
27
  });
28
28
  const prompts = (deps) => async (inquirer) => {
29
29
  const logger = getLogger(["gen", "env"]);
30
- const github = await getGithubRepo();
30
+ const github = deps.github ?? (await getGithubRepo());
31
31
  assert.ok(github, "This generator only works inside a GitHub repository.");
32
32
  logger.debug("github repo {github}", { github });
33
33
  const answers = await inquirer.prompt([
@@ -1,8 +1,9 @@
1
1
  import type { NodePlopAPI } from "plop";
2
+ import { GitHubRepo } from "../../domain/github-repo.js";
2
3
  import { GitHubService } from "../../domain/github.js";
3
4
  import { Payload as MonorepoPayload } from "../plop/generators/monorepo/index.js";
4
5
  export declare const setMonorepoGenerator: (plop: NodePlopAPI) => void;
5
6
  export declare const getPlopInstance: () => Promise<NodePlopAPI>;
6
7
  export declare const runMonorepoGenerator: (plop: NodePlopAPI, githubService: GitHubService) => Promise<MonorepoPayload>;
7
- export declare const runDeploymentEnvironmentGenerator: (plop: NodePlopAPI) => Promise<void>;
8
- export declare const setDeploymentEnvironmentGenerator: (plop: NodePlopAPI) => void;
8
+ export declare const runDeploymentEnvironmentGenerator: (plop: NodePlopAPI, github: GitHubRepo) => Promise<void>;
9
+ export declare const setDeploymentEnvironmentGenerator: (plop: NodePlopAPI, github: GitHubRepo) => void;
@@ -25,23 +25,24 @@ const validatePayload = async (payload, github) => {
25
25
  }
26
26
  }
27
27
  };
28
- export const getPlopInstance = async () => {
29
- const plop = await nodePlop();
30
- setMonorepoGenerator(plop);
31
- setDeploymentEnvironmentGenerator(plop);
32
- return plop;
33
- };
28
+ export const getPlopInstance = async () => nodePlop();
34
29
  const runActions = async (generator, payload) => {
35
30
  const logger = getLogger(["dx-cli", "init"]);
36
31
  const result = await generator.runActions(payload);
37
32
  if (result.failures.length > 0) {
38
33
  for (const failure of result.failures) {
39
- logger.error(failure.message);
34
+ if (failure.error === "Aborted due to previous action failure") {
35
+ continue;
36
+ }
37
+ logger.error(`Error on {type} step. ${failure.message}`, {
38
+ type: failure.type,
39
+ });
40
+ throw new Error("One or more actions failed during generation.");
40
41
  }
41
- throw new Error("One or more actions failed during generation.");
42
42
  }
43
43
  };
44
44
  export const runMonorepoGenerator = async (plop, githubService) => {
45
+ setMonorepoGenerator(plop);
45
46
  const generator = plop.getGenerator(PLOP_MONOREPO_GENERATOR_NAME);
46
47
  const answers = await generator.runPrompts();
47
48
  const payload = monorepoPayloadSchema.parse(answers);
@@ -53,7 +54,8 @@ export const runMonorepoGenerator = async (plop, githubService) => {
53
54
  });
54
55
  return payload;
55
56
  };
56
- export const runDeploymentEnvironmentGenerator = async (plop) => {
57
+ export const runDeploymentEnvironmentGenerator = async (plop, github) => {
58
+ setDeploymentEnvironmentGenerator(plop, github);
57
59
  const generator = plop.getGenerator(PLOP_ENVIRONMENT_GENERATOR_NAME);
58
60
  const payload = await generator.runPrompts();
59
61
  await oraPromise(runActions(generator, payload), {
@@ -62,10 +64,10 @@ export const runDeploymentEnvironmentGenerator = async (plop) => {
62
64
  text: "Creating environment...",
63
65
  });
64
66
  };
65
- export const setDeploymentEnvironmentGenerator = (plop) => {
67
+ export const setDeploymentEnvironmentGenerator = (plop, github) => {
66
68
  const credential = new AzureCliCredential();
67
69
  const cloudAccountRepository = new AzureSubscriptionRepository(credential);
68
70
  const cloudAccountService = new AzureCloudAccountService(credential);
69
71
  const templatesPath = path.join(import.meta.dirname, "../../../templates/environment");
70
- createDeploymentEnvironmentGenerator(plop, templatesPath, cloudAccountRepository, cloudAccountService);
72
+ createDeploymentEnvironmentGenerator(plop, templatesPath, cloudAccountRepository, cloudAccountService, github);
71
73
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagopa/dx-cli",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "type": "module",
5
5
  "description": "A CLI useful to manage DX tools.",
6
6
  "repository": {
@@ -0,0 +1,305 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/macos,turbo,terraform,intellij+all,node
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=macos,turbo,terraform,intellij+all,node
3
+
4
+ ### Intellij+all ###
5
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
6
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
7
+
8
+ # User-specific stuff
9
+ .idea/**/workspace.xml
10
+ .idea/**/tasks.xml
11
+ .idea/**/usage.statistics.xml
12
+ .idea/**/dictionaries
13
+ .idea/**/shelf
14
+
15
+ # AWS User-specific
16
+ .idea/**/aws.xml
17
+
18
+ # Generated files
19
+ .idea/**/contentModel.xml
20
+
21
+ # Sensitive or high-churn files
22
+ .idea/**/dataSources/
23
+ .idea/**/dataSources.ids
24
+ .idea/**/dataSources.local.xml
25
+ .idea/**/sqlDataSources.xml
26
+ .idea/**/dynamic.xml
27
+ .idea/**/uiDesigner.xml
28
+ .idea/**/dbnavigator.xml
29
+
30
+ # Gradle
31
+ .idea/**/gradle.xml
32
+ .idea/**/libraries
33
+
34
+ # Gradle and Maven with auto-import
35
+ # When using Gradle or Maven with auto-import, you should exclude module files,
36
+ # since they will be recreated, and may cause churn. Uncomment if using
37
+ # auto-import.
38
+ # .idea/artifacts
39
+ # .idea/compiler.xml
40
+ # .idea/jarRepositories.xml
41
+ # .idea/modules.xml
42
+ # .idea/*.iml
43
+ # .idea/modules
44
+ # *.iml
45
+ # *.ipr
46
+
47
+ # CMake
48
+ cmake-build-*/
49
+
50
+ # Mongo Explorer plugin
51
+ .idea/**/mongoSettings.xml
52
+
53
+ # File-based project format
54
+ *.iws
55
+
56
+ # IntelliJ
57
+ out/
58
+
59
+ # mpeltonen/sbt-idea plugin
60
+ .idea_modules/
61
+
62
+ # JIRA plugin
63
+ atlassian-ide-plugin.xml
64
+
65
+ # Cursive Clojure plugin
66
+ .idea/replstate.xml
67
+
68
+ # SonarLint plugin
69
+ .idea/sonarlint/
70
+
71
+ # Crashlytics plugin (for Android Studio and IntelliJ)
72
+ com_crashlytics_export_strings.xml
73
+ crashlytics.properties
74
+ crashlytics-build.properties
75
+ fabric.properties
76
+
77
+ # Editor-based Rest Client
78
+ .idea/httpRequests
79
+
80
+ # Android studio 3.1+ serialized cache file
81
+ .idea/caches/build_file_checksums.ser
82
+
83
+ ### Intellij+all Patch ###
84
+ # Ignore everything but code style settings and run configurations
85
+ # that are supposed to be shared within teams.
86
+
87
+ .idea/*
88
+
89
+ !.idea/codeStyles
90
+ !.idea/runConfigurations
91
+
92
+ ### macOS ###
93
+ # General
94
+ .DS_Store
95
+ .AppleDouble
96
+ .LSOverride
97
+
98
+ # Icon must end with two \r
99
+ Icon
100
+
101
+
102
+ # Thumbnails
103
+ ._*
104
+
105
+ # Files that might appear in the root of a volume
106
+ .DocumentRevisions-V100
107
+ .fseventsd
108
+ .Spotlight-V100
109
+ .TemporaryItems
110
+ .Trashes
111
+ .VolumeIcon.icns
112
+ .com.apple.timemachine.donotpresent
113
+
114
+ # Directories potentially created on remote AFP share
115
+ .AppleDB
116
+ .AppleDesktop
117
+ Network Trash Folder
118
+ Temporary Items
119
+ .apdisk
120
+
121
+ ### macOS Patch ###
122
+ # iCloud generated files
123
+ *.icloud
124
+
125
+ ### Node ###
126
+ # Logs
127
+ logs
128
+ *.log
129
+ npm-debug.log*
130
+ yarn-debug.log*
131
+ yarn-error.log*
132
+ lerna-debug.log*
133
+ .pnpm-debug.log*
134
+
135
+ # Diagnostic reports (https://nodejs.org/api/report.html)
136
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
137
+
138
+ # Runtime data
139
+ pids
140
+ *.pid
141
+ *.seed
142
+ *.pid.lock
143
+
144
+ # Directory for instrumented libs generated by jscoverage/JSCover
145
+ lib-cov
146
+
147
+ # Coverage directory used by tools like istanbul
148
+ coverage
149
+ *.lcov
150
+
151
+ # nyc test coverage
152
+ .nyc_output
153
+
154
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
155
+ .grunt
156
+
157
+ # Bower dependency directory (https://bower.io/)
158
+ bower_components
159
+
160
+ # node-waf configuration
161
+ .lock-wscript
162
+
163
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
164
+ build/Release
165
+
166
+ # Dependency directories
167
+ node_modules/
168
+ jspm_packages/
169
+
170
+ # Snowpack dependency directory (https://snowpack.dev/)
171
+ web_modules/
172
+
173
+ # TypeScript cache
174
+ *.tsbuildinfo
175
+
176
+ # Optional npm cache directory
177
+ .npm
178
+
179
+ # Optional eslint cache
180
+ .eslintcache
181
+
182
+ # Optional stylelint cache
183
+ .stylelintcache
184
+
185
+ # Microbundle cache
186
+ .rpt2_cache/
187
+ .rts2_cache_cjs/
188
+ .rts2_cache_es/
189
+ .rts2_cache_umd/
190
+
191
+ # Optional REPL history
192
+ .node_repl_history
193
+
194
+ # Output of 'npm pack'
195
+ *.tgz
196
+
197
+ # Yarn Integrity file
198
+ .yarn-integrity
199
+
200
+ # dotenv environment variable files
201
+ .env
202
+ .env.development.local
203
+ .env.test.local
204
+ .env.production.local
205
+ .env.local
206
+
207
+ # parcel-bundler cache (https://parceljs.org/)
208
+ .cache
209
+ .parcel-cache
210
+
211
+ # Next.js build output
212
+ .next
213
+ out
214
+
215
+ # Nuxt.js build / generate output
216
+ .nuxt
217
+ dist
218
+
219
+ # Gatsby files
220
+ .cache/
221
+ # Comment in the public line in if your project uses Gatsby and not Next.js
222
+ # https://nextjs.org/blog/next-9-1#public-directory-support
223
+ # public
224
+
225
+ # vuepress build output
226
+ .vuepress/dist
227
+
228
+ # vuepress v2.x temp and cache directory
229
+ .temp
230
+
231
+ # Docusaurus cache and generated files
232
+ .docusaurus
233
+
234
+ # Serverless directories
235
+ .serverless/
236
+
237
+ # FuseBox cache
238
+ .fusebox/
239
+
240
+ # DynamoDB Local files
241
+ .dynamodb/
242
+
243
+ # TernJS port file
244
+ .tern-port
245
+
246
+ # Stores VSCode versions used for testing VSCode extensions
247
+ .vscode-test
248
+
249
+ # yarn v2
250
+ .yarn/cache
251
+ .yarn/unplugged
252
+ .yarn/build-state.yml
253
+ .yarn/install-state.gz
254
+ .pnp.*
255
+
256
+ ### Node Patch ###
257
+ # Serverless Webpack directories
258
+ .webpack/
259
+
260
+ # Optional stylelint cache
261
+
262
+ # SvelteKit build / generate output
263
+ .svelte-kit
264
+
265
+ ### Terraform ###
266
+ # Local .terraform directories
267
+ **/.terraform/*
268
+
269
+ # .tfstate files
270
+ *.tfstate
271
+ *.tfstate.*
272
+
273
+ # Crash log files
274
+ crash.log
275
+ crash.*.log
276
+
277
+ # Exclude all .tfvars files, which are likely to contain sensitive data, such as
278
+ # password, private keys, and other secrets. These should not be part of version
279
+ # control as they are data points which are potentially sensitive and subject
280
+ # to change depending on the environment.
281
+ *.tfvars
282
+ *.tfvars.json
283
+
284
+ # Ignore override files as they are usually used to override resources locally and so
285
+ # are not checked in
286
+ override.tf
287
+ override.tf.json
288
+ *_override.tf
289
+ *_override.tf.json
290
+
291
+ # Include override files you do wish to add to version control using negated pattern
292
+ # !example_override.tf
293
+
294
+ # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
295
+ # example: *tfplan*
296
+
297
+ # Ignore CLI configuration files
298
+ .terraformrc
299
+ terraform.rc
300
+
301
+ ### Turbo ###
302
+ # Turborepo task cache
303
+ .turbo
304
+
305
+ # End of https://www.toptal.com/developers/gitignore/api/macos,turbo,terraform,intellij+all,node