After gitlab runner runs related tests or packages, we always want it to actively inform us of the results in real time. At this time, we need a DingTalk robot. I reported the idea of trying it out and searched on docker hub. Although I found several keywords with the same keywords, it is a pity that these authors are lazy and do not have any instructions for use. Just get one yourself.
foreword
If you don't want to know how I completed the build process from 0 to 1, but just need a DingTalk message that can be sent under itlab runner, please move to the docker official repository to quickly meet the current needs.
Choose a language
The DingTalk open document gives two examples of code push, namely JAVA and PHP. Since PHP is an unnecessary scripting language, we use PHP here.
<?php
function request_by_curl($remote_server, $post_string) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $remote_server);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
// curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$webhook = "https://oapi.dingtalk.com/robot/send?access_token=xxxxxx";
$message="我就是我, 是不一样的烟火";
$data = array ('msgtype' => 'text','text' => array ('content' => $message));
$data_string = json_encode($data);
$result = request_by_curl($webhook, $data_string);
echo $result;
?>
Although the most primitive curl command can also be used in bash to achieve this effect, but in terms of development efficiency, this is not the best choice.
image
After the language is determined to use php, I choose the more commonly used php:5.6 version, and we only need to use the scripting function of php here, so we can use the php:5.6-cli version. But after starting the docker service locally, execute: docker run php:5.6-cli /bin/bash
, wait for a while, a php:5.6-cli environment is set up.
panjie@panjies-iMac yunzhiclub % docker run -it php:5.6-cli /bin/bash
root@d46c5475b769:/# php -v
PHP 5.6.40 (cli) (built: Jan 23 2019 00:04:26)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
docker run -it php:5.6-cli /bin/bash
indicates that after constructing the corresponding container, enter the container.
Finally, we use the exit
command to exit the container, at which point the container is automatically terminated.
local debugging
Next, we debug the contanier container built on the php:5.6-cli
image. The steps are as follows:
- Create a ding.php file locally
- Copy the official sample code to the ding.php file.
- Replace the token with your own DingTalk robot token
- Copy ding.php to the contanier container
- Execute on the container
php ding.php
to view the effect
The process is as follows:
Create a ding.php file locally, then we copy the official code and replace the part with access_token=xxx:
<?php
function request_by_curl($remote_server, $post_string) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $remote_server);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
// curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$webhook = "https://oapi.dingtalk.com/robot/send?access_token=这里替换为你自己的自定义钉钉机器人token";
$message="我就是我, 是不一样的烟火";
$data = array ('msgtype' => 'text','text' => array ('content' => $message));
$data_string = json_encode($data);
$result = request_by_curl($webhook, $data_string);
echo $result;
?>
Note: The robot type must be a custom machine
After saving the file, use the docker run -t -d --name=php php:5.6-cli
command to start the container, and then continue to execute docker cp ./ding.php php:/root/ding.php
to copy the local ding.php to the container.
Finally, we proceed to the container for testing:
$ docker exec -it php /bin/bash
root@80adb7e221c3:/# cd /root
root@80adb7e221c3:~# php ding.php
root@80adb7e221c3:~# exit
Then you can find the messages pushed by the tested robot in DingTalk:
mardown
But just pushing text messages is not enough. What we want is to push messages with PR addresses, so that when the construction is successful, we can directly open the PR addresses to complete the merge operation by clicking the link in DingTalk.
Next, we stop the original container, start a new container, and use the mount method to mount the current directory to the container, so that we can make code changes locally, and then execute the script in the container for testing .
$ docker stop php
$ docker container rm php
$ docker run -it -v /Users/panjie/gitlab/yunzhiclub/process-evaluation/ding:/root --name=php php:5.6-cli /bin/bash
root@488cfb9ae30a:/# cd /root
root@488cfb9ae30a:~# root@ddff97414a5c:~# ls
ding.php
Note: The -d
parameter is missing from the above parameters, and the -t
parameter and the ending /bin/bash
e912d4598bfca9c08fd162e1a18a8282--- parameter are added. The function is to enter the container after the container is created.
Among them:/Users/panjie/gitlab/yunzhiclub/process-evaluation/ding
is the local directory where ding.php is located, which must be an absolute path, and/root
is the container directory.
Modify ding.php
According to the official documentation of DingTalk , we will change the push robot message format to markdown.
<?php
function request_by_curl($remote_server, $post_string) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $remote_server);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$webhook = "https://oapi.dingtalk.com/robot/send?access_token=你自定义机器人的token";
$message = ["title" => "这是标题", "text" => "## 执行成功 \n 我就是我,不一样的烟火[这里是地址](https://www.baidu.com)"];
$data = array ('msgtype' => 'markdown','markdown' => $message);
$data_string = json_encode($data);
$result = request_by_curl($webhook, $data_string);
echo $result;
echo PHP_EOL;
?>
Execute the php /root/ding.php
test in the container:
environment variable
Execute in the script in gitlab runner env
to view the environment variables, and then we find out the required items:
CI_MERGE_REQUEST_PROJECT_URL=https://xxx.xxx.com:xxx/yunzhiclub/process-evaluation
CI_MERGE_REQUEST_TITLE=用户管理 重置密码 和 编辑
CI_MERGE_REQUEST_IID=32
GITLAB_USER_LOGIN=weiweiyi189
Used to splice [PR标题](PR地址)构建成功,运行者:weiweiyi189
this markdown message.
PHP get environment variable
In order to use PHP in combination with environment variables in gitlab runner, we make the following modifications to ding.php.
<?php
$projectUrl = getenv("CI_MERGE_REQUEST_PROJECT_URL");
$prId = getenv("CI_MERGE_REQUEST_IID");
if (!$prId) {
echo "当前脚本仅适用于PR" . PHP_EOL;
exit(1);
}
$prUrl = $projectUrl . "/-/merge_requests/" . $prId;
$title = getenv("CI_MERGE_REQUEST_TITLE");
$author = getenv("GITLAB_USER_LOGIN");
$text = "## 😀 😃 😄 😁 😆 \n [$title]($prUrl)运行成功,提交者: $author";
function request_by_curl($remote_server, $post_string) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $remote_server);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$webhook = "https://oapi.dingtalk.com/robot/send?access_token=你自定义机器的token";
$markdown = ["title" => "这是标题", "text" => $text];
$data = array ('msgtype' => 'markdown','markdown' => $markdown);
$data_string = json_encode($data);
$result = request_by_curl($webhook, $data_string);
echo $result;
echo PHP_EOL;
?>
Then design several environment variables in the container:
$ export CI_MERGE_REQUEST_PROJECT_URL=https://xxx.xxx.com:xxx/yunzhiclub/process-evaluation
$ export CI_MERGE_REQUEST_TITLE="title test"
$ export CI_MERGE_REQUEST_IID=32
$ export GITLAB_USER_LOGIN=weiweiyi189
Finally execute again php ding.php
(Note: you may need to change the DingTalk robot keyword)
root@ddff97414a5c:~# php ding.php
{"errcode":0,"errmsg":"ok"}
strip the token
Since the DingTalk machine is only the token is different, so we turn token
into the value from the environment variable, and finally complete the version ding.php
<?php
$token = getenv("YZ_DING_TOKEN");
if (!$token) {
echo "未检测到环境变量'YZ_DING_TOKEN'" . PHP_EOL;
exit(1);
}
$projectUrl = getenv("CI_MERGE_REQUEST_PROJECT_URL");
$prId = getenv("CI_MERGE_REQUEST_IID");
if (!$prId) {
echo "当前脚本仅适用于PR" . PHP_EOL;
exit(1);
}
$prUrl = $projectUrl . "/-/merge_requests/" . $prId;
$title = getenv("CI_MERGE_REQUEST_TITLE");
$author = getenv("GITLAB_USER_LOGIN");
$text = "## 😀 😃 😄 😁 😆 \n [$title]($prUrl)运行成功,提交者: $author";
function request_by_curl($remote_server, $post_string) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $remote_server);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$webhook = "https://oapi.dingtalk.com/robot/send?access_token=$token";
$markdown = ["title" => "这是标题", "text" => $text];
$data = array ('msgtype' => 'markdown','markdown' => $markdown);
$data_string = json_encode($data);
$result = request_by_curl($webhook, $data_string);
echo $result;
echo PHP_EOL;
?>
Before using, we first set the environment variable YZ_DING_TOKEN
:
$ export YZ_DING_TOKEN=65adbb5f6d99955b86e0eff562e1d562exxxx
$ php ding.php
At this point, we have completed the local testing part, and then we can build it into a public image and upload it to a specific repository. For how to automatically build with the help of Alibaba Cloud's container service, please refer to the section How to create a docker container that runs angular unit tests -- DOCKER
The process of using Alibaba Cloud to build an image is omitted. The image address of the construction meeting is: registry.cn-beijing.aliyuncs.com/mengyunzhi/dingding:1.0.0
use
So far, we can use this image for DingTalk message push in gitlab runner
.
dingding-success:
stage: notify
tags:
- docker
image: registry.cn-beijing.aliyuncs.com/mengyunzhi/dingding:1.0.0
variables:
YZ_DING_TOKEN: "65adbb5f6d99955b86e0eff562e1d562e85086cc18740e5c07b2xxxx"
script:
- php /root/ding.php
Note: The keyword of your custom machine needs to be a substring of 运行成功,提交者
.
At this point, the current image can send a successful message to DingTalk when the build is successful.
Of course, you can also rewrite the content in ding.php yourself to meet the needs of more personalized definition of the content sent by the robot.
BUILD OFFICIAL DOCKER IMAGE
After docker is officially registered, public images can be pushed without restrictions. After we register docker, install docker desktop locally.
Next, use the image built by Alibaba Cloud to build locally:
$ docker run --name="dingding" registry.cn-beijing.aliyuncs.com/mengyunzhi/dingding:1.0.0
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-beijing.aliyuncs.com/mengyunzhi/dingding 1.0.0 3b817aa5b98b 19 minutes ago 344MB
Since the official docker repository only supports image push prefixed with its username, we need to rename it before pushing to the official repository:
$ docker tag registry.cn-beijing.aliyuncs.com/mengyunzhi/dingding:1.0.0 teacherpan/gitlab-dingtalk:1.0.0
$ docker image ls
registry.cn-beijing.aliyuncs.com/mengyunzhi/dingding 1.0.0 3b817aa5b98b 19 minutes ago 344MB
teacherpan/gitlab-dingtalk 1.0.0 3b817aa5b98b 19 minutes ago 344MB
Finally, open docker desktop, find the image prefixed with the docker username, and click push to hub in the menu
Depending on the network speed, the upload time will definitely be different:
Finally, we can find it in the official docker library and successfully share it with other docker partners.
At this point, we can happily use the official repository.
dingding-success:
stage: notify
tags:
- docker
image: teacherpan/gitlab-dingtalk
variables:
YZ_DING_TOKEN: "65adbb5f6d99955b86e0eff562e1d562e85086cc18740e5c07b2xxxx"
script:
- php /root/ding.php
The most important thing is that when others have a demand for the DingTalk push of gitlab runner, they can also quickly find us in the docker hub.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。