Devmy CLI
Welcome to the Devmy CLI documentation!
What is Devmy CLI?
Devmy CLI is a CLI (opens in a new tab) which allows you to create monorepo and applications within it in a fast and structured way, configuring cache management, environment variables and application optimizations, allowing the developer to have a project ready to start working on.
Why Devmy CLI?
The Devmy CLI was created with the aim of simplifying and optimizing the process of creating and managing NX monorepo, providing a set of tools and standards that facilitate the work of developers.
-
Creation of Optimized Monorepos: The Devmy CLI is designed to create highly optimized NX monorepos. NX is a powerful platform for managing monorepos, but configuring it optimally can be complex. Devmy CLI automates this process, ensuring that the monorepo created is configured according to best practices and takes full advantage of the potential of NX. This allows you to get an environment of more coherent and high-performance development right from the start.
-
Reduction of Common Work: One of the main goals of the Devmy CLI is to reduce the joint work needed to start a new project. Often, the Creating a new project requires a series of repetitive steps and configurations that can be automated. The Devmy CLI eliminates much of this manual work, allowing developers to focus on more important and specific aspects of their project. By automating tasks such as initial configuration, dependency installation, and build basic structures, the Devmy CLI makes the setup process much faster and more efficient.
-
Application of Common Standards: Another crucial reason why the Devmy CLI was created is to apply common standards across different technologies. In complex development environments, it is critical to maintain consistency across various projects and components. The Devmy CLI enforces coding, configuration, and structure standards that ensure that all projects within the monorepo follow the same guidelines. This not only improves code quality, but also facilitates maintenance and collaboration between different development teams
Glossary
This glossary provides clear and concise definitions of key terms used in the Devmy CLI documentation.
- Add-on: It is a set of operations and code blocks that are inserted into an already generated application and/or library.
- Application: Executable within the monorepo which can use 0-n libraries and communicate with 0-n other applications. Application examples: frontend in Angular or NextJS backend with NestJS or Aws functions, Firebase, etc.
- Brick: Script-generated application, library or extension. The scaffold itself is a brick imported into the cli.
- CLI: The command line application that takes the bricks and generates the code for us.
- Library: Utilities that can be used by applications in the monorepo. the DTO library shared between frontend and backend plugin engine.
- Project: The monorepo and all the applications and libraries it contains
- Scaffold: The bare monorepo structure without projects and libraries.
Big Picture
The main idea is to create a cohesive and easy-to-use structure for developers, favoring centralization rather than scattering resources.
The standardized commands in the package
(dev
, build
, start
, test
, e2e
, lint
, release
) are not just predefined scripts; they represent the only scripts necessary
for any application. We should add new scripts only in cases of extreme necessity.
If something requires more complex management, it needs to be analyzed and integrated into an npm (or pub) script.
For example, for integrating Cypress (opens in a new tab), instead of creating new scripts in the package, we developed @devmy/cypress-runner (opens in a new tab) so that it can be used by everyone without adding complexity to the package commands, thus maintaining a high developer experience. The same principle applies to the dotenv Vault (opens in a new tab) file in the project root with prefix filtering: it is designed to be shared with all applications, centralizing configurations in a single point without duplicating them in Gitlab (opens in a new tab) environment variables or other pipeline systems.
Regarding configurations, instead of replicating information in Gitlab CI/CD Variables (opens in a new tab), we created @devmy/dotenv2shell (opens in a new tab) to load Dotenv Vault (opens in a new tab) environments into the execution shell of GitLab pipelines. This approach enhances the developer experience and promotes centralization of configurations.
Package Management with PNPM and Corepack
For dependency management, devmy cli
uses PNPM and Corepack, providing several advantages over NVM:
- Automated Version Management: Corepack automatically manages package manager versions, eliminating the need for manual configurations.
- Optimized Performance: PNPM offers faster installations and more efficient disk space usage, reducing package duplication.
- Standardized Commands: Simplifies project management with standardized commands.
Goodbye NVM
With the adoption of Corepack and PNPM, there is no longer a need to use NVM to manage Node.js versions, further simplifying the setup process and improving workflow efficiency.
Monorepo NX
Each Devmy project is configured as an NX monorepo, allowing centralized management of all related applications and leveraging NX's caching mechanisms for builds.
Benefits of the NX Monorepo
- Centralized Management: Manage all applications in a single repository.
- Build Cache: Uses NX's cache to optimize builds, reducing compilation times.
Standardized Package Commands
The package manager is standardized with the following commands:
dev
: Launches the monorepo (or single application) in development mode, activating hot-reload. NX builds the libraries that the single project depends on.build
: Executes the production build of the entire monorepo (or single application). NX builds the libraries that the single project depends on.start
: Starts the applications compiled with the production build (or single application). NX runs the build for the single project and all its dependencies.lint
: Performs lint operations on the project or the monorepo.lint:fix
: Performs lint fixes on the project.test
: Runs tests on the project or the monorepo.test:headless
: Runs tests in headless mode, useful for pipelines.e2e
: Runs end-to-end tests.e2e:headless
: Runs end-to-end tests in headless mode, useful for pipelines.
Design Pattern Composite
By adopting the same interface for the package in sub-projects through NX, we implement the Composite Design Pattern. This pattern allows us to treat individual objects and compositions of objects uniformly through a common interface.
Benefits of the Composite Design Pattern
- Uniform Access: Simplifies the development and maintenance process by reducing dependency on specific implementation details.
- Modularity and Reusability: Promotes modularity and code reusability by allowing individual objects and compositions to be treated the same way.
- Agnostic Pipelines: Allows pipelines to be written in a way that is completely agnostic of the project they are working on.
Standardized ports
Regarding the ports for launching various applications, we have standardized them to centralize and unify the setup. This approach eliminates the frustration of remembering the specific port for the frontend application built with a particular framework in a given project. The standardized ports are:
target | port | localhost |
---|---|---|
Frontend | 4000 | localhost:4000 |
Backend | 3000 | localhost:3000 |
This standardization ensures a cohesive development environment and simplifies the process for developers.
Configuration
We use Dotenv Vault (opens in a new tab) created at the root of the monorepo. Each application within the monorepo has access only to the parameters relevant to it, utilizing prefix filtering tools such as Vite env-and-mode (opens in a new tab), Webpack with @dotenv-run/webpack (opens in a new tab), Jest with @dotenv-run/jest (opens in a new tab), Angular with @ngx-env/builder (opens in a new tab) and dotenv-run (opens in a new tab).
Benefits of Centralized Configuration
- Single Management Point: Centralized management of all configurations for all applications.
- Enhanced Security: Reduces the risk of sharing sensitive information between different applications due to prefix filtering.
Workflow and Pipelines
GitHub Flow is a simple and flexible Git workflow ideal for software projects that require frequent releases.
To standardize our pipelines and speedup our daily workflow, we have adopted GitHub Flow, managing the execution of
validation pipelines in both the main
branch and the development branches.
In the main
branch, we also handle version generation through semantic release (opens in a new tab) and the deployment of individual
packages. Here’s how it works in detail:
-
Main Branch (
main
): Themain
branch represents the stable and releasable version of the project. Everything inmain
should be fully tested and production-ready. This branch also handles automatic version generation via semantic release (opens in a new tab). -
Creating a Feature Branch: When starting work on a new feature, create a separate branch from
main
. Give the branch a descriptive name that reflects the feature or change you’re working on and the ClickUP code (e.g.,feat/DE-1234-new-feature
).
git checkout -b feat/DE-1234-new-feature
- Working on the Feature Branch: Make your commits with semver (opens in a new tab) on this branch as you develop
the new feature. This allows you to work in isolation without affecting the
main
branch.
git add .
git commit -m "feat: add new feature"
-
Pull Request (PR): When the feature is complete, open a Pull Request on GitHub or Gitlab to merge the feature branch into the
main
branch. This process allows for code review, discussion of changes, and ensuring everything is in order before integration. -
Review and Approval: Other developers review the Pull Request, provide feedback, and if everything is correct, approve the PR.
-
Merging the Pull Request: Once approved, the Pull Request is merged into the
main
branch. -
Deployment: After merging, the
main
branch contains the new feature and is ready for production. The pipeline handles version generation through semantic release (opens in a new tab) and the deployment of packages. The deployment of individual packages is divided as follows:
- Deploy to Dev: Automatic deployment on the
main
branch. - Deploy to Staging: Manual deployment on the
main
branch. - Deploy to Production: Manual deployment on the
main
branch.
GitHub Flow encourages an iterative and collaborative development cycle, keeping the production code always in a releasable state and integrating an efficient and well-organized deployment system.
Benefits of GitHub Flow
- Automatic Deployments: Automates deployments to staging, improving development cycle efficiency.
- Manual Control: Allows manually triggered jobs for production deployment, ensuring greater control.
Pipeline uses
job | stage | branch |
---|---|---|
install | pre | all |
build | build | all |
lint | test | all |
test | test | all |
e2e | test | main, manually in other branches |
release | release | main |
deploy dev | deploy | main |
deploy staging | deploy | manually in main |
deploy production | deploy | manually in main |