Skip to content

Commit 10948da

Browse files
ci: automatic deploy to staging and prod, e2e test and rollback
1 parent 7ba01cf commit 10948da

20 files changed

+288
-88
lines changed

.github/CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Os testes são executados com [mocha](https://www.npmjs.com/package/mocha), vali
9393
Para rodar os testes, execute:
9494

9595
1. `make test-integration` para os testes de integração.
96-
1. `make test-e2e` para os testes E2E em cima da imagem docker que irá para produção.
96+
1. `make test-e2e-localhost` para os testes E2E em cima da imagem docker que irá para produção.
9797
1. `make test-unit` para os testes unitários.
9898

9999
_Execute o comando `make test` para rodar os testes unitários e de integração._

.github/workflows/continuous_delivery.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ jobs:
8181
retention-days: 1
8282
path: coverage-integration/lcov.info
8383

84+
test-e2e:
85+
86+
runs-on: ubuntu-18.04
87+
88+
steps:
89+
- name: Project checkout
90+
uses: actions/checkout@v2
91+
- run: docker-compose build run-app-e2e
92+
- run: docker-compose build test-e2e-localhost
93+
- name: Run E2E test in locally built docker image
94+
run: make test-e2e-localhost
95+
8496
sonarcloud:
8597
needs: [test-unit, test-integration]
8698

@@ -145,7 +157,7 @@ jobs:
145157
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
146158

147159
release:
148-
needs: [lint, commit-lint, dockerfile-lint, test-mutation, test-infra-docker, test-contract, sonarcloud]
160+
needs: [lint, commit-lint, dockerfile-lint, test-infra-docker, test-contract, sonarcloud]
149161

150162
runs-on: ubuntu-18.04
151163
environment: production

.github/workflows/continuous_integration.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ jobs:
9999
- name: Project checkout
100100
uses: actions/checkout@v2
101101
- run: docker-compose build run-app-e2e
102-
- run: docker-compose build test-e2e
103-
- name: Run E2E Test
104-
run: make test-e2e
102+
- run: docker-compose build test-e2e-localhost
103+
- name: Run E2E test in locally built docker image
104+
run: make test-e2e-localhost
105105

106106
sonarcloud:
107107
needs: [test-unit, test-integration]

.github/workflows/deploy-online-serverest.yml

Lines changed: 170 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,206 @@
11
name: Deploy ServeRest on the web
22

3+
# This pipeline runs when the continuous_delivery.yml pipeline generates a new release
4+
35
on:
46
release:
57
types: [released]
6-
workflow_dispatch:
7-
inputs:
8-
publicar-no-serverest-dev:
9-
description: 'Publicar a API no ServeRest.dev?'
10-
required: true
11-
default: 'true'
12-
publicar-no-agilizei:
13-
description: 'Publicar a API no Agilizei?'
14-
required: false
15-
default: 'false'
16-
schedule:
17-
- cron: "0 6 * * *"
188

199
env:
10+
PROJECT_ID: serverest
11+
SERVICE_NAME: app
12+
REGION: us-central1
13+
SERVICE_PRODUCTION: app
14+
SERVICE_STAGING: app-staging
2015
PACT_BROKER_BASE_URL: https://paulogoncalves.pactflow.io
2116
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
2217

2318
jobs:
24-
can-i-deploy:
19+
build-and-push-image-to-gcloud-container-registry:
20+
name: Build and push image to container registry
21+
runs-on: ubuntu-18.04
22+
23+
steps:
24+
- name: Project checkout
25+
uses: actions/checkout@v2
26+
- name: Set up Cloud SDK
27+
uses: google-github-actions/setup-gcloud@v0
28+
- name: Authentication on GCloud
29+
run: |
30+
echo $GCP_IAM_SERVICE_ACCOUNT_KEY > gcloud-service-key.json
31+
gcloud auth activate-service-account --key-file gcloud-service-key.json
32+
env:
33+
GCP_IAM_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_IAM_SERVICE_ACCOUNT_KEY }}
34+
- run: gcloud config set project serverest
35+
- name: Build and deploy to Gcloud
36+
run: |
37+
gcloud builds submit . \
38+
--config=cloudbuild.yaml \
39+
--substitutions=COMMIT_SHA=${{ github.sha }}
40+
41+
deploy-staging:
42+
name: Deploy on staging environment (staging.serverest.dev)
43+
needs: build-and-push-image-to-gcloud-container-registry
2544

