DEV Community

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

Posted on • Updated 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

Discussion (3)

Collapse
williamkoller profile image
Will Koller

Parabéns pelo artigo

Collapse
allbertuu profile image
Alberto Albuquerque

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

Collapse
cruz profile image
Rise

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