Introdução
Como desenvolvedores, amamos automatizar tarefas rotineiras. Nesta publicação demonstrarei a automação do fluxo de release utilizando a biblioteca semantic-release. Esta library permite automatizar todo o oprocesso de geração de release; Determinando o número da próxima versão, criando a nova tag, gerando as novas release notes e a publicação do pacote no NPM, caso seja necessário.
Para tudo isso funcionar, a biblioteca faz uso das mensagens de commits para determinar o número da próxima versão, o Changelog e a publicação. Por padrão o semantic-release utiliza a especificação de mensagens de commits do Angular o Conventional Commits e a convenção semver para o número de versão.
Resumindo o SemVer nos diz como devem ser os números de nossas versões, como por exemplo: MAJOR.MINOR.PATCH
. Já o Conventional Commits nos diz como devem ser nossos commits, para que o de/para do commit pro SemVer seja feito de forma automática.
Abaixo mostrarei uma imagem desse de/para:
No CI o semantic-release deve ser executado após o build ser feito com sucesso no branch de release, por exemplo.
Como funciona
O semantic-release verifica os commits de um branch entre a última tag gerada até o último commit deste branch, para então acionar a geração de uma nova tag. Em seguida ele cria ou atualiza o arquivo de Changelog com base nos commits entre as duas tags.
Ná prática fica da seguinte forma, como é mostrado na imagem a seguir:
Observe que no final imagem temos uma tag 1.17.1
e após realizarmos um commit novo no branch de release, o semantic-release é acionado e cria uma nova tag com a numeração 1.17.2
. Em seguida, realizamos dois commits um de docs e outro de fix, quando esses commits vão para o branch de release é acionado novamente e temos uma nova tag 1.17.3
. Depois disso, temos mais um commit de feat no branch de release e nossa nova tag é 1.18.0
.
E nosso arquivo de Changelog fica da seguinte maneira:
É importante notar que cada tag foi associada a uma release, a tag 1.17.1
tem uma release associada e nas notas de release temos os commits que foram feitos naquela tag.
Observe que existe um commit de docs e ele não foi adicionado nos Changelogs, porém há formas de configurar para que ele apareça.
Por último, mas não menos importante é possível executar o semantic-release sem acionar a geração de uma nova release, basta executar ele como dry-run
. Isso é uma salvação quando estamos no processo de configuração ou queremos ver o Changelog daquela versão.
Configuração
Nessa seção descreverei passo a passo de como configurar o semantic-release em um projeto. Uma observação é possível que as versões dos pacotes estejam diferentes, ou seja, mais atualizados após a publicação desse blog post.
- Criar um repositório git e adiciona-lo ao remoto no Github ou usar um repositório já existente;
git init
- Realizar as configurações necessárias do semantic-release.
Note que, se for um projeto novo necessita de
yarn init
;
yarn init
- Agora precisamos adicionar o pacote do semantic-release nas dev dependencies;
yarn add semantic-release -D
- Em seguida precisamos adicionar os plugins do semantic-release;
yarn add @commitlint/cli @commitlint/config-conventional @semantic-release/changelog @semantic-release/git -D
-
Cada plugin tem um propósito especifico:
-
@commitlint/cli
: É um analisador de mensagem de commit para verificar se a mensagem do commit está segundo o padrão; -
@commitlint/config-conventional
: É o configurador de um padrão a ser seguido nas mensagens de commit, como por exemplo o padrão do Angular; -
@semantic-release/changelog
: Plugin que atualiza ou cria o arquivo de Changelog; -
@semantic-release/git
: Plugin que realiza os commits de release e artefatos gerados;
-
-
Adicionar o pacote Husky (opcional):
- Esse passo é interessante pois com o husky evitamos de subir commits fora do padrão;
-
Criar um arquivo
.releaserc.json
exemplo disponível na doc:- O arquivo
.releaserc.json
ficou da seguinte maneira;
- O arquivo
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/github",
"@semantic-release/changelog",
[
"@semantic-release/npm",
{
"npmPublish": false
}
],
{
"path": "@semantic-release/git",
"assets": ["package.json", "package-lock.json", "CHANGELOG.md"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
],
"branches": [
"main"
]
}
- Criar uma workflow para ser executado no Github action:
- Criar um
.env
com a seguinte key GITHUB_TOKEN e o seu access token do Github; - Criar um diretório Github workflows com um arquivo dentro:
.github/workflows/release.yml
; - Temos o arquivo
.github/workflows/release.yml
dessa forma;
- Criar um
name: Release
on:
push:
branches:
- main
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 'lts/*'
- name: Install dependencies
run: yarn install
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: yarn release
- Adicionar o comando do semantic-release nos scripts do
package.json
:- Por último o
package.json
está assim;
- Por último o
{
"name": "poc-release",
"version": "0.1.0",
"main": "index.js",
"repository": {
"type": "git",
"url": "git@github.com:andraderaul/poc-release.git"
},
"author": "Raul Andrade",
"license": "MIT",
"scripts": {
"test": "jest",
"release": "semantic-release",
"release:dry": "semantic-release --dry-run",
},
"devDependencies": {
"@commitlint/cli": "^16.2.3",
"@commitlint/config-conventional": "^16.2.1",
"@semantic-release/changelog": "^6.0.1",
"@semantic-release/git": "^10.0.1",
"husky": "^7.0.4",
"jest": "^27.5.1",
"semantic-release": "^19.0.2"
}
}
Repositórios
Para ver o código de configuração na íntegra, acesse o repositório no github.
As imagens utilizadas nos exemplos são de outro repositório.
Referências
semantic-release
Semantic Versioning 2.0.0
Conventional Commits
Top comments (3)
Parabéns pelo artigo
Woww, incrível!! Vou implementar nos meus projetos pra já
Nossa amei o artigo, estava mesmo precisando disso valeu amigo !!