2645
runs-on: ubuntu-18.04
2746

2847
steps:
29-
- uses: actions/checkout@v2
30-
- run: docker pull pactfoundation/pact-cli:latest
31-
- name: Verify that it will not break a contract in production
48+
- name: Set up Cloud SDK
49+
uses: google-github-actions/setup-gcloud@v0
50+
- name: Authentication on GCloud
3251
run: |
33-
docker run --rm \
34-
-e PACT_BROKER_BASE_URL \
35-
-e PACT_BROKER_TOKEN \
36-
pactfoundation/pact-cli \
37-
broker can-i-deploy \
38-
--pacticipant 'ServeRest - API Rest' \
39-
--version ${{ github.sha }} \
40-
--to production
52+
echo $GCP_IAM_SERVICE_ACCOUNT_KEY > gcloud-service-key.json
53+
gcloud auth activate-service-account --key-file gcloud-service-key.json
54+
env:
55+
GCP_IAM_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_IAM_SERVICE_ACCOUNT_KEY }}
56+
- run: gcloud config set project serverest
57+
- name: Deploy container image to 'staging' environment
58+
run: |
59+
gcloud run \
60+
deploy $SERVICE_STAGING \
61+
--image gcr.io/$PROJECT_ID/$SERVICE_NAME:${{ github.sha }} \
62+
--region $REGION
4163
42-
deploy-on-serverest-dev:
43-
needs: can-i-deploy
44-
if: github.event.inputs.publicar-no-serverest-dev != 'false'
64+
test-e2e-staging:
65+
name: E2E test on staging environment
66+
needs: deploy-staging
4567

4668
runs-on: ubuntu-18.04
4769

4870
steps:
4971
- name: Project checkout
5072
uses: actions/checkout@v2
51-
with:
52-
fetch-depth: 2
53-
- name: Setup SSH to use on 'git push umbler'
54-
uses: shimataro/[email protected]
55-
with:
56-
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
57-
public-key: ${{ secrets.SSH_PUBLIC_KEY }}
58-
known-hosts: ${{ secrets.SSH_KNOWN_HOSTS }}
59-
- name: Deploy on serverest.dev
73+
- run: docker-compose build test-e2e-staging
74+
- name: Run E2E test in staging environment
75+
run: make test-e2e-staging
76+
77+
deploy-production:
78+
name: Deploy on prod environment (serverest.dev)
79+
needs: test-e2e-staging
80+
81+
runs-on: ubuntu-18.04
82+
83+
steps:
84+
- name: Set up Cloud SDK
85+
uses: google-github-actions/setup-gcloud@v0
86+
- name: Authentication on GCloud
6087
run: |
61-
git remote add umbler ssh://[email protected]:9922/jnydrgre/serverest-dev.git
62-
git fetch --unshallow origin
63-
git config --global user.email "[email protected]"
64-
git config --global user.name "deploy umbler"
65-
git commit --allow-empty -m "empty commity" --no-verify
66-
git push umbler ${GITHUB_REF##*/}:trunk --no-verify --force
88+
echo $GCP_IAM_SERVICE_ACCOUNT_KEY > gcloud-service-key.json
89+
gcloud auth activate-service-account --key-file gcloud-service-key.json
90+
env:
91+
GCP_IAM_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_IAM_SERVICE_ACCOUNT_KEY }}
92+
- run: gcloud config set project serverest
93+
- name: Deploy container image to 'production' environment
94+
run: |
95+
gcloud run \
96+
deploy $SERVICE_PRODUCTION \
97+
--image gcr.io/$PROJECT_ID/$SERVICE_NAME:${{ github.sha }} \
98+
--region $REGION
6799
68-
deploy-on-api-agilizei:
69-
needs: can-i-deploy
70-
if: github.event_name == 'schedule' || github.event.inputs.publicar-no-agilizei == 'true'
100+
test-e2e-smoke-production:
101+
name: Smoke test in production environment
102+
needs: deploy-production
71103

