@expressots/cli 3.0.0-beta.4 → 4.0.0-preview.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.
- package/README.md +41 -95
- package/bin/cicd/cli.d.ts +6 -0
- package/bin/cicd/cli.js +126 -0
- package/bin/cicd/form.d.ts +29 -0
- package/bin/cicd/form.js +345 -0
- package/bin/cicd/generators/azure-devops.d.ts +2 -0
- package/bin/cicd/generators/azure-devops.js +370 -0
- package/bin/cicd/generators/bitbucket.d.ts +2 -0
- package/bin/cicd/generators/bitbucket.js +217 -0
- package/bin/cicd/generators/circleci.d.ts +2 -0
- package/bin/cicd/generators/circleci.js +274 -0
- package/bin/cicd/generators/github-actions.d.ts +14 -0
- package/bin/cicd/generators/github-actions.js +426 -0
- package/bin/cicd/generators/gitlab-ci.d.ts +2 -0
- package/bin/cicd/generators/gitlab-ci.js +237 -0
- package/bin/cicd/generators/index.d.ts +6 -0
- package/bin/cicd/generators/index.js +15 -0
- package/bin/cicd/generators/jenkins.d.ts +2 -0
- package/bin/cicd/generators/jenkins.js +248 -0
- package/bin/cicd/generators/template-loader.d.ts +17 -0
- package/bin/cicd/generators/template-loader.js +128 -0
- package/bin/cicd/index.d.ts +1 -0
- package/bin/cicd/index.js +5 -0
- package/bin/cli.d.ts +1 -1
- package/bin/cli.js +18 -3
- package/bin/commands/project.commands.d.ts +19 -6
- package/bin/commands/project.commands.js +390 -61
- package/bin/config/index.d.ts +5 -0
- package/bin/config/index.js +10 -0
- package/bin/config/manager.d.ts +98 -0
- package/bin/config/manager.js +222 -0
- package/bin/containerize/analyzers/bootstrap-analyzer.d.ts +46 -0
- package/bin/containerize/analyzers/bootstrap-analyzer.js +187 -0
- package/bin/containerize/analyzers/project-analyzer.d.ts +20 -0
- package/bin/containerize/analyzers/project-analyzer.js +150 -0
- package/bin/containerize/cli.d.ts +4 -0
- package/bin/containerize/cli.js +113 -0
- package/bin/containerize/form.d.ts +15 -0
- package/bin/containerize/form.js +154 -0
- package/bin/containerize/generators/ci-generator.d.ts +31 -0
- package/bin/containerize/generators/ci-generator.js +936 -0
- package/bin/containerize/generators/docker-compose-generator.d.ts +8 -0
- package/bin/containerize/generators/docker-compose-generator.js +186 -0
- package/bin/containerize/generators/dockerfile-generator.d.ts +8 -0
- package/bin/containerize/generators/dockerfile-generator.js +635 -0
- package/bin/containerize/generators/kubernetes-generator.d.ts +8 -0
- package/bin/containerize/generators/kubernetes-generator.js +133 -0
- package/bin/containerize/generators/template-loader.d.ts +36 -0
- package/bin/containerize/generators/template-loader.js +129 -0
- package/bin/containerize/index.d.ts +4 -0
- package/bin/containerize/index.js +13 -0
- package/bin/containerize/presets/preset-registry.d.ts +20 -0
- package/bin/containerize/presets/preset-registry.js +102 -0
- package/bin/costs/cli.d.ts +5 -0
- package/bin/costs/cli.js +183 -0
- package/bin/costs/form.d.ts +44 -0
- package/bin/costs/form.js +412 -0
- package/bin/costs/index.d.ts +4 -0
- package/bin/costs/index.js +25 -0
- package/bin/costs/pricing-manager.d.ts +84 -0
- package/bin/costs/pricing-manager.js +342 -0
- package/bin/costs/providers/index.d.ts +32 -0
- package/bin/costs/providers/index.js +153 -0
- package/bin/costs/sources/api-source.d.ts +10 -0
- package/bin/costs/sources/api-source.js +32 -0
- package/bin/costs/sources/index.d.ts +6 -0
- package/bin/costs/sources/index.js +15 -0
- package/bin/costs/sources/local-json-source.d.ts +23 -0
- package/bin/costs/sources/local-json-source.js +59 -0
- package/bin/costs/sources/remote-json-source.d.ts +11 -0
- package/bin/costs/sources/remote-json-source.js +53 -0
- package/bin/costs/types.d.ts +53 -0
- package/bin/costs/types.js +5 -0
- package/bin/dev/cli.d.ts +4 -0
- package/bin/dev/cli.js +134 -0
- package/bin/dev/form.d.ts +36 -0
- package/bin/dev/form.js +254 -0
- package/bin/dev/index.d.ts +1 -0
- package/bin/dev/index.js +5 -0
- package/bin/generate/cli.js +29 -2
- package/bin/generate/form.d.ts +5 -1
- package/bin/generate/form.js +3 -3
- package/bin/generate/templates/nonopinionated/config.tpl +12 -0
- package/bin/generate/templates/nonopinionated/event.tpl +10 -0
- package/bin/generate/templates/nonopinionated/guard.tpl +18 -0
- package/bin/generate/templates/nonopinionated/handler.tpl +12 -0
- package/bin/generate/templates/nonopinionated/interceptor.tpl +27 -0
- package/bin/generate/templates/opinionated/config.tpl +47 -0
- package/bin/generate/templates/opinionated/entity.tpl +1 -8
- package/bin/generate/templates/opinionated/event.tpl +15 -0
- package/bin/generate/templates/opinionated/guard.tpl +41 -0
- package/bin/generate/templates/opinionated/handler.tpl +23 -0
- package/bin/generate/templates/opinionated/interceptor.tpl +50 -0
- package/bin/generate/utils/command-utils.d.ts +7 -3
- package/bin/generate/utils/command-utils.js +95 -31
- package/bin/generate/utils/nonopininated-cmd.d.ts +10 -1
- package/bin/generate/utils/nonopininated-cmd.js +100 -1
- package/bin/generate/utils/opinionated-cmd.d.ts +10 -1
- package/bin/generate/utils/opinionated-cmd.js +112 -7
- package/bin/generate/utils/string-utils.d.ts +6 -0
- package/bin/generate/utils/string-utils.js +13 -1
- package/bin/help/form.js +11 -3
- package/bin/migrate/analyzers/platform-detector.d.ts +14 -0
- package/bin/migrate/analyzers/platform-detector.js +116 -0
- package/bin/migrate/cli.d.ts +6 -0
- package/bin/migrate/cli.js +96 -0
- package/bin/migrate/form.d.ts +25 -0
- package/bin/migrate/form.js +347 -0
- package/bin/migrate/generators/compose-to-k8s.d.ts +2 -0
- package/bin/migrate/generators/compose-to-k8s.js +324 -0
- package/bin/migrate/generators/compose-to-railway.d.ts +2 -0
- package/bin/migrate/generators/compose-to-railway.js +138 -0
- package/bin/migrate/generators/compose-to-render.d.ts +2 -0
- package/bin/migrate/generators/compose-to-render.js +148 -0
- package/bin/migrate/generators/generic-migration.d.ts +9 -0
- package/bin/migrate/generators/generic-migration.js +221 -0
- package/bin/migrate/generators/heroku-to-fly.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-fly.js +291 -0
- package/bin/migrate/generators/heroku-to-railway.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-railway.js +283 -0
- package/bin/migrate/generators/heroku-to-render.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-render.js +148 -0
- package/bin/migrate/generators/index.d.ts +7 -0
- package/bin/migrate/generators/index.js +17 -0
- package/bin/migrate/generators/template-loader.d.ts +21 -0
- package/bin/migrate/generators/template-loader.js +59 -0
- package/bin/migrate/index.d.ts +1 -0
- package/bin/migrate/index.js +5 -0
- package/bin/new/cli.js +21 -6
- package/bin/new/form.d.ts +25 -4
- package/bin/new/form.js +285 -70
- package/bin/profile/analyzers/dockerfile-analyzer.d.ts +27 -0
- package/bin/profile/analyzers/dockerfile-analyzer.js +122 -0
- package/bin/profile/analyzers/image-analyzer.d.ts +19 -0
- package/bin/profile/analyzers/image-analyzer.js +85 -0
- package/bin/profile/cli.d.ts +4 -0
- package/bin/profile/cli.js +92 -0
- package/bin/profile/form.d.ts +56 -0
- package/bin/profile/form.js +400 -0
- package/bin/profile/index.d.ts +1 -0
- package/bin/profile/index.js +5 -0
- package/bin/profile/optimizers/index.d.ts +19 -0
- package/bin/profile/optimizers/index.js +137 -0
- package/bin/providers/add/form.d.ts +1 -1
- package/bin/providers/add/form.js +27 -6
- package/bin/providers/create/form.js +2 -1
- package/bin/scripts/form.js +27 -5
- package/bin/studio/cli.d.ts +15 -0
- package/bin/studio/cli.js +166 -0
- package/bin/studio/index.d.ts +5 -0
- package/bin/studio/index.js +9 -0
- package/bin/templates/cache.d.ts +54 -0
- package/bin/templates/cache.js +180 -0
- package/bin/templates/cli.d.ts +8 -0
- package/bin/templates/cli.js +292 -0
- package/bin/templates/fetcher.d.ts +49 -0
- package/bin/templates/fetcher.js +208 -0
- package/bin/templates/index.d.ts +11 -0
- package/bin/templates/index.js +37 -0
- package/bin/templates/manager.d.ts +116 -0
- package/bin/templates/manager.js +323 -0
- package/bin/templates/renderer.d.ts +49 -0
- package/bin/templates/renderer.js +204 -0
- package/bin/templates/types.d.ts +51 -0
- package/bin/templates/types.js +5 -0
- package/bin/utils/add-module-to-container.d.ts +2 -2
- package/bin/utils/add-module-to-container.js +15 -5
- package/bin/utils/cli-ui.d.ts +30 -3
- package/bin/utils/cli-ui.js +95 -13
- package/bin/utils/index.d.ts +4 -0
- package/bin/utils/index.js +4 -0
- package/bin/utils/input-validation.d.ts +50 -0
- package/bin/utils/input-validation.js +143 -0
- package/bin/utils/package-manager-commands.d.ts +24 -0
- package/bin/utils/package-manager-commands.js +50 -0
- package/bin/utils/safe-spawn.d.ts +35 -0
- package/bin/utils/safe-spawn.js +51 -0
- package/bin/utils/update-tsconfig-paths.d.ts +35 -0
- package/bin/utils/update-tsconfig-paths.js +286 -0
- package/package.json +154 -154
package/README.md
CHANGED
|
@@ -1,118 +1,64 @@
|
|
|
1
|
-
<a name="readme-top"></a>
|
|
2
|
-
|
|
3
|
-
<!-- PROJECT SHIELDS -->
|
|
4
|
-
|
|
5
|
-
[![Codecov][codecov-shield]][codecov-url]
|
|
6
|
-
[![NPM][npm-shield]][npm-url]
|
|
7
|
-
![Build][build-shield]
|
|
8
|
-
[![Contributors][contributors-shield]][contributors-url]
|
|
9
|
-
[![Forks][forks-shield]][forks-url]
|
|
10
|
-
[![Stargazers][stars-shield]][stars-url]
|
|
11
|
-
[![Issues][issues-shield]][issues-url]
|
|
12
|
-
[![MIT License][license-shield]][license-url]
|
|
13
|
-
[![LinkedIn][linkedin-shield]][linkedin-url]
|
|
14
|
-
|
|
15
|
-
<!-- PROJECT LOGO -->
|
|
16
|
-
<br />
|
|
17
1
|
<div align="center">
|
|
18
|
-
<a href="https://
|
|
19
|
-
<img src="https://github.com/expressots/expressots/blob/main/media/expressots.png" alt="
|
|
2
|
+
<a href="https://expresso-ts.com">
|
|
3
|
+
<img src="https://github.com/expressots/expressots/blob/main/media/expressots.png" alt="ExpressoTS" width="120">
|
|
20
4
|
</a>
|
|
21
5
|
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
<p
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<a href="https://
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
·
|
|
34
|
-
<a href="https://
|
|
6
|
+
<h1>@expressots/cli</h1>
|
|
7
|
+
|
|
8
|
+
<p>Command-line tool for scaffolding, generating, and deploying ExpressoTS applications.</p>
|
|
9
|
+
|
|
10
|
+
<p>
|
|
11
|
+
<a href="https://www.npmjs.com/package/@expressots/cli"><img src="https://img.shields.io/npm/v/@expressots/cli?style=flat&color=0d0d0d" alt="npm"></a>
|
|
12
|
+
<a href="https://github.com/expressots/expressots-cli/blob/main/LICENSE.md"><img src="https://img.shields.io/github/license/expressots/expressots-cli?style=flat&color=0d0d0d" alt="License"></a>
|
|
13
|
+
<a href="https://discord.com/invite/PyPJfGK"><img src="https://img.shields.io/badge/Discord-join-0d0d0d?logo=discord&logoColor=white" alt="Discord"></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p>
|
|
17
|
+
<a href="https://doc.expresso-ts.com">Documentation</a> ·
|
|
18
|
+
<a href="https://doc.expresso-ts.com/docs/cli/overview">CLI Reference</a> ·
|
|
19
|
+
<a href="https://discord.com/invite/PyPJfGK">Community</a>
|
|
35
20
|
</p>
|
|
36
21
|
</div>
|
|
37
22
|
|
|
38
|
-
|
|
39
|
-
<details>
|
|
40
|
-
<summary>Table of Contents</summary>
|
|
41
|
-
<ol>
|
|
42
|
-
<li><a href="#about-the-project">About The Project</a></li>
|
|
43
|
-
<li><a href="#getting-started">Getting Started</a></li>
|
|
44
|
-
<li><a href="#contributing">Contributing</a></li>
|
|
45
|
-
<li><a href="#support-the-project">Support the project</a></li>
|
|
46
|
-
<li><a href="#license">License</a></li>
|
|
47
|
-
</ol>
|
|
48
|
-
</details>
|
|
23
|
+
---
|
|
49
24
|
|
|
50
|
-
|
|
25
|
+
## Install
|
|
51
26
|
|
|
52
|
-
|
|
27
|
+
```bash
|
|
28
|
+
npm i -g @expressots/cli
|
|
29
|
+
```
|
|
53
30
|
|
|
54
|
-
|
|
31
|
+
## What This Package Does
|
|
55
32
|
|
|
56
|
-
|
|
33
|
+
The ExpressoTS CLI creates new projects, generates controllers, use-cases, providers, and modules, manages CI/CD pipelines, Docker and Kubernetes configs, and handles deployment workflows — all from the terminal. It is the fastest way to go from zero to a running application.
|
|
57
34
|
|
|
58
|
-
|
|
59
|
-
- You can find our [Documentation here](https://doc.expresso-ts.com/)
|
|
60
|
-
- Checkout our [First Steps documentation](https://doc.expresso-ts.com/docs/overview/first-steps)
|
|
61
|
-
- Our [CLI Documentation](https://doc.expresso-ts.com/docs/cli/overview)
|
|
35
|
+
## Quick Look
|
|
62
36
|
|
|
63
|
-
|
|
37
|
+
```bash
|
|
38
|
+
# Create a new project
|
|
39
|
+
expressots new my-app
|
|
64
40
|
|
|
65
|
-
|
|
66
|
-
|
|
41
|
+
# Generate a use-case
|
|
42
|
+
expressots generate usecase user/create
|
|
67
43
|
|
|
68
|
-
|
|
44
|
+
# Start in development
|
|
45
|
+
expressots dev
|
|
46
|
+
```
|
|
69
47
|
|
|
70
|
-
|
|
71
|
-
- **Build Your Portfolio**: Contributing to an open-source project like ExpressoTS is a great way to showcase your skills.
|
|
72
|
-
- **Join a Network**: Get to know a community of like-minded developers.
|
|
73
|
-
- **Improve the Product**: Help us fill in the gaps, correct errors, or make complex topics easier to understand.
|
|
48
|
+
## Documentation
|
|
74
49
|
|
|
75
|
-
|
|
50
|
+
For the full command reference and usage guides visit **[doc.expresso-ts.com/docs/cli/overview](https://doc.expresso-ts.com/docs/cli/overview)**.
|
|
76
51
|
|
|
77
|
-
|
|
78
|
-
- [How to Contribute](https://github.com/expressots/expressots/blob/main/CONTRIBUTING_HOWTO.md)
|
|
79
|
-
- [Coding Guidelines](https://github.com/rsaz/TypescriptCodingGuidelines)
|
|
52
|
+
## Contributing
|
|
80
53
|
|
|
81
|
-
|
|
54
|
+
See the [Contributing Guide](https://github.com/expressots/expressots/blob/main/CONTRIBUTING.md) for how to get involved.
|
|
82
55
|
|
|
83
|
-
|
|
56
|
+
## Support
|
|
84
57
|
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
|
|
89
|
-
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues)**
|
|
90
|
-
- Share the project with your friends and colleagues
|
|
58
|
+
- [GitHub Sponsors](https://github.com/sponsors/expressots)
|
|
59
|
+
- [Discord](https://discord.com/invite/PyPJfGK)
|
|
60
|
+
- [Report an Issue](https://github.com/expressots/expressots-cli/issues)
|
|
91
61
|
|
|
92
62
|
## License
|
|
93
63
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
97
|
-
|
|
98
|
-
<!-- MARKDOWN LINKS & IMAGES -->
|
|
99
|
-
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
|
|
100
|
-
|
|
101
|
-
[codecov-url]: https://codecov.io/gh/expressots/expressots-cli
|
|
102
|
-
[codecov-shield]: https://img.shields.io/codecov/c/gh/expressots/expressots-cli/main?style=for-the-badge&logo=codecov&labelColor=FB9AD1
|
|
103
|
-
[npm-url]: https://www.npmjs.com/package/@expressots/expressots-cli
|
|
104
|
-
[npm-shield]: https://img.shields.io/npm/v/%40expressots%2Fcli?style=for-the-badge&logo=npm&color=9B3922
|
|
105
|
-
[build-shield]: https://img.shields.io/github/actions/workflow/status/expressots/expressots-cli/build.yml?branch=main&style=for-the-badge&logo=github
|
|
106
|
-
[contributors-shield]: https://img.shields.io/github/contributors/expressots/expressots-cli?style=for-the-badge
|
|
107
|
-
[contributors-url]: https://github.com/expressots/expressots-cli/graphs/contributors
|
|
108
|
-
[forks-shield]: https://img.shields.io/github/forks/expressots/expressots-cli?style=for-the-badge
|
|
109
|
-
[forks-url]: https://github.com/expressots/expressots-cli/forks
|
|
110
|
-
[stars-shield]: https://img.shields.io/github/stars/expressots/expressots-cli?style=for-the-badge
|
|
111
|
-
[stars-url]: https://github.com/expressots/expressots-cli/stargazers
|
|
112
|
-
[issues-shield]: https://img.shields.io/github/issues/expressots/expressots-cli?style=for-the-badge
|
|
113
|
-
[issues-url]: https://github.com/expressots/expressots-cli/issues
|
|
114
|
-
[license-shield]: https://img.shields.io/github/license/expressots/expressots-cli?style=for-the-badge
|
|
115
|
-
[license-url]: https://github.com/expressots/expressots-cli/blob/main/LICENSE
|
|
116
|
-
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
|
|
117
|
-
[linkedin-url]: https://www.linkedin.com/company/expresso-ts/
|
|
118
|
-
[product-screenshot]: images/screenshot.png
|
|
64
|
+
MIT — see [LICENSE](./LICENSE.md).
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CommandModule } from "yargs";
|
|
2
|
+
type CommandModuleArgs = {};
|
|
3
|
+
export type CIPlatform = "github" | "gitlab" | "circleci" | "jenkins" | "bitbucket" | "azure";
|
|
4
|
+
export type CIStrategy = "basic" | "comprehensive" | "security-focused";
|
|
5
|
+
declare const cicdCommand: () => CommandModule<CommandModuleArgs, any>;
|
|
6
|
+
export { cicdCommand };
|
package/bin/cicd/cli.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cicdCommand = void 0;
|
|
4
|
+
const form_1 = require("./form");
|
|
5
|
+
const cicdCommand = () => {
|
|
6
|
+
return {
|
|
7
|
+
command: "cicd <action> [platform]",
|
|
8
|
+
describe: "Generate and manage CI/CD pipeline configurations.",
|
|
9
|
+
aliases: ["ci", "pipeline"],
|
|
10
|
+
builder: (yargs) => {
|
|
11
|
+
yargs.positional("action", {
|
|
12
|
+
choices: ["init", "generate", "list", "validate"],
|
|
13
|
+
describe: "Action to perform",
|
|
14
|
+
type: "string",
|
|
15
|
+
demandOption: true,
|
|
16
|
+
});
|
|
17
|
+
yargs.positional("platform", {
|
|
18
|
+
choices: [
|
|
19
|
+
"github",
|
|
20
|
+
"gitlab",
|
|
21
|
+
"circleci",
|
|
22
|
+
"jenkins",
|
|
23
|
+
"bitbucket",
|
|
24
|
+
"azure",
|
|
25
|
+
"all",
|
|
26
|
+
],
|
|
27
|
+
describe: "CI/CD platform to generate for",
|
|
28
|
+
type: "string",
|
|
29
|
+
});
|
|
30
|
+
yargs.option("strategy", {
|
|
31
|
+
choices: [
|
|
32
|
+
"basic",
|
|
33
|
+
"comprehensive",
|
|
34
|
+
"security-focused",
|
|
35
|
+
],
|
|
36
|
+
describe: "CI/CD pipeline strategy",
|
|
37
|
+
type: "string",
|
|
38
|
+
alias: "s",
|
|
39
|
+
default: "comprehensive",
|
|
40
|
+
});
|
|
41
|
+
yargs.option("include-security", {
|
|
42
|
+
describe: "Include security scanning (Trivy, Snyk)",
|
|
43
|
+
type: "boolean",
|
|
44
|
+
default: true,
|
|
45
|
+
});
|
|
46
|
+
yargs.option("include-e2e", {
|
|
47
|
+
describe: "Include end-to-end tests",
|
|
48
|
+
type: "boolean",
|
|
49
|
+
default: false,
|
|
50
|
+
});
|
|
51
|
+
yargs.option("include-coverage", {
|
|
52
|
+
describe: "Include code coverage reporting",
|
|
53
|
+
type: "boolean",
|
|
54
|
+
default: true,
|
|
55
|
+
});
|
|
56
|
+
yargs.option("docker-registry", {
|
|
57
|
+
describe: "Docker registry URL (e.g., ghcr.io, docker.io)",
|
|
58
|
+
type: "string",
|
|
59
|
+
alias: "r",
|
|
60
|
+
});
|
|
61
|
+
yargs.option("deploy-target", {
|
|
62
|
+
choices: [
|
|
63
|
+
"kubernetes",
|
|
64
|
+
"ecs",
|
|
65
|
+
"cloudrun",
|
|
66
|
+
"railway",
|
|
67
|
+
"render",
|
|
68
|
+
"fly",
|
|
69
|
+
"none",
|
|
70
|
+
],
|
|
71
|
+
describe: "Deployment target platform",
|
|
72
|
+
type: "string",
|
|
73
|
+
default: "none",
|
|
74
|
+
});
|
|
75
|
+
yargs.option("branch", {
|
|
76
|
+
describe: "Branch to trigger CI/CD on",
|
|
77
|
+
type: "string",
|
|
78
|
+
alias: "b",
|
|
79
|
+
default: "main",
|
|
80
|
+
});
|
|
81
|
+
yargs.option("node-version", {
|
|
82
|
+
describe: "Node.js version for CI",
|
|
83
|
+
type: "string",
|
|
84
|
+
default: "20",
|
|
85
|
+
});
|
|
86
|
+
yargs.option("output-dir", {
|
|
87
|
+
describe: "Output directory for generated files",
|
|
88
|
+
type: "string",
|
|
89
|
+
alias: "o",
|
|
90
|
+
});
|
|
91
|
+
return yargs;
|
|
92
|
+
},
|
|
93
|
+
handler: async (argv) => {
|
|
94
|
+
const { action, platform, strategy, includeSecurity, includeE2e, includeCoverage, dockerRegistry, deployTarget, branch, nodeVersion, outputDir, } = argv;
|
|
95
|
+
const options = {
|
|
96
|
+
platform: platform,
|
|
97
|
+
strategy: strategy,
|
|
98
|
+
includeSecurity,
|
|
99
|
+
includeE2E: includeE2e,
|
|
100
|
+
includeCoverage,
|
|
101
|
+
dockerRegistry,
|
|
102
|
+
deployTarget,
|
|
103
|
+
branch,
|
|
104
|
+
nodeVersion,
|
|
105
|
+
outputDir,
|
|
106
|
+
};
|
|
107
|
+
switch (action) {
|
|
108
|
+
case "init":
|
|
109
|
+
await (0, form_1.initCICD)(options);
|
|
110
|
+
break;
|
|
111
|
+
case "generate":
|
|
112
|
+
await (0, form_1.generateCICD)(options);
|
|
113
|
+
break;
|
|
114
|
+
case "list":
|
|
115
|
+
await (0, form_1.listPlatforms)();
|
|
116
|
+
break;
|
|
117
|
+
case "validate":
|
|
118
|
+
await (0, form_1.validatePipelines)();
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
console.log(`Unknown action: ${action}`);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
exports.cicdCommand = cicdCommand;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CIPlatform, CIStrategy } from "./cli";
|
|
2
|
+
export interface CICDOptions {
|
|
3
|
+
platform?: CIPlatform | "all";
|
|
4
|
+
strategy: CIStrategy;
|
|
5
|
+
includeSecurity: boolean;
|
|
6
|
+
includeE2E: boolean;
|
|
7
|
+
includeCoverage: boolean;
|
|
8
|
+
dockerRegistry?: string;
|
|
9
|
+
deployTarget: string;
|
|
10
|
+
branch: string;
|
|
11
|
+
nodeVersion: string;
|
|
12
|
+
outputDir?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Interactive CI/CD setup wizard
|
|
16
|
+
*/
|
|
17
|
+
export declare function initCICD(options: CICDOptions): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Generate CI/CD configuration for specific platform(s)
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateCICD(options: CICDOptions): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* List available CI/CD platforms
|
|
24
|
+
*/
|
|
25
|
+
export declare function listPlatforms(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Validate existing CI/CD configurations
|
|
28
|
+
*/
|
|
29
|
+
export declare function validatePipelines(): Promise<void>;
|
package/bin/cicd/form.js
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validatePipelines = exports.listPlatforms = exports.generateCICD = exports.initCICD = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
11
|
+
const project_analyzer_1 = require("../containerize/analyzers/project-analyzer");
|
|
12
|
+
const generators_1 = require("./generators");
|
|
13
|
+
const PLATFORMS = [
|
|
14
|
+
{
|
|
15
|
+
id: "github",
|
|
16
|
+
name: "GitHub Actions",
|
|
17
|
+
description: "CI/CD for GitHub repositories",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "gitlab",
|
|
21
|
+
name: "GitLab CI",
|
|
22
|
+
description: "CI/CD for GitLab repositories",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "circleci",
|
|
26
|
+
name: "CircleCI",
|
|
27
|
+
description: "Cloud-based CI/CD platform",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "jenkins",
|
|
31
|
+
name: "Jenkins",
|
|
32
|
+
description: "Self-hosted automation server",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "bitbucket",
|
|
36
|
+
name: "Bitbucket Pipelines",
|
|
37
|
+
description: "CI/CD for Bitbucket Cloud",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: "azure",
|
|
41
|
+
name: "Azure DevOps",
|
|
42
|
+
description: "Microsoft Azure CI/CD platform",
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
/**
|
|
46
|
+
* Interactive CI/CD setup wizard
|
|
47
|
+
*/
|
|
48
|
+
async function initCICD(options) {
|
|
49
|
+
console.log(chalk_1.default.cyan("\n🔧 ExpressoTS CI/CD Setup Wizard\n"));
|
|
50
|
+
// Analyze project first
|
|
51
|
+
const analysis = await (0, project_analyzer_1.analyzeProject)();
|
|
52
|
+
// Interactive prompts
|
|
53
|
+
const answers = await inquirer_1.default.prompt([
|
|
54
|
+
{
|
|
55
|
+
type: "checkbox",
|
|
56
|
+
name: "platforms",
|
|
57
|
+
message: "Select CI/CD platforms to configure:",
|
|
58
|
+
choices: PLATFORMS.map((p) => ({
|
|
59
|
+
name: `${p.name} - ${p.description}`,
|
|
60
|
+
value: p.id,
|
|
61
|
+
checked: p.id === "github",
|
|
62
|
+
})),
|
|
63
|
+
validate: (input) => input.length > 0 || "Select at least one platform",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: "list",
|
|
67
|
+
name: "strategy",
|
|
68
|
+
message: "Select CI/CD strategy:",
|
|
69
|
+
choices: [
|
|
70
|
+
{ name: "Basic - Lint, test, build", value: "basic" },
|
|
71
|
+
{
|
|
72
|
+
name: "Comprehensive - Full testing, security, coverage",
|
|
73
|
+
value: "comprehensive",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "Security-Focused - Maximum security scanning",
|
|
77
|
+
value: "security-focused",
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
default: "comprehensive",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: "confirm",
|
|
84
|
+
name: "includeSecurity",
|
|
85
|
+
message: "Include security scanning (Trivy, Snyk)?",
|
|
86
|
+
default: true,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
type: "confirm",
|
|
90
|
+
name: "includeE2E",
|
|
91
|
+
message: "Include end-to-end tests?",
|
|
92
|
+
default: false,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
type: "confirm",
|
|
96
|
+
name: "includeCoverage",
|
|
97
|
+
message: "Include code coverage reporting?",
|
|
98
|
+
default: true,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
type: "list",
|
|
102
|
+
name: "deployTarget",
|
|
103
|
+
message: "Select deployment target:",
|
|
104
|
+
choices: [
|
|
105
|
+
{ name: "None (build only)", value: "none" },
|
|
106
|
+
{ name: "Kubernetes", value: "kubernetes" },
|
|
107
|
+
{ name: "AWS ECS", value: "ecs" },
|
|
108
|
+
{ name: "Google Cloud Run", value: "cloudrun" },
|
|
109
|
+
{ name: "Railway", value: "railway" },
|
|
110
|
+
{ name: "Render", value: "render" },
|
|
111
|
+
{ name: "Fly.io", value: "fly" },
|
|
112
|
+
],
|
|
113
|
+
default: "none",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
type: "input",
|
|
117
|
+
name: "dockerRegistry",
|
|
118
|
+
message: "Docker registry (leave empty for default):",
|
|
119
|
+
default: "",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
type: "input",
|
|
123
|
+
name: "branch",
|
|
124
|
+
message: "Main branch name:",
|
|
125
|
+
default: "main",
|
|
126
|
+
},
|
|
127
|
+
]);
|
|
128
|
+
// Generate for each selected platform
|
|
129
|
+
const selectedOptions = {
|
|
130
|
+
...options,
|
|
131
|
+
strategy: answers.strategy,
|
|
132
|
+
includeSecurity: answers.includeSecurity,
|
|
133
|
+
includeE2E: answers.includeE2E,
|
|
134
|
+
includeCoverage: answers.includeCoverage,
|
|
135
|
+
deployTarget: answers.deployTarget,
|
|
136
|
+
dockerRegistry: answers.dockerRegistry || undefined,
|
|
137
|
+
branch: answers.branch,
|
|
138
|
+
};
|
|
139
|
+
console.log(chalk_1.default.yellow("\n📝 Generating CI/CD configurations...\n"));
|
|
140
|
+
for (const platform of answers.platforms) {
|
|
141
|
+
await generatePlatformConfig(platform, selectedOptions, analysis);
|
|
142
|
+
}
|
|
143
|
+
console.log(chalk_1.default.green("\n✅ CI/CD setup complete!\n"));
|
|
144
|
+
printNextSteps(answers.platforms, selectedOptions);
|
|
145
|
+
}
|
|
146
|
+
exports.initCICD = initCICD;
|
|
147
|
+
/**
|
|
148
|
+
* Generate CI/CD configuration for specific platform(s)
|
|
149
|
+
*/
|
|
150
|
+
async function generateCICD(options) {
|
|
151
|
+
console.log(chalk_1.default.cyan("\n🔧 ExpressoTS CI/CD Generator\n"));
|
|
152
|
+
if (!options.platform) {
|
|
153
|
+
console.log(chalk_1.default.red("Error: Please specify a platform. Use 'expressots cicd list' to see available platforms."));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const analysis = await (0, project_analyzer_1.analyzeProject)();
|
|
157
|
+
console.log(chalk_1.default.yellow("📝 Generating CI/CD configuration...\n"));
|
|
158
|
+
if (options.platform === "all") {
|
|
159
|
+
for (const platform of PLATFORMS) {
|
|
160
|
+
await generatePlatformConfig(platform.id, options, analysis);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
await generatePlatformConfig(options.platform, options, analysis);
|
|
165
|
+
}
|
|
166
|
+
console.log(chalk_1.default.green("\n✅ CI/CD configuration generated!\n"));
|
|
167
|
+
printNextSteps(options.platform === "all"
|
|
168
|
+
? PLATFORMS.map((p) => p.id)
|
|
169
|
+
: [options.platform], options);
|
|
170
|
+
}
|
|
171
|
+
exports.generateCICD = generateCICD;
|
|
172
|
+
/**
|
|
173
|
+
* List available CI/CD platforms
|
|
174
|
+
*/
|
|
175
|
+
async function listPlatforms() {
|
|
176
|
+
console.log(chalk_1.default.cyan("\n📋 Available CI/CD Platforms\n"));
|
|
177
|
+
console.log(chalk_1.default.bold("Platform".padEnd(20) + "Description".padEnd(45) + "Status"));
|
|
178
|
+
console.log("-".repeat(80));
|
|
179
|
+
for (const platform of PLATFORMS) {
|
|
180
|
+
const status = chalk_1.default.green("✓ Available");
|
|
181
|
+
console.log(chalk_1.default.white(platform.name.padEnd(20)) +
|
|
182
|
+
chalk_1.default.gray(platform.description.padEnd(45)) +
|
|
183
|
+
status);
|
|
184
|
+
}
|
|
185
|
+
console.log(chalk_1.default.gray("\nUsage: expressots cicd generate <platform>"));
|
|
186
|
+
console.log(chalk_1.default.gray(" expressots cicd generate all"));
|
|
187
|
+
console.log(chalk_1.default.gray(" expressots cicd init (interactive wizard)\n"));
|
|
188
|
+
}
|
|
189
|
+
exports.listPlatforms = listPlatforms;
|
|
190
|
+
/**
|
|
191
|
+
* Validate existing CI/CD configurations
|
|
192
|
+
*/
|
|
193
|
+
async function validatePipelines() {
|
|
194
|
+
console.log(chalk_1.default.cyan("\n🔍 Validating CI/CD Configurations\n"));
|
|
195
|
+
const cwd = process.cwd();
|
|
196
|
+
const validations = [];
|
|
197
|
+
// Check for each platform's config file
|
|
198
|
+
const platformFiles = [
|
|
199
|
+
{
|
|
200
|
+
platform: "GitHub Actions",
|
|
201
|
+
paths: [
|
|
202
|
+
".github/workflows/ci.yml",
|
|
203
|
+
".github/workflows/docker-deploy.yml",
|
|
204
|
+
],
|
|
205
|
+
},
|
|
206
|
+
{ platform: "GitLab CI", paths: [".gitlab-ci.yml"] },
|
|
207
|
+
{ platform: "CircleCI", paths: [".circleci/config.yml"] },
|
|
208
|
+
{ platform: "Jenkins", paths: ["Jenkinsfile"] },
|
|
209
|
+
{ platform: "Bitbucket", paths: ["bitbucket-pipelines.yml"] },
|
|
210
|
+
{ platform: "Azure DevOps", paths: ["azure-pipelines.yml"] },
|
|
211
|
+
];
|
|
212
|
+
for (const { platform, paths } of platformFiles) {
|
|
213
|
+
for (const filePath of paths) {
|
|
214
|
+
const fullPath = path_1.default.join(cwd, filePath);
|
|
215
|
+
const exists = fs_1.default.existsSync(fullPath);
|
|
216
|
+
if (exists) {
|
|
217
|
+
const issues = [];
|
|
218
|
+
let valid = true;
|
|
219
|
+
try {
|
|
220
|
+
const content = fs_1.default.readFileSync(fullPath, "utf-8");
|
|
221
|
+
// Basic validation checks
|
|
222
|
+
if (content.length < 50) {
|
|
223
|
+
issues.push("File seems too short");
|
|
224
|
+
valid = false;
|
|
225
|
+
}
|
|
226
|
+
// Check for common issues
|
|
227
|
+
if (filePath.endsWith(".yml") ||
|
|
228
|
+
filePath.endsWith(".yaml")) {
|
|
229
|
+
if (content.includes("\t")) {
|
|
230
|
+
issues.push("Contains tabs (YAML should use spaces)");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Check for placeholder values
|
|
234
|
+
if (content.includes("YOUR_") ||
|
|
235
|
+
content.includes("<REPLACE>")) {
|
|
236
|
+
issues.push("Contains placeholder values that need to be replaced");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
issues.push("Failed to read file");
|
|
241
|
+
valid = false;
|
|
242
|
+
}
|
|
243
|
+
validations.push({
|
|
244
|
+
platform,
|
|
245
|
+
file: filePath,
|
|
246
|
+
exists,
|
|
247
|
+
valid,
|
|
248
|
+
issues,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (validations.length === 0) {
|
|
254
|
+
console.log(chalk_1.default.yellow("No CI/CD configuration files found."));
|
|
255
|
+
console.log(chalk_1.default.gray("\nRun 'expressots cicd init' to create CI/CD configurations.\n"));
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
console.log(chalk_1.default.bold("File".padEnd(45) + "Status".padEnd(15) + "Issues"));
|
|
259
|
+
console.log("-".repeat(80));
|
|
260
|
+
for (const v of validations) {
|
|
261
|
+
const status = v.valid
|
|
262
|
+
? chalk_1.default.green("✓ Valid")
|
|
263
|
+
: chalk_1.default.yellow("⚠ Warning");
|
|
264
|
+
const issues = v.issues.length > 0 ? chalk_1.default.gray(v.issues.join(", ")) : "";
|
|
265
|
+
console.log(chalk_1.default.white(v.file.padEnd(45)) + status.padEnd(24) + issues);
|
|
266
|
+
}
|
|
267
|
+
console.log();
|
|
268
|
+
}
|
|
269
|
+
exports.validatePipelines = validatePipelines;
|
|
270
|
+
/**
|
|
271
|
+
* Generate configuration for a specific platform
|
|
272
|
+
*/
|
|
273
|
+
async function generatePlatformConfig(platform, options, analysis) {
|
|
274
|
+
const cwd = process.cwd();
|
|
275
|
+
const outputDir = options.outputDir || cwd;
|
|
276
|
+
const generatorOptions = {
|
|
277
|
+
projectName: analysis?.projectName || path_1.default.basename(cwd),
|
|
278
|
+
nodeVersion: options.nodeVersion || analysis?.nodeVersion || "20",
|
|
279
|
+
packageManager: analysis?.packageManager || "npm",
|
|
280
|
+
strategy: options.strategy,
|
|
281
|
+
includeSecurity: options.includeSecurity,
|
|
282
|
+
includeE2E: options.includeE2E,
|
|
283
|
+
includeCoverage: options.includeCoverage,
|
|
284
|
+
dockerRegistry: options.dockerRegistry,
|
|
285
|
+
deployTarget: options.deployTarget,
|
|
286
|
+
branch: options.branch,
|
|
287
|
+
port: analysis?.port || 3000,
|
|
288
|
+
};
|
|
289
|
+
switch (platform) {
|
|
290
|
+
case "github":
|
|
291
|
+
await (0, generators_1.generateGitHubActions)(outputDir, generatorOptions);
|
|
292
|
+
break;
|
|
293
|
+
case "gitlab":
|
|
294
|
+
await (0, generators_1.generateGitLabCI)(outputDir, generatorOptions);
|
|
295
|
+
break;
|
|
296
|
+
case "circleci":
|
|
297
|
+
await (0, generators_1.generateCircleCI)(outputDir, generatorOptions);
|
|
298
|
+
break;
|
|
299
|
+
case "jenkins":
|
|
300
|
+
await (0, generators_1.generateJenkinsfile)(outputDir, generatorOptions);
|
|
301
|
+
break;
|
|
302
|
+
case "bitbucket":
|
|
303
|
+
await (0, generators_1.generateBitbucketPipelines)(outputDir, generatorOptions);
|
|
304
|
+
break;
|
|
305
|
+
case "azure":
|
|
306
|
+
await (0, generators_1.generateAzureDevOps)(outputDir, generatorOptions);
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Print next steps after generation
|
|
312
|
+
*/
|
|
313
|
+
function printNextSteps(platforms, options) {
|
|
314
|
+
console.log(chalk_1.default.bold("📖 Next Steps:\n"));
|
|
315
|
+
console.log(chalk_1.default.white("1. Review generated configuration files"));
|
|
316
|
+
console.log(chalk_1.default.white("2. Configure required secrets in your CI/CD platform:\n"));
|
|
317
|
+
// Common secrets
|
|
318
|
+
const secrets = [
|
|
319
|
+
"DOCKER_USERNAME - Docker registry username",
|
|
320
|
+
"DOCKER_PASSWORD - Docker registry password/token",
|
|
321
|
+
];
|
|
322
|
+
if (options.includeSecurity) {
|
|
323
|
+
secrets.push("SNYK_TOKEN - Snyk API token (optional)");
|
|
324
|
+
}
|
|
325
|
+
if (options.includeCoverage) {
|
|
326
|
+
secrets.push("CODECOV_TOKEN - Codecov upload token (optional)");
|
|
327
|
+
}
|
|
328
|
+
if (options.deployTarget === "kubernetes") {
|
|
329
|
+
secrets.push("KUBE_CONFIG - Kubernetes configuration");
|
|
330
|
+
}
|
|
331
|
+
else if (options.deployTarget === "railway") {
|
|
332
|
+
secrets.push("RAILWAY_TOKEN - Railway API token");
|
|
333
|
+
}
|
|
334
|
+
else if (options.deployTarget === "render") {
|
|
335
|
+
secrets.push("RENDER_API_KEY - Render API key");
|
|
336
|
+
}
|
|
337
|
+
else if (options.deployTarget === "fly") {
|
|
338
|
+
secrets.push("FLY_API_TOKEN - Fly.io API token");
|
|
339
|
+
}
|
|
340
|
+
for (const secret of secrets) {
|
|
341
|
+
console.log(chalk_1.default.gray(` • ${secret}`));
|
|
342
|
+
}
|
|
343
|
+
console.log(chalk_1.default.white("\n3. Commit and push to trigger the pipeline"));
|
|
344
|
+
console.log(chalk_1.default.gray("\n💡 Tip: Run 'expressots cicd validate' to check your configurations\n"));
|
|
345
|
+
}
|