Sending Tekton pipeline status to Matrix chat room

RMAG news

Matrix provides an “open network for secure, decentralised communication”. With Matrix bridges, you can connect to Slack, IRC, Teams, Discord, you name it!

This blog post explains how to interconnect a Tekton pipeline with a Matrix room, for the purpose of notifying the room members of the pipeline status.

Matrix API

Matrix provides several APIs, Client-Server API is one of them.

In order to be able to send messages to a matrix room, the Tekton pipeline needs to send an access_token along with the request to the Matrix server.

Thus, a prerequisite to this task is to register a Matrix user for the bot with one of the Matrix servers.

Obtaining a Matrix access_token

Once the registration process is done, I obtained the access_token through a simple login API call:

curl -XPOST -d ‘{“type”:”m.login.password”, “user”:”sherine.khoury”, “password”:”take_a_wild_guess”}’ “https://matrix.org/_matrix/client/r0/login”
{“user_id”:”@sherine.khoury:matrix.org”,”access_token”:”syt_c2hlcmluZS5raG91cnk_NFpzzGCtxFAHEDVKhYTl_123456″,”home_server”:”matrix.org”,”device_id”:”CNYGHLSLQY”,”well_known”:{“m.homeserver”:{“base_url”:”https://matrix-client.matrix.org/”}}}

With the access_token, I created a secret, with name matrix-access-token in the namespace hosting my pipeline, of type generic with a single key, token, containing the access_token I just obtained in the step above.

Example

kind: Secret
apiVersion: v1
metadata:
name: matrix-access-token
stringData:
token: {OAuth token for the bot app}

Obtaining the Matrix Room ID

The hardest for me was to create a room with Matrix. I’m pretty new to Matrix 😛, and it seems every server has different rules when it comes to the request body of POST /_matrix/client/v3/createRoom.

Similarly, every Matrix client calls the room differently: On FluffyChat, it’s a Group, which can be created after creating a space. In Element, it’s simply called a room!! Thankfully.

When you create a room in Element, the web UI provides the room ID back to you.

But you still need to set a Local address for the room in the Room Settings in order to be able to query the roomAlias by API. 🤷

The room alias usually is #ROOM_NAME:SERVER_NAME.

So for a room with name my-team on matrix.org, you can also obtain the RoomID by sending the following request to the client-server API:

curl -v https://matrix.org/_matrix/client/v3/directory/room/%23my-room:matrix.org
{“room_id”:”!xWldUqOaDUkrHUZRIP:matrix.org”,”servers”:[“matrix.org”]}

Notice there is no need for authentication here. Notice also the %23 replacing the # character in the room alias.

Tekton Task

Largely inspired from the Slack task on TektonHub:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: send-to-matrix-room
labels:
app.kubernetes.io/version: “0.1”
annotations:
tekton.dev/pipelines.minVersion: “0.12.1”
tekton.dev/categories: Messaging
tekton.dev/tags: messaging
tekton.dev/platforms: “linux/amd64,linux/s390x,linux/ppc64le”
spec:
description: >-
These tasks post a simple message to a matrix room.

This task uses Matrix’s Client-Server REST api to send the message.

params:
– name: matrix-access-token
type: string
description: secret name containing matrix access token (key is token)
– name: room
type: string
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
– name: endpoint
type: string
description: Matrix server URL to which to send the message
– name: message
type: string
description: plain text message
steps:
– name: post
image: docker.io/curlimages/curl:7.70.0@sha256:031df77a11e5edded840bc761a845eab6e3c2edee22669fb8ad6d59484b6a1c4 #tag: 7.70.0
script: |
#!/bin/sh
/usr/bin/curl -X POST -H ‘Content-type: application/json’ –data ‘{“msgtype”:”m.text”, “body”:”$(params.message)”}’ https://$(params.endpoint)/_matrix/client/r0/rooms/$(params.room)/send/m.room.message?access_token=$TOKEN
env:
– name: TOKEN
valueFrom:
secretKeyRef:
name: $(params.matrix-access-token)
key: token

💡 It could be an idea to replace room and endpoint by the room alias.
Instead of having a single step I could have used:

Use cut -d: -f2, I could retrieve the endpoint
Curl the /_matrix/client/v3/directory/room to retrieve the RoomID
Send the message using the RoomID and Endpoint

💡 If this looks good, I could send a PR to the TektonHub.

Tekton example pipeline

Now that I’ve got a task, I can use that task in a pipeline, like so:

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: pipeline-matrix-hello
namespace: okd-team
spec:
params:
– name: matrix-room
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
type: string
– name: matrix-endpoint
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
type: string

– name: repo-name
description: The repo name
type: string
– name: bundle-version
description: The bundle version
type: string

tasks:
– name: talk-to-matrix
params:
– name: matrix-access-token
value: matrix-access-token
– name: endpoint
value: $(params.matrix-endpoint)
– name: room
value: $(params.matrix-room)
– name: message
value: Going to run operator pipeline on repo $(params.repo-name) to build $(params.bundle-version)
taskRef:
kind: Task
name: send-to-matrix-room

Finally, start the pipeline using

tkn pipeline start pipeline-matrix-hello –param repo-name=node-observability-operator –param bundle-version=v1.1.1 –param matrix-endpoint=matrix.org –param matrix-room=!yKXXPqFwfCOTipZMxp:matrix.org

The logs of the pipelinerun show:

tkn pipelinerun logs pipeline-matrix-hello-run-hscx9 -f -n okd-team
[talk-to-matrix : post] % Total % Received % Xferd Average Speed Time Time Time Current
[talk-to-matrix : post] Dload Upload Total Spent Left Speed
100 172 0 59 100 113 114 219 –:–:– –:–:– –:–:– 334
[talk-to-matrix : post] {“event_id”:”$EYhJ9A5DlMlBx8xD4ORF9q-8r1KmLTsvODvCgwu5xkU”}
Please follow and like us:
Pin Share