Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: implement devcontainers #249

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"dockerComposeFile": "../docker-compose.yml",
"service": "api",
"workspaceFolder": "/workspace",
"forwardPorts": [8080],
"postCreateCommand": "yarn install --frozen-lockfile",
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"ms-azuretools.vscode-docker",
"mutantdino.resourcemonitor",
"eamodio.gitlens",
"mongodb.mongodb-vscode"
]
}
}
}
2 changes: 0 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@
!nest-cli.json
!tsconfig.json
!tsconfig.build.json
!docker/entrypoint.local.sh
!docker/wait-for.sh
3 changes: 1 addition & 2 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ jobs:
run: yarn install --frozen-lockfile
- name: Tests
run: |
yarn queue:init
yarn test:ci --shard=${{ matrix.shard }}/${{ strategy.job-total }}
env:
DB_HOST: database
Expand All @@ -104,7 +105,5 @@ jobs:
- name: Build and push docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile
push: false
tags: nestjs:latest
16 changes: 4 additions & 12 deletions .github/workflows/pull_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ jobs:
container: node:lts
timeout-minutes: 10
services:
database:
db:
image: mongo:6.0.15-jammy
env:
MONGO_INITDB_ROOT_USERNAME: acid
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: develop
options: >-
--health-cmd "echo 'dgit stb.runCommand("ping").ok' | mongosh --quiet"
--health-interval 10s
Expand Down Expand Up @@ -85,17 +84,12 @@ jobs:
run: yarn install --frozen-lockfile
- name: Tests
run: |
yarn queue:init
yarn test:ci --shard=${{ matrix.shard }}/${{ strategy.job-total }}
env:
DB_HOST: database
DB_USERNAME: acid
DB_PASSWORD: password
DB_DATABASE: develop
QUEUE_HOST: queue
QUEUE_USERNAME: acid
QUEUE_PASSWORD: password
DB_HOST: db
AWS_ENDPOINT: http://aws:4566
AWS_SQS_URL: http://sqs.eu-west-1.aws.localstack.cloud:4566/000000000000/localstack-queue
AWS_SQS_URL: http://sqs.eu-west-1.aws:4566/000000000000/localstack-queue

docker-build:
needs: skip-draft
Expand All @@ -112,7 +106,5 @@ jobs:
- name: Build and push docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile
push: false
tags: nestjs:latest
24 changes: 0 additions & 24 deletions .gitlab-ci.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.14.0
20.15.1
2 changes: 0 additions & 2 deletions .prettierignore

This file was deleted.

32 changes: 16 additions & 16 deletions .swcrc
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"jsc":{
"parser":{
"syntax":"typescript",
"tsx":false,
"decorators":true
},
"transform":{
"legacyDecorator":true,
"decoratorMetadata":true
},
"target":"es2018"
},
"module":{
"type":"commonjs",
"noInterop":true
}
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"target": "es2018"
},
"module": {
"type": "commonjs",
"noInterop": true
}
}
File renamed without changes.
72 changes: 41 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ by event organizers and approved or rejected.

## 💻 I'm a dev, how do I get started?

### Run using [dev containers](https://containers.dev/)

```
git clone [email protected]:acidtango/boilerplate-nestjs.git
```

Open the devcontainer using your favourite IDE and you are ready to go!!

### Run in local environment

Prerequisites:

- [Node.js](https://nodejs.org/es/download)
Expand All @@ -19,19 +29,17 @@ Prerequisites:
Now:

```bash
git clone [email protected]:DanielRamosAcosta/codetalk.git
git clone [email protected]:acidtango/boilerplate-nestjs.git
cd codetalk
yarn install
docker-compose up -d database # starts DDBB
yarn start:dev # opens the server in development mode
docker compose up -d db aws # starts DDBB & queue
```

You are now good ready to go!! 👯

### `yarn` scripts

- `build`: Compiles the project for later using `yarn start`
- `initialize:db`: Initializes a local database
- `start`: Opens the server by compiling the sources on the fly
- `start:dev`: Opens the server compiling the project on the fly in watch mode
- `start:prod`: Opens the server in production mode using the compiled sources
Expand All @@ -49,28 +57,28 @@ You are now good ready to go!! 👯

### Docker

We use Docker as a utility tool, mainly for running MongoDB. In the `docker-compose.yml` you have two wservuces services:
We use Docker as a utility tool, mainly for running MongoDB and LocalStack. In the `docker-compose.yml` you have two services:

- `codetalk`: The API if you want to open it as a docker container
- `database`: A mongodb database that we use for starting the API in development mode and running the integration tests locally.
- `api`: The API if you want to open it as a docker container
- `db`: A mongodb database that we use for starting the API in development mode and running the integration tests locally.
- `aws`: This is LocalStack, which is an environment simulation of AWS. We use it for the SQS service.

### Project management

- [Trello board](https://example.org/)
- [Github repo](https://github.com/DanielRamosAcosta/codetalk)
- [Github Actions](https://github.com/DanielRamosAcosta/codetalk/actions)
- [Github repo](https://github.com/acidtango/boilerplate-nestjs)
- [Github Actions](https://github.com/acidtango/boilerplate-nestjs/actions)
- [Figma](https://example.org/)
- [Firebase console](https://example.org/)

## 🛠 Which technologies are you using?

- Node
- [Node](https://nodejs.org/en)
- [Nestjs](https://nestjs.com/)
- Validations with [Class Validator & Class Transformer](https://docs.nestjs.com/techniques/validation)
- [OpenAPI docs](https://docs.nestjs.com/openapi/introduction)
- Mainly used as dependency injection container
- TypeScript
- [Stripe](https://stripe.com/es)
- Validations with [Class Validator & Class Transformer](https://docs.nestjs.com/techniques/validation)
- [OpenAPI docs](https://docs.nestjs.com/openapi/introduction)
- Mainly used as dependency injection container
- [TypeScript](https://github.com/AgileCraftsmanshipCanarias/kata-setup-typescript)

## 🏘 How is the code organized?

Expand Down Expand Up @@ -126,8 +134,8 @@ You can read more about dependency inversion [here](https://en.wikipedia.org/wik
- Do not import third-parties or side effect methods into the domain/use cases layer
- Instead, create an interface that represent that interaction
- Create two implementations of that interface:
- A "real" implementation (calling TypeORM, Stripe, Fetch HTTP API Call...).
- A "fake" implementation just for testing purposes.
- A "real" implementation (calling TypeORM, Stripe, Fetch HTTP API Call...).
- A "fake" implementation just for testing purposes.

### Dependency injection container

Expand All @@ -140,16 +148,16 @@ The interfaces are a compile-time thing of Typescript, so when we need to inject
```typescript
// TalkRepository.interface.ts
export interface TalkRepository {
save(talk: Talk): Promise<void>
findBy(talkId: TalkId): Promise<Talk | undefined>
save(talk: Talk): Promise<void>
findBy(talkId: TalkId): Promise<Talk | undefined>
}
```

```typescript
// Token.ts
export enum Token {
TALK_REPOSITORY = 'TALK_REPOSITORY',
// ...
TALK_REPOSITORY = 'TALK_REPOSITORY',
// ...
}
```

Expand All @@ -168,8 +176,8 @@ Later on, we need to wire up these dependencies from a Nestjs module:

@Global()
@Module({
providers: [{ provide: Token.TALK_REPOSITORY, useClass: TalkRepositoryMongo }],
exports: [Token.TALK_REPOSITORY],
providers: [{ provide: Token.TALK_REPOSITORY, useClass: TalkRepositoryMongo }],
exports: [Token.TALK_REPOSITORY],
})
export class TalkRepositoryModule {}
```
Expand All @@ -185,24 +193,26 @@ In general, this inheritance does not have any logic. It's just like a explanato
Examples:

```typescript
class ReservationLister extends UseCase { /* ... */}
class Reservation extends AggregateRoot { /* ... */ }
class ReservationTitle extends ValueObject<string> { /* ... */ }
class ReservationLister extends UseCase {
/* ... */
}
class Reservation extends AggregateRoot {
/* ... */
}
class ReservationTitle extends ValueObject<string> {
/* ... */
}
```

## ✅ Tests

- We are using [Jest](https://jestjs.io/) and [tepper](https://github.com/DanielRamosAcosta/tepper) for acceptance tests.
- Unitary Tests are paired with the element that tests. For example `Talk.spec.ts` is next to `Talk.ts`.
- Acceptance tests lives under the `tests` directory. These tests crosses the framework layers and we interact with the API as a black box. These are the main tests that we use for TDD by performing outside-in.
- E2E tests lives under the `tests` directory. These tests crosses the framework layers and we interact with the API as a black box. These are the main tests that we use for TDD by performing outside-in. We write them in an acceptance test fashion.

### CI/CD

- The CI and CD are in Github Actions
- We run the precommit script before each commit using Husky.
- The CI runs for both acceptance/unitary and integration tests with a real database.
- After all tests passed, then the API is re-deployed

## 📲 Contact

The project was mainly developed by [Alberto González](https://github.com/AlberTJ97) and [Daniel Ramos](https://github.com/DanielRamosAcosta) from [Acid Tango](https://acidtango.com/) with ❤️ and 💪
41 changes: 16 additions & 25 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,43 +1,34 @@
version: "3.7"
version: '3.7'
services:
db:
image: mongo:6.0.15-jammy
environment:
MONGO_INITDB_ROOT_USERNAME: acid
MONGO_INITDB_ROOT_PASSWORD: password
ports:
- "27017:27017"
- 27017:27017
volumes:
- db-data:/data/db

aws:
image: localstack/localstack
environment:
SERVICES: sqs
AWS_DEFAULT_REGION: eu-west-1
ports:
- '4566:4566'
- 4566:4566
volumes:
- ./init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh

api:
build:
context: .
dockerfile: ./docker/Dockerfile.dev
image: mcr.microsoft.com/devcontainers/typescript-node:20
command: sleep infinity
environment:
DB_HOST: db
DB_PORT: 5432
DB_USERNAME: acid
DB_PASSWORD: password
DB_DATABASE: develop
DEPLOY_ENV: dev
AWS_ENDPOINT: aws

working_dir: /home/node/
AWS_ENDPOINT: http://aws:4566
AWS_SQS_URL: http://sqs.eu-west-1.aws:4566/000000000000/localstack-queue
volumes:
- "./src:/home/node/src"
- "./test:/home/node/test"
entrypoint:
- /bin/sh
- -c
- |
./entrypoint.sh
ports:
- "8080:8080"
networks:
- default
- .:/workspace:cached

volumes:
db-data:
18 changes: 0 additions & 18 deletions docker/Dockerfile.dev

This file was deleted.

Loading