Notificando um canal no Teams a partir do Gitlab CI

ATENÇÃO: ESTE POST ESTÁ DESATUALIZADO, FAVOR CONSULTAR O REPOSITÓRIO NO GITHUB!

Notificações de falhas e erros durante a execução são essenciais para um bom monitoramento do pipeline; normalmente estas notificações são enviadas para um canal (Slack, Teams, Telegram, Discord etc), de onde podem ser vistas e tratadas.

Se você usa o GitLab CI/CD como CI/CD para sua aplicação e o Microsoft Teams como a ferramenta de comunicação, a integração não é muito difícil; só não está muito bem documentada. Vamos lá:

  1. Escolha o canal que deverá receber a notificação do Teams; caso não exista, crie-o (se tiver permissões) ou peça ao administrador local do Microsoft 365 para criar para você.
  2. No canal alvo, crie um webhook de entrada para uso do pipeline da aplicação. Copie a URL do webhook, vamos precisar dela.
  3. Crie seu card de notificação. Aconselho criar no Card Playground caso não tenha familiaridade com JSON.
    • O card será disparado quando ocorrer alguma falha em um job do CI:
    • Usaremos algumas variáveis internas do GitLab CI no card para informar o ocorrido ao operador:
      • CI_PIPELINE_ID e CI_PIPELINE_URL contém o número e a URL do pipeline
      • CI_JOB_STAGE contém o stage do job
      • CI_JOB_NAME contém o nome do job
    • Importante: as variáveis utilizadas no card deverão estar no template JSON de maneira literal, conforme veremos no próximo ponto.
  4. Vamos modificar o .gitlab-ci.yml do projeto no GitLab em dois pontos.
    • No bloco principal de variáveis, vamos criar uma variável, que chamaremos de URL_WEBHOOK_TEAMS, para a URL do webhook (lembre-se de modificar para a URL fornecida pelo Teams!):
    variables:
      (suas variáveis)
      URL_WEBHOOK_TEAMS:"https://minhaorganizacao.webhook.office.com/webhookb2/URL-completa-do-webhook-do-canal-Teams"
    
    • Como vamos notificar o canal apenas quando há algum erro no pipeline (variável interna CI_JOB_STATUS com o valor failed), usaremos after_script na seção default para, em caso de erro, disparar o envio do card para o canal:
    default:
      after_script:
        - |
          generate_post_data()
          {
          cat << EOF
          {
          "@context": "https://schema.org/extensions",
          "@type": "MessageCard",
          "themeColor": "810000",
          "title": "Pipeline $CI_PIPELINE_ID executado com ERRO!",
          "summary": "Pipeline executado com ERRO!",
          "sections": [
            {
              "activityTitle": "Erro na execução do pipeline $CI_PIPELINE_ID.\n\nJob: $CI_JOB_NAME\n\n Stage: $CI_JOB_STAGE"
            }
          ],
          "potentialAction": [
            {
              "@type": "OpenUri",
              "name": "Verificar o pipeline",
              "targets": [
                {
                  "os": "default",
                  "uri": "$CI_PIPELINE_URL"
                }
              ]
            },
            {
              "@type": "OpenUri",
              "name": "Job com erro",
              "targets": [
                {
                  "os": "default",
                  "uri": "$CI_JOB_URL"
                }
              ]
            }
          ]
          }
          EOF
          }      
        - |
          if [ "$CI_JOB_STATUS" = "failed" ]
          then
            curl -H "Content-Type:application/json" -d "$(generate_post_data)" $URL_WEBHOOK_TEAMS     
          fi      
    

Fluxo de execução

Ao rodar o script, acontece o seguinte fluxo:

  • O job é executado
  • Após a execução normal do job, o GitLab CI executa o script em after_script.
    • É criada uma função generate_post_data com o JSON do card e as variáveis a serem substituídas
    • Caso o job tenha saído com algum erro, roda um curl fazendo uma requisição HTTP POST para a URL do webhook, com os dados criados a partir de generate_post_data; o próprio Bash substitui as variáveis.

Caso o leitor prefira usar o HTTPie em vez do curl, troque a linha correspondente por echo $(generate_post_data) | http POST $URL_WEBHOOK_TEAMS.


2022-08-26