72104
runs-on: ubuntu-18.04
73105

106+
steps:
107+
- name: Project checkout
108+
uses: actions/checkout@v2
109+
- run: docker-compose build test-e2e-smoke-production
110+
- name: Run smoke test in production environment
111+
run: make test-e2e-smoke-production
112+
113+
# Rollback jobs \/
114+
115+
rollback-get-previous-info:
116+
name: Get info from previous version (not the latest version)
117+
needs: test-e2e-smoke-production
118+
if: ${{ failure() && needs.test-e2e-smoke-production.result == 'failure' }}
119+
120+
runs-on: ubuntu-18.04
121+
122+
outputs:
123+
git_hash: ${{ steps.info_about_previous_version.outputs.git_hash }}
124+
git_tag: ${{ steps.info_about_previous_version.outputs.git_tag }}
125+
74126
steps:
75127
- name: Project checkout
76128
uses: actions/checkout@v2
77129
with:
78-
fetch-depth: 2
79-
- name: Setup SSH to use on 'git push umbler'
80-
uses: shimataro/[email protected]
81-
with:
82-
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
83-
public-key: ${{ secrets.SSH_PUBLIC_KEY }}
84-
known-hosts: ${{ secrets.SSH_KNOWN_HOSTS }}
85-
- name: Deploy on Agilizei
130+
ref: trunk
131+
fetch-depth: 0
132+
- run: |
133+
echo "::set-output name=git_hash::$(git rev-parse $(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1)))"
134+
echo "::set-output name=git_tag::$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1))"
135+
id: info_about_previous_version
136+
137+
rollback-production:
138+
name: Rollback production environment (serverest.dev)
139+
needs: rollback-get-previous-info
140+
if: ${{ always() && needs.rollback-get-previous-info.result == 'success' }}
141+
142+
runs-on: ubuntu-18.04
143+
144+
steps:
145+
- name: Set up Cloud SDK
146+
uses: google-github-actions/setup-gcloud@v0
147+
- name: Authentication on GCloud
148+
run: |
149+
echo $GCP_IAM_SERVICE_ACCOUNT_KEY > gcloud-service-key.json
150+
gcloud auth activate-service-account --key-file gcloud-service-key.json
151+
env:
152+
GCP_IAM_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_IAM_SERVICE_ACCOUNT_KEY }}
153+
- run: gcloud config set project serverest
154+
- name: Deploy image from '${{ needs.rollback-get-previous-info.outputs.git_tag }}' to 'production' environment
86155
run: |
87-
git remote add umbler ssh://[email protected]:9922/jnydrgre/serverest-api-agilizei-com.git
88-
git fetch --unshallow origin
89-
git config --global user.email "[email protected]"
90-
git config --global user.name "deploy umbler"
91-
git commit --allow-empty -m "empty commity" --no-verify
92-
git push umbler ${GITHUB_REF##*/}:trunk --no-verify --force
93-
94-
contract-test-tag-pact:
95-
needs: deploy-on-serverest-dev
156+
gcloud run \
157+
deploy $SERVICE_PRODUCTION \
158+
--image gcr.io/$PROJECT_ID/$SERVICE_NAME:${{ needs.rollback-get-previous-info.outputs.git_hash }} \
159+
--region $REGION
160+
161+
contract-test-rollback:
162+
name: Contract test - Rollback 'production' tag
163+
needs: rollback-production
164+
if: ${{ always() && needs.rollback-production.result == 'success' }}
165+
166+
runs-on: ubuntu-18.04
167+
168+
# Why delete tag on rollback? Read: https://docs.pact.io/pact_broker/tags#handling-rollbacks
169+
steps:
170+
- name: Delete Production tag recently created
171+
run: |
172+
curl -X DELETE https://paulogoncalves.pactflow.io/pacticipants/$PACTICIPANT/versions/$VERSION/tags/$TAG -H "Authorization: Bearer $PACT_BROKER_TOKEN"
173+
env:
174+
PACTICIPANT: ServeRest - API Rest
175+
VERSION: ${{ github.sha }}
176+
TAG: production
177+
178+
# Rollback jobs /\
179+
180+
contract-test-tag-staging:
181+
name: Contract test - Tag with 'staging'
182+
needs: deploy-staging
183+
184+
runs-on: ubuntu-18.04
185+
186+
steps:
187+
- uses: actions/checkout@v2
188+
- run: docker pull pactfoundation/pact-cli:latest
189+
- name: Tag the pact contract with 'staging' tag
190+
run: |
191+
docker run --rm \
192+
-e PACT_BROKER_BASE_URL \
193+
-e PACT_BROKER_TOKEN \
194+
pactfoundation/pact-cli \
195+
broker create-version-tag \
196+
--pacticipant 'ServeRest - API Rest' \
197+
--version ${{ github.sha }} \
198+
--tag staging
199+
200+
contract-test-tag-production:
201+
name: Contract test - Tag with 'production'
202+
needs: deploy-production
203+
96204
runs-on: ubuntu-18.04
97205

98206
steps:

Dockerfile.dev

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ COPY package*.json ./
66

77
RUN npm ci
88

9-
COPY . .
10-
119
FROM base as test
1210

1311
ENV NODE_ENV=serverest-test
@@ -19,12 +17,16 @@ RUN apk --no-cache add git ca-certificates wget=1.21.1-r1 bash \
1917
&& apk --no-cache add glibc-2.29-r0.apk \
2018
&& rm -rf /var/cache/apk/*
2119

20+
COPY . .
21+
2222
FROM base as dev
2323

2424
ENV NODE_ENV=serverest-development
2525
ENV USERNAME='docker'
2626
ENV TERM=xterm-256color
2727

28+
COPY . .
29+
2830
EXPOSE 3000
2931

3032
CMD [ "npm", "run", "dev" ]

Dockerfile.terratest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM golang:1.17.3-alpine3.14@sha256:55da409cc0fe11df63a7d6962fbefd1321fedc305d9
22

33
# hadolint ignore=DL3018
44
RUN apk --no-cache add \
5-
build-base=0.5-r2 \
5+
build-base \
66
docker \
77
openrc \
88
bash \

Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ test-unit:
3636
test-integration:
3737
@docker-compose up --abort-on-container-exit --build test-integration
3838

39-
test-e2e:
40-
@docker-compose up --abort-on-container-exit --exit-code-from test-e2e --build test-e2e
39+
test-e2e-localhost:
40+
@docker-compose up --abort-on-container-exit --exit-code-from test-e2e-localhost --build test-e2e-localhost
4141

4242
test-mutation-diff:
4343
@docker-compose up --abort-on-container-exit --build test-mutation-diff
@@ -47,3 +47,11 @@ test-mutation:
4747

4848
test-infra:
4949
@docker-compose up --abort-on-container-exit --build test-infra
50+
51+
# COMANDOS DE TESTE PÓS DEPLOY \/
52+
53+
test-e2e-staging:
54+
@docker-compose up --abort-on-container-exit --build test-e2e-staging
55+
56+
test-e2e-smoke-production:
57+
@docker-compose up --abort-on-container-exit --build test-e2e-smoke-production

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,15 @@ Todas essas opções possuem as mesmas rotas, regras, dados pré-cadastrados e d
5252

5353
No ambiente online os dados cadastrados são removidos diariamente, enquanto que no local basta reiniciar o ServeRest.
5454

55-
Prefira a opção de ambiente local caso precise que os dados não sejam alterados por outro usuário.
55+
> Prefira a opção de ambiente local caso precise que os dados não sejam alterados por outro usuário.
5656
5757
### Online
5858

5959
Acesse **<https://serverest.dev>** para visualizar a documentação e as rotas disponíveis.
6060

6161
> Essa é a melhor opção para quem não possui NPM e Docker na máquina ou não quer preocupar em gerenciar ambiente.
6262
63-
A base de dados volta ao estado original [diariamente às 3h](https://github.com/ServeRest/ServeRest/actions?query=workflow%3A%22Clean+serverest.dev+database%22).
64-
6563
O ServeRest online possui monitoramento constante do status e tempo de atividade para garantir que esteja sempre disponível.
66-
Acesse [ServeRest Status](https://status.serverest.dev/) para ver detalhes do uptime.
6764

6865
### Localmente com NPM
6966

0 commit comments

Comments
 (0)