Como criar um projeto com Nestjs do zero com deploy no Heroku usando Github Actions
Published: 2022-06-04 16:29:42

Ola devs e devas!

Porque iremos usar Nestjs?!
Nestjs é um framework Nodejs que conseguimos escalar muito rapidamente usando POO e é meu framework favorito.

Em primeiro lugar precisa ter instalados `node` e o cli do nestjs, para instalarmos o cli rodamos esse comando `npm i -g @nesjs/cli`

Agora iremos criar o projeto com cli do nest: `nest new api-example-dev.to-ci-cd`

O cli do nest é muito poderoso e cria toda uma estrutura inicial para nós.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ao6ubi8o187ik395yv4z.png)

Para acessar digitaremos: `cd api-example-dev.to-ci-cd && code .`

Essa é a estrutura de pasta que temos:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tv0c4nz4c0ikir0d4ek7.png)

Agora iremos rodar o projeto com o comando: `yarn start:dev`

Aplicação de pé:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5bgmeg9ws6no0zb6zkvh.png)

Agora iremos criar o projeto no heroku:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k032m2erf6f8jo0uzsuo.png)

Antes disso, precisamos instalar o cli do heroku e fazer o login:

```
sudo snap install heroku --classic
heroku login
```

Iremos adicionar o remote do heroku no nosso projeto: `heroku git:remote -a api-example-dev-to-ci-cd`


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iftrezfvjhiogn7bs9ra.png)

Agora criaremos o arquivo Procfile que sera lido pelo heroku na hora que fizermos o push:

Procfile:

```
web: npm run start:prod
```
Agora iremos preparar para fazer o push:

```
git add .
git commit -m "chore: add setup"
git push heroku main
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n6lajgzcmhjw6e5i0so0.png)

Iremos criar o nosso projeto no Github:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvdsan5n5cjzyop4zxsa.png)

Precisamos adicionar a porta do projeto no heroku:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vf0240mwht9zv9z5g0hd.png)

Iremos acessar a nossa aplicação:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3zds0y21ckq9syzd8sjj.png)

Tudo ok com nossa aplicação, agora iremos implementar nosso CI/CD para automatizar nossos deploy.

Criaremos o arquivo `ci-cd.yml`:

```
name: 'CI/CD'

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  continuous-integration:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]

    steps:
      - uses: actions/checkout@v2

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}

      - name: Install dependencies
        run: yarn install

  continuos-delivery:
    runs-on: ubuntu-latest

    needs: [continuous-integration]

    steps:
      - uses: actions/checkout@v2

      - name: Deploy to heroku
        if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main'}}
        uses: akhileshns/heroku-deploy@v3.12.12
        with:
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
          heroku_app_name: ${{ secrets.HEROKU_APP_NAME }}
          heroku_email: ${{ secrets.HEROKU_EMAIL }}
```

Agora iremos adicionar as secrets no Github:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kgohev2qkw83h69bhle7.png)
Iremos preparar para fazer o push, mas agora no github:

```
git add .
git commit -m "chore: add ci/cd workflow"
git push origin main
```

Rodando o Actions:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccbwlgppfwdv8q2l3xa6.png)


Agora iremos mudar o retorno para vermos o CI/CD funcionando:

```
export class AppService {
  getHello(): { message: string } {
    return {
      message: `welcome to the @dev.to example api with CI/CD Heroku`,
    };
  }
}
```

Precisamos alterar o retorno na nossa controller também:

```
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): { message: string } {
    return this.appService.getHello();
  }
}

```

Preparando o push:

```
git add .
git commit -m "feat: add new return"
git push origen main
```

Rodando a Action com a nova alteração:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cpw3mnj62oucnoxutqq0.png)


Iremos acessar a aplicação novamente:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/id39ar487sn4ynum7caj.png)

Pronto, implementamos CI/CD no Github Actions com deploy no Heroku