ProgrammingSystem

(English) A Teams notifying CI/CD

teams

Introduction

In order to inform our teams member we were currently using the native integration proposed by Gitlab
to send webhook to teams.

However I was facing the following limitation:
* Settings too restrictive, only one webhook by project
* Settings not selective enough, a lot of spam was transmitted

I thus decided to change my way of processing and directly send the webhook from
a CI/CD customized and executing only on release branches (vX-dev/vX).

The current article will describe how I send those notifications.

Summary

First step, semantic release push the new version and it's release;
Second step, the CI trigger, get the release, modify a Teams JSON Card and send the payload to the Channel URL.

Teams JSON card

For the moment I only made one basic card template like

{
    "@type": "MessageCard",
    "@context": "http://schema.org/extensions",
    "themeColor": "0076D7",
    "summary": "__summary__",
    "sections": [
        {
            "activityTitle": "__activityTitle__",
            "activitySubtitle": "__activitySubtitle__",
            "activityImage": "__activityImage__",
            "facts": [
                {
                    "name": "Published by",
                    "value": "__author__"
                }
            ],
            "text": "__text__",
            "markdown": true
        }
    ]
}

You can see all the variables you can changes as __xxxx__.
The card as been created from the Message card playground.

Gitlab CI

.notify-ci.yml

I add quite problems with this CI due to the replacements and Gitlab compatibility.
It's the main reason I use a bash template to send my commands, it avoid some problems.

.teams_release: &teams_release |
  echo "Running for $CI_COMMIT_REF_NAME with URL: $CI_API_V4_URL/projects/$CI_PROJECT_ID/releases/$CI_COMMIT_REF_NAME"
  curl -vvv --header "PRIVATE-TOKEN: $GITLAB_TOKEN" -o release.json "$CI_API_V4_URL/projects/$CI_PROJECT_ID/releases/$CI_COMMIT_REF_NAME"
  cat release.json
  export text="Release notes:   \n$(cat release.json|jq .description|tr -d \")"
  export author_name=$(cat release.json|jq ".commit|.author_name")
  export author_email=$(cat release.json|jq ".commit|.author_email")
  export avatar_url=$(curl -vvv --header "PRIVATE-TOKEN: $GITLAB_TOKEN" "$CI_API_V4_URL/avatar?email=${author_email//\"}"|jq .avatar_url)
  export author="[${author_name//\"}](mailto:${author_email//\"})"
  echo "Got author $author (author_name:$author_email) with avatar: $avatar_url"
  perl -pi -e 's/__text__/$ENV{text}/g' $CARD_JSON
  sed -i "s~__activityImage__~$avatar_url~g" $CARD_JSON
  sed -i "s~__activitySubtitle__~Release $CI_COMMIT_REF_NAME is available~g" $CARD_JSON
  sed -i "s~__activityTitle__~[$CI_PROJECT_NAME]($CI_PROJECT_URL)~g" $CARD_JSON
  sed -i "s~__author__~$author~g" $CARD_JSON
  sed -i 's~""~"~g' $CARD_JSON

.teams: &teams
  image: alpine  
  before_script:
    - apk --no-cache add curl jq perl
  script:
    - echo "Running for $CI_COMMIT_REF_NAME"
    - *teams_release
    - cat $CARD_JSON
    - 'curl -L -H "Content-Type: application/json" -d @$CARD_JSON $HOOK_URL'

## Check if version tag
.only_version_tag: &vers
  only:
   - /^v([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/
  except:
   - branches
   - triggers

## Staging
notify_monitoring:
    stage: notify
    <<: *vers
    <<: *teams
    variables:
      CARD_TYPE: "teams_release"
      HOOK_URL: "$MONITORING_HOOK"
    only:
    - /v*-dev/
    - /^v\d+\.\d+(\.\d+)?$/

The CI/CD will automatically install all the deps and work only on releases branches.

.gitlab-ci.yml

And then the Gitlab CI.

include:
  - local: '.notify-ci.yml'
  - local: '.release-ci.yml'

stages:
  - release 
  - notify

And here the final result for one commit.: