DEV Community

Cover image for Como automatizar o processo de versionamento de um projeto em Javascript
Raul Andrade
Raul Andrade

Posted on • Edited on

Como automatizar o processo de versionamento de um projeto em Javascript

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:

De/para do SemVer para Tag de versionamento

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:

Na imagem mostra uma linha do tempo de commits

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:

Na imagem mostra a linha do tempo do Changelog

É 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
Enter fullscreen mode Exit fullscreen mode
  • Realizar as configurações necessárias do semantic-release. Note que, se for um projeto novo necessita de yarn init;
yarn init
Enter fullscreen mode Exit fullscreen mode
  • Agora precisamos adicionar o pacote do semantic-release nas dev dependencies;
yarn add semantic-release -D
Enter fullscreen mode Exit fullscreen mode
  • Em seguida precisamos adicionar os plugins do semantic-release;
yarn add @commitlint/cli @commitlint/config-conventional @semantic-release/changelog @semantic-release/git -D
Enter fullscreen mode Exit fullscreen mode
  • 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;
{
  "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"
  ]
}
Enter fullscreen mode Exit fullscreen mode
  • 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;
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
Enter fullscreen mode Exit fullscreen mode
  • Adicionar o comando do semantic-release nos scripts do package.json:
    • Por último o package.json está assim;
{
  "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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
williamkoller profile image
William Koller

Parabéns pelo artigo

Collapse
 
cruz profile image
Rise

Nossa amei o artigo, estava mesmo precisando disso valeu amigo !!

Collapse
 
allbertuu profile image
Alberto Albuquerque

Woww, incrível!! Vou implementar nos meus projetos pra já