Skip to content

Commit 9f2b98d

Browse files
authored
ci(.github): create gh actions scope for ci (#59)
* ci(.github): create gh actions scope for ci * chore: remove circleci * fix(ci): fixed ci process with gh * fix(ci): better README with badges updated
1 parent 5f4df2c commit 9f2b98d

File tree

6 files changed

+146
-94
lines changed

6 files changed

+146
-94
lines changed

.circleci/config.yml

Lines changed: 0 additions & 49 deletions
This file was deleted.

.github/workflows/main.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
name: Node.js CI
3+
4+
on: [pull_request]
5+
6+
jobs:
7+
build:
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- uses: actions/checkout@v4
12+
- name: Use Node.js
13+
uses: actions/setup-node@v4
14+
with:
15+
node-version: "22.15.x"
16+
- run: sudo apt-get update
17+
- run: sudo apt-get install -y tzdata
18+
- run: sudo ln -fs /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
19+
- run: yarn
20+
- run: yarn test-ci
21+
- name: Coveralls
22+
uses: coverallsapp/github-action@v2
23+
with:
24+
github-token: ${{ secrets.GITHUB_TOKEN }}
25+
path-to-lcov: ./reports/coverage/lcov.info
26+
- name: Upload test results
27+
uses: actions/upload-artifact@v4
28+
with:
29+
name: test-results
30+
path: ./test-results/

.github/workflows/mutator.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
name: Mutator CI
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths-ignore:
8+
- .github/workflows/mutator.yaml
9+
- .github/workflows/main.yaml
10+
env:
11+
SERVICE_HOST: "dashboard.stryker-mutator.io"
12+
PROJECT: "nodejs-hexagonal-boilerplate"
13+
API_KEY: ${{ secrets.STRIKER_MUTATOR_TOKEN }}
14+
15+
jobs:
16+
mutator:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: Use Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: "22.15.x"
25+
- run: sudo apt-get update
26+
- run: sudo apt-get install -y tzdata
27+
- run: sudo ln -fs /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
28+
- run: yarn
29+
- run: yarn test-ci
30+
- name: Mutator run mutator
31+
run: |
32+
yarn stryker-mutate --reporters dashboard \
33+
--dashboard.version ${{env.GITHUB_REF_NAME}}

README.md

Lines changed: 79 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@
55
[![Standard - JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
66
[![Conventional Changelog](https://img.shields.io/badge/changelog-conventional-brightgreen.svg)](http://conventional-changelog.github.io)
77
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
8-
[![CircleCI](https://circleci.com/gh/claytonsilva/nodejs-hexagonal-boilerplate.svg?style=svg)](https://circleci.com/gh/claytonsilva/nodejs-hexagonal-boilerplate)
8+
[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fclaytonsilva%2Fnodejs-hexagonal-boilerplate%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/claytonsilva/nodejs-hexagonal-boilerplate/main)
9+
![gh_actions](https://github.com/claytonsilva/nodejs-hexagonal-boilerplate/actions/workflows/main.yml/badge.svg)
910

1011
## Inspiração
1112

12-
Inspirado em desenvolver essa arquitetura depois de acompanhar algumas palestras da Nubank, a ideia de separação de responsabilidades por camadas e modelos de testes me fez inspirar a criar um modelo em Node.js.
13+
Inspirado em desenvolver essa arquitetura depois de acompanhar
14+
algumas palestras da Nubank, a ideia
15+
de separação de responsabilidades
16+
por camadas e modelos de testes me fez inspirar a criar um modelo em Node.js.
1317

1418
## O que vem a ser? Aonde vive? Hoje no globo reporter
1519

16-
Antes de tudo vamos no [Wikipedia](https://en.wikipedia.org/wiki/Hexagonal_architecture_(software))
20+
Antes de tudo vamos no [Wikipedia](<https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)>)
1721
Depois vamos paginar [esse slide bacana da Nubank](https://pt.slideshare.net/Nubank/arquitetura-funcional-em-microservices).
1822

1923
## Já viu os dois? senta que lá vem história
@@ -22,24 +26,30 @@ Depois vamos paginar [esse slide bacana da Nubank](https://pt.slideshare.net/Nub
2226

2327
Vamos elencar algumas dores do desenvolvimento:
2428

25-
* Mockar serviços ou testar neles;
26-
* Criar uma condição de teste com volume aceitável de cobertura, e possibilidade do seu teste evoluir
27-
conforme vai a experiência de consumo do produto;
28-
* Projetar Tolerância a falha;
29-
* Saber onde deve entrar o BDD e onde entra o teste unitário; e
30-
* (para galera que curte o lado funcional do Javascript) criar codigo 100% puro sem ter que vender o rim.
29+
- Mockar serviços ou testar neles;
30+
- Criar uma condição de teste com volume aceitável de cobertura,
31+
e possibilidade do seu teste evoluir
32+
conforme vai a experiência de consumo do produto;
33+
- Projetar Tolerância a falha;
34+
- Saber onde deve entrar o BDD e onde entra o teste unitário; e
35+
- (para galera que curte o lado funcional do Javascript) criar
36+
codigo 100% puro sem ter que vender o rim.
3137

3238
### Dado isso vamos começar pela camada do meio, aonde ficam os negócios
3339

34-
* É a camada mais pura;
35-
* Não conversa com ninguém, somente é consumido;
36-
* Onde as funções DEVEM ser mais puras possíveis;
37-
* Não precisam de implementar injeção de dependência;
38-
* Não são assíncronas pois recebe tudo que precisa na entrada e devolve o objeto necessário; e
39-
* São fáceis de fazer teste unitário porque são puros e com entradas que se limita a Arrays e objetos.
40-
41-
Nela deve ficar toda questão de negócios que sua solução propõe, sabemos que nessa área é onde vai ocorrer
42-
mais mudanças conforme for evoluindo sua aplicação, então ela tem que ser simpática e amigável a ponto de voce nem ligar
40+
- É a camada mais pura;
41+
- Não conversa com ninguém, somente é consumido;
42+
- Onde as funções DEVEM ser mais puras possíveis;
43+
- Não precisam de implementar injeção de dependência;
44+
- Não são assíncronas pois recebe tudo que precisa na entrada
45+
e devolve o objeto necessário; e
46+
- São fáceis de fazer teste unitário porque são puros
47+
e com entradas que se limita a Arrays e objetos.
48+
49+
Nela deve ficar toda questão de negócios que sua solução propõe,
50+
sabemos que nessa área é onde vai ocorrer
51+
mais mudanças conforme for evoluindo sua aplicação, então
52+
ela tem que ser simpática e amigável a ponto de voce nem ligar
4353
que o jest rode na trigger de pos-commit.
4454

4555
Concentre nela os casos de uso, nela que será construído o seu negócio.
@@ -48,62 +58,90 @@ Concentre nela os casos de uso, nela que será construído o seu negócio.
4858

4959
É a cola que une as camadas externas com negócio (é você controller?).
5060

51-
Diferentemente do controller que foi projetado para arquitetura MVC e todo mundo já deixou alguma regra de negócio nele que eu sei e não adianta mentir, ele abstrai totalmente a ideia de ponte e pode ser aplicado em **qualquer contexto** dando uma flexibilidade grande para reaproveitamento de código.
61+
Diferentemente do controller que foi projetado
62+
para arquitetura MVC e todo mundo já deixou alguma
63+
regra de negócio nele que eu sei e não adianta mentir,
64+
ele abstrai totalmente a ideia de ponte e
65+
pode ser aplicado em **qualquer contexto** dando uma
66+
flexibilidade grande para reaproveitamento de código.
5267

5368
---
5469

5570
Importante ressaltar
5671

57-
* camada de negócios conversa com adapter;
58-
* adapter conversa com ports; e
59-
* ~~camada de negócios fala com ports~~.
72+
- camada de negócios conversa com adapter;
73+
- adapter conversa com ports; e
74+
- ~~camada de negócios fala com ports~~.
6075

6176
---
6277

63-
O controller tinha responsabilidade de fazer ponte com a camada de modelo e ainda sanitizar os dados, preocupação que veremos na frente em **ports**.
78+
O controller tinha responsabilidade de fazer ponte com a
79+
camada de modelo e ainda sanitizar os dados,
80+
preocupação que veremos na frente em **ports**.
6481

65-
Aqui já ocorre consumo de serviços que precisam ser simulados (mock, emulador de serviços), então por consequência ocorre também injeção de dependência, para que a solução permita entrar com mock com facilidade sem alterar o contexto da função. O teste unitário começa a ficar mais complicado e começa os testes de comportamento, pois no adapter você está claramente consumindo o serviço, mas consumindo de forma direta.
82+
Aqui já ocorre consumo de serviços que precisam ser
83+
simulados (mock, emulador de serviços), então por consequência ocorre
84+
também injeção de dependência, para que a solução permita
85+
entrar com mock com facilidade sem alterar o contexto da função.
86+
O teste unitário começa a ficar mais complicado e
87+
começa os testes de comportamento, pois no adapter
88+
você está claramente consumindo o serviço, mas consumindo de forma direta.
6689

6790
### Ports
6891

69-
As bordas que dão a fama de arquitetura hexagonal, pois foi feito pra abstrair como um hexágono onde cada lado significa uma porta I/O.
92+
As bordas que dão a fama de arquitetura hexagonal, pois foi feito pra abstrair
93+
como um hexágono onde cada lado significa uma porta I/O.
7094

7195
Exemplos de ports:
7296

73-
* máquinas de estado (fila, banco de dados);
74-
* handlers em lambda;
75-
* serviço http com express; e
76-
* log shipper.
97+
- máquinas de estado (fila, banco de dados);
98+
- handlers em lambda;
99+
- serviço http com express; e
100+
- log shipper.
77101

78-
Ele pode ser conectado ao ambiente real ou simulado, onde também ocorre injeção de dependência e o contexto da avaliação de comportamento foge do contexto das regras de negócio.
102+
Ele pode ser conectado ao ambiente real ou simulado, onde também ocorre injeção de
103+
dependência e o contexto da avaliação de comportamento
104+
foge do contexto das regras de negócio.
79105

80-
Começa a ficar convidativo fazer ainda o BDD, mas com as portas podemos ir além, através de simulação de serviços como [localstack](https://localstack.cloud/) podemos chegar a simular alguns volumes de carga (não generosos por ser simulado e não ter o mesmo throughput de um ambiente real), e usar [Chaos Monkey](https://en.wikipedia.org/wiki/Chaos_engineering), isso é possível porque o localstack permite que você simule taxas de erros nos serviços para testes de resiliência.
106+
Começa a ficar convidativo fazer ainda o BDD, mas com as portas podemos ir além,
107+
através de simulação de serviços como [localstack](https://localstack.cloud/)
108+
podemos chegar a simular alguns volumes de carga
109+
(não generosos por ser simulado e não ter o mesmo throughput de um ambiente real),
110+
e usar [Chaos Monkey](https://en.wikipedia.org/wiki/Chaos_engineering),
111+
isso é possível porque o localstack permite que você simule taxas de erros
112+
nos serviços para testes de resiliência.
81113

82-
Esse [projeto da Netflix](https://github.com/Netflix/chaosmonkey) pode ampliar seus serviços pra teste como banco de dados por exemplo.
114+
Esse [projeto da Netflix](https://github.com/Netflix/chaosmonkey) pode ampliar
115+
seus serviços pra teste como banco de dados por exemplo.
83116

84-
Na integração contínua o localstack é amigável para manter o mesmo ambiente em várias fases até chegar em produção passando por várias situações semelhante a serviços reais.
117+
Na integração contínua o localstack é amigável para manter
118+
o mesmo ambiente em várias fases até chegar em produção
119+
passando por várias situações semelhante a serviços reais.
85120

86121
![diagrama](./diagram.png)
87122

88123
### Como usar esse projeto
89124

90125
É bem simples de já começar rodando
91126

92-
1. Configure o `.env` baseado no `.env.example`;
93-
2. ligue o localstack com `docker-compose up -d`;
94-
3. levante o ambiente demo usando [terraform](https://www.terraform.io/) com os comandos:
127+
- Configure o `.env` baseado no `.env.example`;
128+
- ligue o localstack com `docker-compose up -d`;
129+
- levante o ambiente demo usando [terraform](https://www.terraform.io/) com os comandos:
130+
95131
```bash
96132
$terraform init
97133
$terraform plan (avalia se é isso mesmo que quer criar)
98134
$terraform apply
99135
```
100-
4. instale as dependências com `yarn install`; e
101-
5. rode o projeto com yarn start.
136+
137+
- Instale as dependências com `yarn install`; e
138+
- Rode o projeto com yarn start.
102139

103140
Irá levantar uma instância de serviço http(Express), e seja feliz no consumo
104141

105142
## Features desse boilerplate
106143

107-
1. JsDoc implementado em todos os métodos e separados em namespaces na documentação que é gerado toda vez que aplica commit;
108-
2. localstack como ambiente de simulação; e
109-
3. Javascript ECMA 2015 com linters que te ajudam a manter o código funcional e puro.
144+
- JsDoc implementado em todos os métodos e separados em namespaces
145+
na documentação que é gerado toda vez que aplica commit;
146+
- Localstack como ambiente de simulação; e
147+
- Javascript ECMA 2015 com linters que te ajudam a manter o código funcional e puro.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
"usePathForSuiteName": "true"
3232
},
3333
"engines": {
34-
"node": "^12.18.1",
35-
"yarn": "^1.20.0",
36-
"npm": "^6.0.0"
34+
"node": "^22",
35+
"yarn": "^1.22",
36+
"npm": "^10"
3737
},
3838
"lint-staged": {
3939
"src/**/*.js": [

stryker.conf.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
module.exports = {
66
mutator: 'javascript',
77
packageManager: 'npm',
8-
reporters: ['html', 'clear-text', 'progress'],
8+
reporters: ['html', 'clear-text', 'progress', 'dashboard'],
99
testRunner: 'jest',
1010
coverageAnalysis: 'off',
1111
maxConcurrentTestRunners: 2,

0 commit comments

Comments
 (0)