Skip to content

Commit

Permalink
docs(site): added documentations
Browse files Browse the repository at this point in the history
  • Loading branch information
KernelPanic92 committed Dec 12, 2024
1 parent 76c4bcf commit 7f04b31
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 157 deletions.
1 change: 1 addition & 0 deletions doc/pages/_meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"index": "Introduction",
"manifesto": "Manifesto",
"standards": "Standards",
"installation": "Installation",
"get-started": "Get Started",
"commands": "Commands",
Expand Down
157 changes: 0 additions & 157 deletions doc/pages/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,160 +44,3 @@ Application examples: frontend in Angular or NextJS backend with NestJS or Aws f
- **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

![Big Picture Scheme](/pages/index/big-picture.png)

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](https://www.npmjs.com/package/cypress), instead of creating new scripts in the package, we developed
[@devmy/cypress-runner](https://www.npmjs.com/package/@devmy/cypress-runner) 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](https://www.dotenv.org/docs/security/env-vault) 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](https://www.gitlab.com) environment variables or other pipeline systems.

Regarding configurations, instead of replicating information in [Gitlab CI/CD Variables](https://docs.gitlab.com/ee/ci/variables), we created
[@devmy/dotenv2shell](https://www.npmjs.com/package/@devmy/dotenv2shell) to load [Dotenv Vault](https://www.dotenv.org/docs/security/env-vault) 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](https://www.dotenv.org/docs/security/env-vault) 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](https://vitejs.dev/guide/env-and-mode#env-files), [Webpack with @dotenv-run/webpack](https://www.npmjs.com/package/@dotenv-run/webpack),
[Jest with @dotenv-run/jest](https://www.npmjs.com/package/@dotenv-run/jest), [Angular with @ngx-env/builder](https://www.npmjs.com/package/@ngx-env/builder) and
[dotenv-run](https://dotenv.run).

#### 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](https://github.com/semantic-release/semantic-release) and the deployment of individual
packages. Here’s how it works in detail:

1. **Main Branch (`main`)**: The `main` branch represents the stable and releasable version of the project.
Everything in `main` should be fully tested and production-ready. This branch also handles automatic version generation
via [semantic release](https://github.com/semantic-release/semantic-release).

2. **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`).

```bash
git checkout -b feat/DE-1234-new-feature
```

3. **Working on the Feature Branch**: Make your commits with [semver](https://semver.org) on this branch as you develop
the new feature. This allows you to work in isolation without affecting the `main` branch.

```bash
git add .
git commit -m "feat: add new feature"
```

4. **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.

5. **Review and Approval**: Other developers review the Pull Request, provide feedback, and if everything is correct,
approve the PR.

6. **Merging the Pull Request**: Once approved, the Pull Request is merged into the `main` branch.

7. **Deployment**: After merging, the `main` branch contains the new feature and is ready for production.
The pipeline handles version generation through [semantic release](https://github.com/semantic-release/semantic-release)
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 |


28 changes: 28 additions & 0 deletions doc/pages/standards.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Standards

In this section, all the standards and conventions adopted to standardize the applications developed in Devmy are summarized.
Implementing uniform standards is crucial for ensuring consistency, maintainability, and code quality across all projects.
These principles not only facilitate collaboration among team members but also ensure that applications are easily understandable and scalable over time.
Following these guidelines helps reduce the risk of errors and improve development efficiency, allowing teams to focus
on innovation and problem-solving rather than managing discrepancies in the code.

## Big Picture

![Big Picture Scheme](/pages/index/big-picture.png)

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](https://www.npmjs.com/package/cypress), instead of creating new scripts in the package, we developed
[@devmy/cypress-runner](https://www.npmjs.com/package/@devmy/cypress-runner) 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](https://www.dotenv.org/docs/security/env-vault) 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](https://www.gitlab.com) environment variables or other pipeline systems.

Regarding configurations, instead of replicating information in [Gitlab CI/CD Variables](https://docs.gitlab.com/ee/ci/variables), we created
[@devmy/dotenv2shell](https://www.npmjs.com/package/@devmy/dotenv2shell) to load [Dotenv Vault](https://www.dotenv.org/docs/security/env-vault) environments into the execution
shell of GitLab pipelines. This approach enhances the developer experience and promotes centralization of configurations.
10 changes: 10 additions & 0 deletions doc/pages/standards/application-port.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
### Application Port

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.
13 changes: 13 additions & 0 deletions doc/pages/standards/configuration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Configuration

We use [Dotenv Vault](https://www.dotenv.org/docs/security/env-vault) 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](https://vitejs.dev/guide/env-and-mode#env-files), [Webpack with @dotenv-run/webpack](https://www.npmjs.com/package/@dotenv-run/webpack),
[Jest with @dotenv-run/jest](https://www.npmjs.com/package/@dotenv-run/jest), [Angular with @ngx-env/builder](https://www.npmjs.com/package/@ngx-env/builder) and
[dotenv-run](https://dotenv.run).

## 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.

8 changes: 8 additions & 0 deletions doc/pages/standards/monorepo.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 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 cache to optimize builds, reducing compilation times.
23 changes: 23 additions & 0 deletions doc/pages/standards/package-commands.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# 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.
27 changes: 27 additions & 0 deletions doc/pages/standards/package-manager.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Package Manager - Corepack + PNPM

Choosing the right package manager is crucial for ensuring efficient dependency management in our project, facilitating the work of developers, and optimizing the overall performance of the application. After careful consideration, we have decided to adopt **Corepack** alongside **PNPM** for the following reasons:

- **Automated Version Management**:
- **Corepack** simplifies the management of package manager versions, ensuring that developers always use the correct versions of PNPM (or other supported managers) without having to manually configure each environment.
- This automation helps avoid version conflicts and improves the reliability of builds.

- **Optimized Performance**:
- **PNPM** is designed to be highly performant, reducing installation times for dependencies through the use of an advanced caching system.
- Compared to other package managers, PNPM employs a global store approach for dependencies, allowing packages to be shared across projects, minimizing the time and space required for installations.

- **Efficient Disk Space Usage**:
- PNPM's strategy of linking dependencies rather than duplicating them significantly reduces disk space usage, making the installation process leaner and less burdensome on the system.

- **Stringent Package Policy**:
- PNPM enforces a strict policy regarding which packages the application can access, enhancing security and ensuring that only declared dependencies are included in the project.
- This approach minimizes the risk of vulnerabilities and conflicts, improving the overall stability of the application.

In summary, the combination of **Corepack** and **PNPM** allows us to optimize dependency management, improve performance, and ensure greater security in our development environment. These choices reflect our commitment to maintaining an effective and modern workflow in line with industry best practices.

## Goodbye NVM
With the adoption of `Corepack` and `PNPM`, there is no longer a need to use `NVM` to manage Node versions, further simplifying the setup process and improving workflow efficiency.

## Sources
- [Corepack](https://nodejs.org/api/corepack.html)
- [PNPM](https://pnpm.io/)
Loading

0 comments on commit 7f04b31

Please sign in to comment.