Compare commits

..

3 Commits

Author SHA1 Message Date
lddsb b7390525e1 fix: default image cdn url 2020-01-20 11:34:31 +08:00
lddsb 9df9c9aa37 add tips title option 2019-11-07 21:40:28 +08:00
lddsb f931e70cc7 compatible full token url as token parameter 2019-09-24 09:26:28 +08:00
18 changed files with 307 additions and 1065 deletions
+37 -11
View File
@@ -9,7 +9,7 @@ steps:
commands:
- make vet
environment:
GO111MODULE: "on"
GO111MODULE: on
volumes:
- name: gopath
path: /go
@@ -21,7 +21,7 @@ steps:
- make test
- make coverage
environment:
GO111MODULE: "on"
GO111MODULE: on
volumes:
- name: gopath
path: /go
@@ -37,13 +37,9 @@ volumes:
- name: gopath
temp: {}
trigger:
event:
- pull_request
---
kind: pipeline
name: dryrun
name: build
steps:
- name: build
@@ -53,7 +49,13 @@ steps:
- go build -a -o drone-dingtalk-message .
environment:
CGO_ENABLED: 0
GO111MODULE: "on"
GO111MODULE: on
- name: executable
pull: always
image: golang
commands:
- ./drone-dingtalk-message -h
- name: dryrun
pull: always
@@ -61,15 +63,39 @@ steps:
settings:
cache_from: lddsb/drone-dingtalk-message
dockerfile: Dockerfile
dry_run: true
dryrun: true
repo: lddsb/drone-dingtalk-message
tags:
- latest
- 1.0.0
when:
event:
- pull_request
- name: publish
pull: always
image: plugins/docker
settings:
repo: lddsb/drone-dingtalk-message
dockerfile: Dockerfile
tags:
- latest
- 1.0.0
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
status:
- success
event:
- tag
trigger:
event:
- pull_request
ref:
- refs/heads/master
- 'refs/pull/**'
- 'refs/tags/**'
depends_on:
- testing
-2
View File
@@ -1,2 +0,0 @@
[*.y*ml]
indent_size = 2
-55
View File
@@ -1,55 +0,0 @@
name: Publish to DockerHub and Github Package
on:
push:
tags:
- "v*"
jobs:
dockerhub:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Repo metadata
id: repo
uses: actions/github-script@v3
with:
script: |
const repo = await github.repos.get(context.repo)
return repo.data
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=lddsb/drone-dingtalk-message
GITHUB_IMAGE=ghcr.io/lddsb/drone-dingtalk-message
VERSION=${GITHUB_REF#refs/tags/v}
TAGS="${DOCKER_IMAGE}:${VERSION}"
if [[ $VERSION =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
MINOR=${VERSION%.*}
MAJOR=${MINOR%.*}
TAGS="$TAGS,${DOCKER_IMAGE}:${MINOR},${DOCKER_IMAGE}:${MAJOR},${DOCKER_IMAGE}:latest"
TAGS="$TAGS,${GITHUB_IMAGE}:${VERSION},${GITHUB_IMAGE}:${MINOR},${GITHUB_IMAGE}:${MAJOR},${GITHUB_IMAGE}:latest"
fi
echo ::set-output name=tags::${TAGS}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Register
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.CR_PAT }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.prep.outputs.tags }}
-25
View File
@@ -1,25 +0,0 @@
name: Publish release
on:
push:
tags:
- "v*"
jobs:
release:
name: publish release, upload asset
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.15.6
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.CR_PAT }}
+1 -3
View File
@@ -2,6 +2,4 @@ dive.log
drone-dingtalk-message
.idea
vendor
coverage.txt
coverage.out
env.list
coverage.txt
-49
View File
@@ -1,49 +0,0 @@
env:
- GO111MODULE=on
before:
hooks:
- go mod download
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- 386
- amd64
- arm
- arm64
mod_timestamp: '{{ .CommitTimestamp }}'
binary: dingtalk-message
flags:
- -trimpath
ldflags:
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X main.builtBy=goreleaser
checksum:
name_template: '{{ .ProjectName }}_checksums.txt'
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
- Merge pull request
- Merge branch
- go mod tidy
archives:
- name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
format_overrides:
- goos: windows
format: zip
files:
- README.md
- LICENSE
- tpls/*
-72
View File
@@ -1,72 +0,0 @@
# Changelog
## [Unreleased]
## [1.2.5] - 2020-12-16
### Added:
* The TPL can use environment variables.
* Debug mode.
* Use GitHub Actions for automation.
## [1.2.4] - 2020-04-28
### Fixed:
* kubernetes runner missing env, [details](https://docs.drone.io/runner/kubernetes/overview)
## [1.2.3] - 2020-01-20
### Fixed:
* CDN url of default image.
## [1.2.2] - 2019-12-07
### Added:
* Support DingTalk `sign secret`, please see the [README](README.md) for instructions.
## [1.2.1] - 2019-11-07
### Added:
* Support customize message tips title by `tips_title` option.
## [1.2.0] - 2019-09-24
### Added:
* Support custom TPL.
## [1.1.4] - 2020-04-28
### Fixed:
* kubernetes runner missing env, [details](https://docs.drone.io/runner/kubernetes/overview)
## [1.1.3] - 2020-01-20
### Fixed:
* CDN url of default image.
## [1.1.2] - 2019-11-07
### Added:
* Support customize message tips title by `tips_title` option.
## [1.1.1] - 2019-09-24
### Added:
* Support full token url as `token`.
## [1.1.0] - 2019-03-09
### Added:
* Package management tools migrate from dep to go mod, 1.0.x version stopped supporting new features.
## [1.0.2] - 2020-01-20
### Fixed:
* CDN url of default image.
## [1.0.1] - 2019-03-09
### Added:
* Auto publish image to DockerHub.
[Unreleased]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.2.5...HEAD
[1.2.5]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.2.4...v1.2.5
[1.2.4]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.2.3...v1.2.4
[1.2.3]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.2.2...v1.2.3
[1.2.2]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.2.1...v1.2.2
[1.2.1]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.2.0...v1.2.1
[1.2.0]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.1.0...v1.2.0
[1.1.4]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.1.3...v1.1.4
[1.1.3]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.1.2...v1.1.3
[1.1.2]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.1.1...v1.1.2
[1.1.1]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.0.0...v1.1.0
[1.0.2]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.0.1...v1.0.2
[1.0.1]: https://github.com/lddsb/drone-dingtalk-message/compare/v1.0.0...v1.0.1
+11 -5
View File
@@ -1,11 +1,17 @@
FROM golang AS builder
WORKDIR /app
COPY . .
RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -a -o drone-dingtalk .
ENV GO111MODULE on
ENV CGO_ENABLED 0
ENV GOOS linux
RUN go build -a -o drone-dingtalk .
FROM alpine:latest
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
COPY --from=builder /app/drone-dingtalk /bin
COPY --from=builder /app/tpls /app/drone/dingtalk/message/tpls
RUN apk update && \
apk add \
ca-certificates && \
rm -rf /var/cache/apk/*
ENTRYPOINT ["/bin/drone-dingtalk"]
COPY --from=builder /app/drone-dingtalk /bin/
ENTRYPOINT ["/bin/drone-dingtalk"]
+36 -115
View File
@@ -1,19 +1,5 @@
# Drone CI DingTalk Message Plugin
[![GitHub Actions](https://github.com/lddsb/drone-dingtalk-message/workflows/Publish%20to%20DockerHub%20and%20Github%20Package/badge.svg)](https://github.com/lddsb/drone-dingtalk-message/actions?query=workflow%3A%22Publish+to+DockerHub+and+Github+Package%22) [![Go Report Card](https://goreportcard.com/badge/github.com/lddsb/drone-dingtalk-message)](https://goreportcard.com/report/github.com/lddsb/drone-dingtalk-message) [![codecov](https://codecov.io/gh/lddsb/drone-dingtalk-message/branch/master/graph/badge.svg)](https://codecov.io/gh/lddsb/drone-dingtalk-message) [![Dependabot](https://api.dependabot.com/badges/status?host=github&repo=lddsb/drone-dingtalk-message&identifier=159822771)](https://app.dependabot.com/accounts/lddsb/repos/159822771) [![LICENSE: MIT](https://img.shields.io/github/license/lddsb/drone-dingtalk-message.svg?style=flat-square)](LICENSE)
[中文说明](README_ZH.md)
<!-- toc -->
- [Drone CI Plugin Config](#drone-ci-plugin-config)
- [Plugin Parameter Reference](#plugin-parameter-reference)
- [TPL](#tpl)
- [Screen Shot](#screen-shot)
- [Development](#development)
- [Todo](#todo)
- [Kubernetes Users](#kubernetes-users)
<!-- tocstop -->
[![Build Status](https://drone.lddsb.com/api/badges/lddsb/drone-dingtalk-message/status.svg)](https://drone.lddsb.com/lddsb/drone-dingtalk-message) [![Go Report Card](https://goreportcard.com/badge/github.com/lddsb/drone-dingtalk-message)](https://goreportcard.com/report/github.com/lddsb/drone-dingtalk-message) [![codecov](https://codecov.io/gh/lddsb/drone-dingtalk-message/branch/master/graph/badge.svg)](https://codecov.io/gh/lddsb/drone-dingtalk-message) [![codebeat badge](https://codebeat.co/badges/23f68b84-1fd2-4f29-8467-9285c1e0facc)](https://codebeat.co/projects/github-com-lddsb-drone-dingtalk-message-master) [![LICENSE: MIT](https://img.shields.io/github/license/lddsb/drone-dingtalk-message.svg?style=flat-square)](LICENSE)
### Drone CI Plugin Config
`0.8.x`
@@ -26,8 +12,11 @@ pipeline:
type: markdown
```
`1.x`
`1.0.x`
```yaml
kind: pipeline
name: default
steps:
...
- name: notification
@@ -35,8 +24,7 @@ steps:
settings:
token: your-groupbot-token
type: markdown
secret: your-secret-for-generate-sign
debug: true
```
### Plugin Parameter Reference
@@ -48,98 +36,38 @@ String. Access token for group bot. (you can get the access token when you add a
String. Message type, plan support text, markdown, link and action card, but due to time issue, it's only support `markdown` and `text` now, and you can get the best experience by use markdown.
`secret`
String. Secret for generate sign.
`tpl`
String. Your custom `tpl`, it can be a local path, or a remote http link.
`debug`
Boolean. Debug mode.
`tips_title`
String. You can customize the title for the message tips, just work when message type is markdown.
`success_color`
`message_color`(when `type=markdown`)
Boolean value. This option can change the title and commit message color if turn on.
`success_color`(when `message_color=true`)
String. You can customize the color for the `build success` message by this option, you should input a hex color, example: `008000`.
`failure_color`
`failure_color`(when `message_color=true`)
String. You can customize the color for the `build success` message by this option, you should input a hex color, example: `FF0000`.
`success_pic`
`sha_link`(when `type=markdown`)
Boolean value. This option can link the sha to your source page when it turn on.
`message_pic`(when `type=markdown`)
Boolean value. If this option turn on, it will embed a image into the message.
`success_pic`(when `message_pic=true`)
String. You can customize the picture for the `build success` message by this option.
`failure_pic`
`failure_pic`(when `message_pic=true`)
String. You can customize the picture for the `build failure` message by this option.
`tpl_commit_branch_name`
String. You can customize the [TPL_COMMIT_BRANCH] by this configuration item.
`tpl_repo_short_name`
String. You can customize the [TPL_REPO_SHORT_NAME] by this configuration item.
`tpl_repo_full_name`
String. You can customize the [TPL_REPO_FULL_NAME] by this configuration item.
`tpl_build_status_success`
String. You can customize the [TPL_BUILD_STATUS] (when status=`success`) by this configuration item.
`tpl_build_status_failure`
String. You can customize the [TPL_BUILD_STATUS] (when status=`failure`) by this configuration item.
### TPL
> `tpl` won't work with message type `link` !!!
That's a good news, we support `tpl` now.This is an example for `markdown` message:
# [TPL_REPO_FULL_NAME] build [TPL_BUILD_STATUS], takes [TPL_BUILD_CONSUMING]s
[TPL_COMMIT_MSG]
[TPL_COMMIT_SHA]([TPL_COMMIT_LINK])
[[TPL_AUTHOR_NAME]([TPL_AUTHOR_EMAIL])](mailto:[TPL_AUTHOR_EMAIL])
[Click To The Build Detail Page [TPL_STATUS_EMOTICON)]]([TPL_BUILD_LINK])
You can write your own `tpl` what you want. The syntax of `tpl` is very simple, you can fill `tpl` with preset variables. It's a list of currently supported preset variables:
| Variable | Value |
| :-------------------: | :-------------------------------------------------: |
| [TPL_REPO_SHORT_NAME] | current repo name(bare name) |
| [TPL_REPO_FULL_NAME] | the full name(with group name) of current repo |
| [TPL_REPO_GROUP_NAME] | the group name of current repo |
| [TPL_REPO_OWNER_NAME] | the owner name of current repo |
| [TPL_REPO_REMOTE_URL] | the remote url of current repo |
| [TPL_BUILD_STATUS] | current build status(e.g., success, failure) |
| [TPL_BUILD_LINK] | current build link |
| [TPL_BUILD_EVENT] | current build event(e.g., push, pull request, etc.) |
| [TPL_BUILD_CONSUMING] | current build consuming, second |
| [TPL_COMMIT_SHA] | current commit sha |
| [TPL_COMMIT_REF] | current commit ref(e.g., refs/heads/master, etc.) |
| [TPL_COMMIT_LINK] | current commit remote url link |
| [TPL_COMMIT_BRANCH] | current branch name(e.g., dev, etc) |
| [TPL_COMMIT_MSG] | current commit message |
| [TPL_AUTHOR_NAME] | current commit author name |
| [TPL_AUTHOR_EMAIL] | current commit author email |
| [TPL_AUTHOR_USERNAME] | current commit author username |
| [TPL_AUTHOR_AVATAR] | current commit author avatar |
| [TPL_STATUS_PIC] | custom pic for build status |
| [TPL_STATUS_COLOR] | custom color for build status |
| [TPL_STATUS_EMOTICON] | custom emoticon for build status |
### Screen Shot
- Send Success
@@ -165,35 +93,28 @@ You can write your own `tpl` what you want. The syntax of `tpl` is very simple,
![markdown-massage-customize](https://i.imgur.com/xFrCTZp.jpg)
### Todo
- Multi-Type
- Multi-Lang
- More User Customization
### Development
We use `go mod` to manage dependencies, so it's easy to build.
- get this repo
- First get this repo
```shell
$ git clone https://github.com/lddsb/drone-dingtalk-message.git /path/to/you/want
go get github.com/lddsb/drone-dingtalk-message
```
- get dependent lib
```shell
dep ensure
```
- build
```shell
$ cd /path/to/you/want && GO111MODULE=on go build .
cd $GOPATH/src/github.com/lddsb/drone-dingtalk-message && go build .
```
- run
```shell
$ ./drone-dingtalk-message -h
./drone-dingtalk-message -h
```
### Todo
It's sad, just support `text`, `markdown` and `link` type now.
- implement all message type
- i18N
- batch send
- retry(e.g., network error, etc.)
### Kubernetes Users
Attention kubernetes users, [CHANGELOG](CHANGELOG.md#124---2020-04-28).It's the available versions:
- `1.1`(always latest for `1.1.x`)
- `>=1.1.4`
- `1.2`(always latest for `1.2.x`)
- `>=1.2.4`
- latest(always latest)
-200
View File
@@ -1,200 +0,0 @@
# Drone CI的钉钉群组机器人通知插件
[![GitHub Actions](https://github.com/lddsb/drone-dingtalk-message/workflows/Publish%20to%20DockerHub%20and%20Github%20Package/badge.svg)](https://github.com/lddsb/drone-dingtalk-message/actions?query=workflow%3A%22Publish+to+DockerHub+and+Github+Package%22) [![Go Report Card](https://goreportcard.com/badge/github.com/lddsb/drone-dingtalk-message)](https://goreportcard.com/report/github.com/lddsb/drone-dingtalk-message) [![codecov](https://codecov.io/gh/lddsb/drone-dingtalk-message/branch/master/graph/badge.svg)](https://codecov.io/gh/lddsb/drone-dingtalk-message) [![Dependabot](https://api.dependabot.com/badges/status?host=github&repo=lddsb/drone-dingtalk-message&identifier=159822771)](https://app.dependabot.com/accounts/lddsb/repos/159822771) [![LICENSE: MIT](https://img.shields.io/github/license/lddsb/drone-dingtalk-message.svg?style=flat-square)](LICENSE)
<!-- toc -->
- [怎么使用本插件](#%E6%80%8E%E4%B9%88%E4%BD%BF%E7%94%A8%E6%9C%AC%E6%8F%92%E4%BB%B6)
- [插件参数](#%E6%8F%92%E4%BB%B6%E5%8F%82%E6%95%B0)
- [模版](#%E6%A8%A1%E7%89%88)
- [截图展示](#%E6%88%AA%E5%9B%BE%E5%B1%95%E7%A4%BA)
- [贡献代码](#%E8%B4%A1%E7%8C%AE%E4%BB%A3%E7%A0%81)
- [未来计划](#%E6%9C%AA%E6%9D%A5%E8%AE%A1%E5%88%92)
- [Kubernetes 用户请注意](#kubernetes-%E7%94%A8%E6%88%B7%E8%AF%B7%E6%B3%A8%E6%84%8F)
<!-- tocstop -->
### 怎么使用本插件
添加一个`step`到你的`.drone.yml`中,下面是例子:
`0.8.x`
```yaml
pipeline:
...
notification:
image: lddsb/drone-dingtalk-message
token: your-group-bot-token
type: markdown
```
`1.x`
```yaml
steps:
...
- name: notification
image: lddsb/drone-dingtalk-message
settings:
token: your-groupbot-token
type: markdown
secret: your-secret-for-generate-sign
debug: true
```
### 插件参数
`token`(必须)
你可以通过加入和创建一个群组来添加钉钉自定义机器人,添加自定义机器人完成后即可获得所需要的`access token`
`type`(必须)
消息类型,因个人能力有限,目前仅支持`markdown``text`,其中,使用`markdown`可以获得最好的体验。
`secret`
如果你设置了`加签`,可以把你的`加签`密钥填入此项完成`加签`操作。
`tpl`
你可以通过该字段来自定义你的消息模版。该字段可以是一个本地路径也可以是一个远程的URL。
`debug`
通过该值可以打开`debug`模式,打印所有环境变量。
`tips_title`
你可以通过该字段自定义钉钉机器人的消息通知提醒标题。(注意,不是消息内容的标题,是收到钉钉机器人发的消息后,会有一个外显的标题)
`success_color`
你可以通过该字段自定义打包成功的颜色。比如:`008000`
`failure_color`
你可以通过该字段自定义打包失败的颜色。比如:`FF0000`
`success_pic`
你可以通过该字段自定义打包成功的图片。
`failure_pic`
字符串,你可以通过该字段自定义打包失败的图片。
`tpl_commit_branch_name`
你可以通过该字段自定义分支的名称,可以在模版中通过[TPL_COMMIT_BRANCH]来使用该值。
`tpl_repo_short_name`
你可以通过该字段自定义仓库的名字,可以在模版中通过[TPL_REPO_SHORT_NAME]来使用该值。
`tpl_repo_full_name`
你可以通过该字段自定义仓库的全名(包含组织名称),可以在模版中通过[TPL_REPO_FULL_NAME]来使用该值。
`tpl_build_status_success`
你可以通过该字段自定义运行成功状态的值,可以在模版中通过[TPL_BUILD_STATUS]来使用该值。(仅当前方`step`运行结果为成功时该值会生效)
`tpl_build_status_failure`
你可以通过该字段自定义运行失败状态的值,可以在模版中通过[TPL_BUILD_STATUS]来使用该值。(仅当前方`step`运行结果为失败时该值会生效)
### 模版
> `tpl` 对 `link` 类型的消息并不支持 !!!
感天动地,我们终于支持自定义模版了!下面是一个`markdown`的自定义模版例子:
# [TPL_REPO_FULL_NAME] build [TPL_BUILD_STATUS], takes [TPL_BUILD_CONSUMING]s
[TPL_COMMIT_MSG]
[TPL_COMMIT_SHA]([TPL_COMMIT_LINK])
[[TPL_AUTHOR_NAME]([TPL_AUTHOR_EMAIL])](mailto:[TPL_AUTHOR_EMAIL])
[Click To The Build Detail Page [TPL_STATUS_EMOTICON)]]([TPL_BUILD_LINK])
你可以写自己喜欢的模版,终于不用再对默认模版发愁啦!并且模版的语法非常简单!比较可惜的是目前支持的变量还比较少,下面是当前支持的变量的列表:
| Variable | Value |
| :-------------------: | :-------------------------------------------------: |
| [TPL_REPO_SHORT_NAME] | 当前仓库的名称,比如本仓库 `drone-dingtalk-message` |
| [TPL_REPO_FULL_NAME] | 当前仓库的名称,比如本仓库 `lddsb/drone-dingtalk-message` |
| [TPL_REPO_GROUP_NAME] | 当前仓库的组织名称,比如本仓库 `lddsb` |
| [TPL_REPO_OWNER_NAME] | 当前仓库拥有者的名称 |
| [TPL_REPO_REMOTE_URL] | 当前仓库的远程地址 |
| [TPL_BUILD_STATUS] | 当前编译的状态(比如, success, failure) |
| [TPL_BUILD_LINK] | 当前编译的链接 |
| [TPL_BUILD_EVENT] | 触发当前编译的动作(比如, push, pull request等) |
| [TPL_BUILD_CONSUMING] | 当前编译耗时,单位秒 |
| [TPL_COMMIT_SHA] | 当前提交的sha |
| [TPL_COMMIT_REF] | 当前提交的ref(比如, refs/heads/master等) |
| [TPL_COMMIT_LINK] | 当前提交的远程地址 |
| [TPL_COMMIT_BRANCH] | 当前分之名称(比如, dev, master等) |
| [TPL_COMMIT_MSG] | 当前提交的信息 |
| [TPL_AUTHOR_NAME] | 当前提交作者名称 |
| [TPL_AUTHOR_EMAIL] | 当前提交作者邮箱地址 |
| [TPL_AUTHOR_USERNAME] | 当前提交作者的用户名 |
| [TPL_AUTHOR_AVATAR] | 当前提交作者的头像 |
| [TPL_STATUS_PIC] | 根据编译状态显示不同的图片 |
| [TPL_STATUS_COLOR] | 根据编译状态显示不同的颜色 |
| [TPL_STATUS_EMOTICON] | 根据编译状态显示不同的表情,比如 `:)` `:(` |
### 截图展示
- 发送成功(Drone Web
![send-success](https://i.imgur.com/cECppkW.jpg)
- 忘记填写Access TokenDrone Web
![missing-access-token](https://i.imgur.com/Su7iiyw.jpg)
- 忘记填写消息类型或者不支持的消息类型
![message-type-error](https://i.imgur.com/qtJ4DsA.jpg)
- 默认的`markdown`消息
![markdown-message-default](https://i.imgur.com/Bl7cT1y.jpg)
- 带颜色和链接的`markdown`消息
![markdown-massage-customize](https://i.imgur.com/pzdFzIw.jpg)
- 带颜色、链接和图片的`markdown`消息
![markdown-massage-customize](https://i.imgur.com/xFrCTZp.jpg)
### 贡献代码
本项目使用了`go mod`来管理依赖,因此要编译本项目相当简单。
- 先把项目代码拷贝到本地
```shell
$ git clone https://github.com/lddsb/drone-dingtalk-message.git /path/to/you/want
```
- 然后直接执行编译即可
```shell
$ cd /path/to/you/want && GO111MODULE=on go build .
```
- 跑个`help`
```shell
$ ./drone-dingtalk-message -h
```
### 未来计划
目前仅支持 `text`, `markdown` 以及 `link` 类型的消息,建议使用`markdown`类型。
- 实现更多的消息类型
- i18N国际化直接翻译环境变量
- 批量发送给多个群机器人
- 失败重试机制
### Kubernetes 用户请注意
因为`Drone CI` [官方缺陷](https://docs.drone.io/runner/kubernetes/overview) ,所以较早版本将无法正常获取到需要用到的变量,会导致部分功能异常。为了能正常使用,所以请使用以下版本:
- `1.1`(总会是`1.1.x`的最新版本)
- `>=1.1.4`
- `1.2`(总会是`1.2.x`的最新版本)
- `>=1.2.4`
+2 -2
View File
@@ -4,6 +4,6 @@ go 1.12
require (
github.com/joho/godotenv v1.3.0
github.com/lddsb/dingtalk-webhook v0.0.4
github.com/urfave/cli v1.22.5
github.com/lddsb/dingtalk-webhook v0.0.1
github.com/urfave/cli v1.20.0
)
+4 -21
View File
@@ -1,23 +1,6 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/lddsb/dingtalk-webhook v0.0.4 h1:gAJFy66L2gZ5j6kDrHRoz/zQFaNamcObtetNonq76RA=
github.com/lddsb/dingtalk-webhook v0.0.4/go.mod h1:dwNU75Sog87wJXAFcY5mDFM7eW4hIdX7bNemrN92pH0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.3 h1:FpNT6zq26xNpHZy08emi755QwzLPs6Pukqjlc7RfOMU=
github.com/urfave/cli v1.22.3/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
github.com/lddsb/dingtalk-webhook v0.0.1 h1:l4FdTMaRaHnrYfByALukFWK0ru9Rttl0dANg13/SnTI=
github.com/lddsb/dingtalk-webhook v0.0.1/go.mod h1:5E+/sOBb6m+3ztqnZl4danEY3I5FeIwb12v12s9osbw=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+69 -181
View File
@@ -4,21 +4,19 @@ import (
"fmt"
"log"
"os"
"time"
"github.com/joho/godotenv"
_ "github.com/joho/godotenv/autoload"
"github.com/urfave/cli"
)
// Version of cli
var Version = "0.2.1219"
var Version = "0.1.1202"
func main() {
app := cli.NewApp()
app.Name = "Drone DingTalk Message Plugin"
app.Usage = "Sending message to DingTalk group by robot using WebHook"
year := time.Now().Year()
app.Copyright = fmt.Sprintf("© 2018-%d Dee Luo", year)
app.Name = "Drone Dingtalk Message Plugin"
app.Usage = "Sending message to Dingtalk group by robot using webhook"
app.Copyright = "© 2018 Dee Luo"
app.Authors = []cli.Author{
{
Name: "Dee Luo",
@@ -29,45 +27,36 @@ func main() {
app.Version = Version
app.Flags = []cli.Flag{
cli.BoolFlag{
Name: "config.debug,debug",
Name: "config.debug",
Usage: "debug mode",
EnvVar: "PLUGIN_DEBUG",
},
cli.StringFlag{
Name: "config.tips.title",
Usage: "customize the tips title",
EnvVar: "PLUGIN_TIPS_TITLE",
},
cli.StringFlag{
Name: "config.token,access_token,token",
Usage: "DingTalk webhook access token",
Usage: "dingtalk webhook access token",
EnvVar: "PLUGIN_ACCESS_TOKEN,PLUGIN_TOKEN",
},
cli.StringFlag{
Name: "config.secret,secret",
Usage: "DingTalk WebHook secret for generate sign",
EnvVar: "PLUGIN_SECRET",
Name: "config.lang",
Value: "zh_CN",
Usage: "the lang display (zh_CN or en_US, zh_CN is default)",
EnvVar: "PLUGIN_LANG",
},
cli.StringFlag{
Name: "config.message.type,message_type,type",
Usage: "DingTalk message type, like text, markdown, action card, link and feed card...",
Name: "config.message.type,message_type",
Usage: "dingtalk message type, like text, markdown, action card, link and feed card...",
EnvVar: "PLUGIN_MSG_TYPE,PLUGIN_TYPE,PLUGIN_MESSAGE_TYPE",
},
cli.StringFlag{
Name: "config.message.at.all,at.all",
Name: "config.message.at.all",
Usage: "at all in a message(only text and markdown type message can at)",
EnvVar: "PLUGIN_MSG_AT_ALL",
},
cli.StringFlag{
Name: "config.message.at.mobiles,mobiles",
Usage: "at someone in a DingTalk group need this guy bind's mobile",
Name: "config.message.at.mobiles",
Usage: "at someone in a dingtalk group need this guy bind's mobile",
EnvVar: "PLUGIN_MSG_AT_MOBILES",
},
cli.StringFlag{
Name: "commit.author.username",
Usage: "providers the author username for the current commit",
EnvVar: "DRONE_COMMIT_AUTHOR",
},
cli.StringFlag{
Name: "commit.author.avatar",
Usage: "providers the author avatar url for the current commit",
@@ -105,45 +94,10 @@ func main() {
EnvVar: "DRONE_COMMIT_SHA",
},
cli.StringFlag{
Name: "commit.ref",
Usage: "provider the commit ref for the current build",
EnvVar: "DRONE_COMMIT_REF",
},
cli.StringFlag{
Name: "repo.full.name",
Name: "repo.fullname",
Usage: "providers the full name of the repository",
EnvVar: "DRONE_REPO",
},
cli.StringFlag{
Name: "repo.name",
Usage: "provider the name of the repository",
EnvVar: "DRONE_REPO_NAME",
},
cli.StringFlag{
Name: "repo.group",
Usage: "provider the group of the repository",
EnvVar: "DRONE_REPO_NAMESPACE",
},
cli.StringFlag{
Name: "repo.remote.url",
Usage: "provider the remote url of the repository",
EnvVar: "DRONE_REMOTE_URL",
},
cli.StringFlag{
Name: "repo.owner",
Usage: "provider the owner of the repository",
EnvVar: "DRONE_REPO_OWNER",
},
cli.Uint64Flag{
Name: "stage.started",
Usage: "stage started ",
EnvVar: "DRONE_STAGE_STARTED",
},
cli.Uint64Flag{
Name: "stage.finished",
Usage: "stage finished",
EnvVar: "DRONE_STAGE_FINISHED",
},
cli.StringFlag{
Name: "build.status",
Usage: "build status",
@@ -156,85 +110,45 @@ func main() {
EnvVar: "DRONE_BUILD_LINK",
},
cli.StringFlag{
Name: "build.event",
Usage: "build event",
EnvVar: "DRONE_BUILD_EVENT",
},
cli.Uint64Flag{
Name: "build.started",
Usage: "build started",
EnvVar: "DRONE_BUILD_STARTED",
},
cli.Uint64Flag{
Name: "build.finished",
Usage: "build finished",
EnvVar: "DRONE_BUILD_FINISHED",
},
cli.StringFlag{
Name: "tpl.build.status.success",
Usage: "tpl.build status for replace success",
EnvVar: "TPL_BUILD_STATUS_SUCCESS, PLUGIN_TPL_BUILD_STATUS_SUCCESS",
},
cli.StringFlag{
Name: "tpl.build.status.failure",
Usage: "tpl.build status for replace failure",
EnvVar: "TPL_BUILD_STATUS_FAILURE, PLUGIN_TPL_BUILD_STATUS_FAILURE",
},
cli.StringFlag{
Name: "custom.pic.url.success",
Usage: "custom success picture url",
Name: "config.success.pic.url",
Usage: "config success picture url",
EnvVar: "SUCCESS_PICTURE_URL,PLUGIN_SUCCESS_PIC",
},
cli.StringFlag{
Name: "custom.pic.url.failure",
Usage: "custom failure picture url",
Name: "config.failure.pic.url",
Usage: "config failure picture url",
EnvVar: "FAILURE_PICTURE_URL,PLUGIN_FAILURE_PIC",
},
cli.StringFlag{
Name: "custom.color.success",
Usage: "custom success color for title in markdown",
Name: "config.success.color",
Usage: "config success color for title in markdown",
EnvVar: "SUCCESS_COLOR,PLUGIN_SUCCESS_COLOR",
},
cli.StringFlag{
Name: "custom.color.failure",
Usage: "custom failure color for title in markdown",
Name: "config.failure.color",
Usage: "config failure color for title in markdown",
EnvVar: "FAILURE_COLOR,PLUGIN_FAILURE_COLOR",
},
cli.StringFlag{
Name: "custom.tpl,tpl",
Usage: "custom tpl",
EnvVar: "PLUGIN_TPL,PLUGIN_CUSTOM_TPL",
cli.BoolFlag{
Name: "config.message.color",
Usage: "configure the message with color or not",
EnvVar: "PLUGIN_COLOR,PLUGIN_MESSAGE_COLOR",
},
cli.BoolFlag{
Name: "config.message.pic",
Usage: "configure the message with picture or not",
EnvVar: "PLUGIN_PIC,PLUGIN_MESSAGE_PIC",
},
cli.BoolFlag{
Name: "config.message.sha.link",
Usage: "link sha source page or not",
EnvVar: "PLUGIN_SHA_LINK,PLUGIN_MESSAGE_SHA_LINK",
},
cli.StringFlag{
Name: "tpl.repo.full.name",
Usage: "tpl custom repo full name",
EnvVar: "PLUGIN_TPL_REPO_FULL_NAME,TPL_REPO_FULL_NAME",
Name: "config.tips.title",
Usage: "tips title, just work for markdown type message",
EnvVar: "PLUGIN_TIPS_TITLE",
},
cli.StringFlag{
Name: "tpl.repo.short.name",
Usage: "tpl custom repo short name",
EnvVar: "PLUGIN_TPL_REPO_SHORT_NAME,TPL_REPO_SHORT_NAME",
},
cli.StringFlag{
Name: "tpl.commit.branch.name",
Usage: "tpl custom commit branch name",
EnvVar: "PLUGIN_TPL_COMMIT_BRANCH_NAME,TPL_COMMIT_BRANCH_NAME",
},
cli.StringFlag{
Name: "custom.started,started",
Usage: "started custom env name, eg., BUILD_STARTED",
EnvVar: "PLUGIN_CUSTOM_STARTED",
},
cli.StringFlag{
Name: "custom.finished,finished",
Usage: "finished custom env name, eg., BUILD_FINISHED",
EnvVar: "PLUGIN_CUSTOM_FINISHED",
},
}
// kubernetes runner patch
if _, err := os.Stat("/run/drone/env"); err == nil {
godotenv.Overload("/run/drone/env")
}
if err := app.Run(os.Args); nil != err {
@@ -248,81 +162,55 @@ func run(c *cli.Context) {
Drone: Drone{
// repo info
Repo: Repo{
ShortName: c.String("repo.name"),
GroupName: c.String("repo.group"),
OwnerName: c.String("repo.owner"),
RemoteURL: c.String("repo.remote.url"),
FullName: c.String("repo.full.name"),
FullName: c.String("repo.fullname"),
},
// build info
Build: Build{
Status: c.String("build.status"),
Link: c.String("build.link"),
Event: c.String("build.event"),
StartAt: c.Uint64("build.started"),
FinishedAt: c.Uint64("build.finished"),
Status: c.String("build.status"),
Link: c.String("build.link"),
},
Commit: Commit{
Sha: c.String("commit.sha"),
Branch: c.String("commit.branch"),
Message: c.String("commit.message"),
Link: c.String("commit.link"),
Author: CommitAuthor{
Avatar: c.String("commit.author.avatar"),
Email: c.String("commit.author.email"),
Name: c.String("commit.author.name"),
Username: c.String("commit.author.username"),
Authors: struct {
Avatar string
Email string
Name string
}{
Avatar: c.String("commit.author.avatar"),
Email: c.String("commit.author.email"),
Name: c.String("commit.author.name"),
},
},
Stage: Stage{
StartedAt: c.Uint64("stage.started"),
FinishedAt: c.Uint64("stage.finished"),
},
},
// custom config
Config: Config{
AccessToken: c.String("config.token"),
Secret: c.String("config.secret"),
IsAtALL: c.Bool("config.message.at.all"),
MsgType: c.String("config.message.type"),
Mobiles: c.String("config.message.at.mobiles"),
Debug: c.Bool("config.debug"),
TipsTitle: c.String("config.tips.title"),
//Lang: c.String("config.lang"),
IsAtALL: c.Bool("config.message.at.all"),
MsgType: c.String("config.message.type"),
Mobiles: c.String("config.message.at.mobiles"),
Debug: c.Bool("config.debug"),
TipsTitle: c.String("config.tips.title"),
},
Custom: Custom{
Pic: Pic{
SuccessPicURL: c.String("custom.pic.url.success"),
FailurePicURL: c.String("custom.pic.url.failure"),
Extra: Extra{
Pic: ExtraPic{
WithPic: c.Bool("config.message.pic"),
SuccessPicURL: c.String("config.success.pic.url"),
FailurePicURL: c.String("config.failure.pic.url"),
},
Color: Color{
SuccessColor: c.String("custom.color.success"),
FailureColor: c.String("custom.color.failure"),
},
Tpl: c.String("custom.tpl"),
Consuming: Consuming{
StartedEnv: c.String("custom.started"),
FinishedEnv: c.String("custom.finished"),
},
},
Tpl: Tpl{
Repo: TplRepo{
FullName: c.String("tpl.repo.full.name"),
ShortName: c.String("tpl.repo.short.name"),
},
Commit: TplCommit{
Branch: c.String("tpl.commit.branch.name"),
},
Build: TplBuild{
Status: Status{
Success: c.String("tpl.build.status.success"),
Failure: c.String("tpl.build.status.failure"),
},
Color: ExtraColor{
SuccessColor: c.String("config.success.color"),
FailureColor: c.String("config.failure.color"),
WithColor: c.Bool("config.message.color"),
},
LinkSha: c.Bool("config.message.sha.link"),
},
}
if err := plugin.Exec(); nil != err {
fmt.Println(err)
os.Exit(1)
}
}
+133 -285
View File
@@ -3,74 +3,51 @@ package main
import (
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"regexp"
"strconv"
"strings"
webhook "github.com/lddsb/dingtalk-webhook"
)
type (
// Repo repo base info
// Repo `repo base info`
Repo struct {
ShortName string // short name
GroupName string // group name
FullName string // repository full name
OwnerName string // repo owner
RemoteURL string // repo remote url
FullName string // repository full name
}
// Build build info
// Build `build info`
Build struct {
Status string // providers the current build status
Link string // providers the current build link
Event string // trigger event
StartAt uint64 // build start at ( unix timestamp )
FinishedAt uint64 // build finish at ( unix timestamp )
Status string // providers the current build status
Link string // providers the current build link
}
// Commit commit info
// Commit `commit info`
Commit struct {
Branch string // providers the branch for the current commit
Link string // providers the http link to the current commit in the remote source code management system(e.g.GitHub)
Message string // providers the commit message for the current build
Sha string // providers the commit sha for the current build
Ref string // commit ref
Author CommitAuthor
Authors CommitAuthors
}
// Stage drone stage env
Stage struct {
StartedAt uint64
FinishedAt uint64
// CommitAuthors `commit author info`
CommitAuthors struct {
Avatar string // providers the author avatar for the current commit
Email string // providers the author email for the current commit
Name string // providers the author name for the current commit
}
// CommitAuthor commit author info
CommitAuthor struct {
Avatar string // providers the author avatar for the current commit
Email string // providers the author email for the current commit
Name string // providers the author name for the current commit
Username string // the author username for the current commit
}
// Drone drone info
// Drone `drone info`
Drone struct {
Repo Repo
Build Build
Commit Commit
Stage Stage
}
// Config plugin private config
// Config `plugin private config`
Config struct {
Debug bool
AccessToken string
Secret string
IsAtALL bool
Mobiles string
Username string
@@ -78,12 +55,12 @@ type (
TipsTitle string
}
// MessageConfig DingTalk message struct
// MessageConfig `DingTalk message struct`
MessageConfig struct {
ActionCard ActionCard
}
// ActionCard action card message struct
// ActionCard `action card message struct`
ActionCard struct {
LinkUrls string
LinkTitles string
@@ -91,109 +68,60 @@ type (
BtnOrientation bool
}
// Pic extra config for pic
Pic struct {
// Extra `extra variables`
Extra struct {
Color ExtraColor
Pic ExtraPic
LinkSha bool
}
// ExtraPic `extra config for pic`
ExtraPic struct {
WithPic bool
SuccessPicURL string
FailurePicURL string
}
// Color extra config for color
Color struct {
// ExtraColor `extra config for color`
ExtraColor struct {
WithColor bool
SuccessColor string
FailureColor string
}
// Plugin plugin all config
// Plugin `plugin all config`
Plugin struct {
Tpl Tpl
Drone Drone
Config Config
Custom Custom
Message MessageConfig
}
// Custom user custom env
Custom struct {
Tpl string
Color Color
Pic Pic
Consuming Consuming
}
// Tpl TPL base
Tpl struct {
Repo TplRepo
Commit TplCommit
Build TplBuild
}
// TplRepo TPL repo
TplRepo struct {
FullName string
ShortName string
}
// TplCommit TPL commit
TplCommit struct {
Branch string
}
// TplBuild TPL build
TplBuild struct {
Status Status
}
// Status status
Status struct {
Success string
Failure string
}
// Consuming custom consuming env
Consuming struct {
StartedEnv string
FinishedEnv string
Drone Drone
Config Config
Extra Extra
}
)
// Exec execute WebHook
// Exec `execute webhook`
func (p *Plugin) Exec() error {
if p.Config.Debug {
for _, e := range os.Environ() {
log.Println(e)
}
}
var err error
if "" == p.Config.AccessToken {
msg := "missing DingTalk access token"
if 0 == len(p.Config.AccessToken) {
msg := "missing dingtalk access token"
return errors.New(msg)
}
tpl, err := p.getMessage()
if err != nil {
return err
if 6 > len(p.Drone.Commit.Sha) {
return errors.New("commit sha cannot short than 6")
}
if p.Config.TipsTitle == "" {
p.Config.TipsTitle = "you have a new message"
}
newWebHook := webhook.NewWebHook(p.Config.AccessToken)
// add sign
if "" != p.Config.Secret {
newWebHook.Secret = p.Config.Secret
}
newWebhook := webhook.NewWebHook(p.Config.AccessToken)
mobiles := strings.Split(p.Config.Mobiles, ",")
switch strings.ToLower(p.Config.MsgType) {
case "markdown":
err = newWebHook.SendMarkdownMsg(p.Config.TipsTitle, tpl, p.Config.IsAtALL, mobiles...)
err = newWebhook.SendMarkdownMsg(p.Config.TipsTitle, p.baseTpl(), p.Config.IsAtALL, mobiles...)
case "text":
err = newWebHook.SendTextMsg(tpl, p.Config.IsAtALL, mobiles...)
err = newWebhook.SendTextMsg(p.baseTpl(), p.Config.IsAtALL, mobiles...)
case "link":
err = newWebHook.SendLinkMsg(p.Drone.Build.Status, tpl, p.Drone.Commit.Author.Avatar, p.Drone.Build.Link)
err = newWebhook.SendLinkMsg(p.Drone.Build.Status, p.baseTpl(), p.Drone.Commit.Authors.Avatar, p.Drone.Build.Link)
default:
msg := "not support message type"
err = errors.New(msg)
@@ -206,173 +134,90 @@ func (p *Plugin) Exec() error {
return err
}
// fileExists check file is exists
func fileExists(filePath string) bool {
_, err := os.Stat(filePath)
if err != nil {
if os.IsExist(err) {
return true
}
return false
// markdownTpl `output the tpl of markdown`
func (p *Plugin) markdownTpl() string {
var tpl string
// title
title := fmt.Sprintf(" %s *Branch Build %s*",
strings.Title(p.Drone.Commit.Branch),
strings.Title(p.Drone.Build.Status))
// with color on title
if p.Extra.Color.WithColor {
title = fmt.Sprintf("<font color=%s>%s</font>", p.getColor(), title)
}
return true
tpl = fmt.Sprintf("# %s \n", title)
// with pic
if p.Extra.Pic.WithPic {
tpl += fmt.Sprintf("![%s](%s)\n\n",
p.Drone.Build.Status,
p.getPicURL())
}
// commit message
commitMsg := fmt.Sprintf("%s", p.Drone.Commit.Message)
if p.Extra.Color.WithColor {
commitMsg = fmt.Sprintf("<font color=%s>%s</font>", p.getColor(), commitMsg)
}
tpl += commitMsg + "\n\n"
// sha info
commitSha := p.Drone.Commit.Sha
if p.Extra.LinkSha {
commitSha = fmt.Sprintf("[Click To %s Commit Detail Page](%s)", commitSha[:6], p.Drone.Commit.Link)
}
tpl += commitSha + "\n\n"
// author info
authorInfo := fmt.Sprintf("`%s(%s)`", p.Drone.Commit.Authors.Name, p.Drone.Commit.Authors.Email)
tpl += authorInfo + "\n\n"
// build detail link
buildDetail := fmt.Sprintf("[Click To The Build Detail Page %s](%s)",
p.getEmoticon(),
p.Drone.Build.Link)
tpl += buildDetail
return tpl
}
// getTpl get tpl from local file or remote file
func (p *Plugin) getTpl() (tpl string, err error) {
//var tpl string
tplDir := "/app/drone/dingtalk/message/tpls"
if "" == p.Custom.Tpl {
p.Custom.Tpl = fmt.Sprintf("%s/%s.tpl", tplDir, strings.ToLower(p.Config.MsgType))
}
func (p *Plugin) baseTpl() string {
tpl := ""
switch strings.ToLower(p.Config.MsgType) {
case "markdown":
tpl = p.markdownTpl()
case "text":
tpl = fmt.Sprintf(`[%s] %s
%s (%s)
@%s
%s (%s)
`,
p.Drone.Build.Status,
strings.TrimSpace(p.Drone.Commit.Message),
p.Drone.Repo.FullName,
p.Drone.Commit.Branch,
p.Drone.Commit.Sha,
p.Drone.Commit.Authors.Name,
p.Drone.Commit.Authors.Email)
case "link":
tpl = fmt.Sprintf(`%s(%s) @%s %s(%s)`,
p.Drone.Repo.FullName,
p.Drone.Commit.Branch,
p.Drone.Commit.Sha[:6],
p.Drone.Commit.Authors.Name,
p.Drone.Commit.Authors.Email)
case "actionCard":
// coming soon
u, err := url.Parse(p.Custom.Tpl)
if err != nil {
return "", err
}
if u.Scheme != "" {
resp, err := http.Get(p.Custom.Tpl)
if err != nil {
return "", err
}
// check response
if u.Path != resp.Request.URL.Path {
return "", errors.New("cannot get tpl from url")
}
// defer close
defer func() {
_ = resp.Body.Close()
}()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
tpl = string(body)
} else {
if !fileExists(p.Custom.Tpl) {
return "", errors.New("tpl file not exists")
}
tplStr, err := ioutil.ReadFile(p.Custom.Tpl)
if err != nil {
return "", err
}
tpl = string(tplStr)
}
return tpl, nil
}
// fillTpl fill the tpl by valid keyword
func (p *Plugin) fillTpl(tpl string) string {
envs := p.getEnvs()
// replace regex
reg := regexp.MustCompile(`\[([^\[\]]*)]`)
match := reg.FindAllStringSubmatch(tpl, -1)
for _, m := range match {
// from environment
if envStr := os.Getenv(m[1]); envStr != "" {
tpl = strings.ReplaceAll(tpl, m[0], envStr)
}
// check if the keyword is legal
if _, ok := envs[m[1]]; ok {
// replace keyword
tpl = strings.ReplaceAll(tpl, m[0], envs[m[1]].(string))
}
}
return tpl
}
// getEnvs get available envs
func (p *Plugin) getEnvs() map[string]interface{} {
var envs map[string]interface{}
envs = make(map[string]interface{})
envs["TPL_REPO_FULL_NAME"] = p.Drone.Repo.FullName
if p.Tpl.Repo.FullName != "" {
envs["TPL_REPO_FULL_NAME"] = p.Tpl.Repo.FullName
}
envs["TPL_REPO_SHORT_NAME"] = p.Drone.Repo.ShortName
if p.Tpl.Repo.ShortName != "" {
envs["TPL_REPO_SHORT_NAME"] = p.Tpl.Repo.ShortName
}
envs["TPL_REPO_GROUP_NAME"] = p.Drone.Repo.GroupName
envs["TPL_REPO_OWNER_NAME"] = p.Drone.Repo.OwnerName
envs["TPL_REPO_REMOTE_URL"] = p.Drone.Repo.RemoteURL
envs["TPL_BUILD_STATUS"] = p.getStatus()
envs["TPL_BUILD_LINK"] = p.Drone.Build.Link
envs["TPL_BUILD_EVENT"] = p.Drone.Build.Event
var consuming uint64
// custom consuming env
if p.Custom.Consuming.FinishedEnv != "" && p.Custom.Consuming.StartedEnv != "" {
finishedAt, _ := strconv.ParseUint(os.Getenv(p.Custom.Consuming.FinishedEnv), 10, 64)
startedAt, _ := strconv.ParseUint(os.Getenv(p.Custom.Consuming.StartedEnv), 10, 64)
consuming = finishedAt - startedAt
} else {
consuming = p.Drone.Build.FinishedAt - p.Drone.Build.StartAt
if consuming == 0 {
consuming = p.Drone.Stage.FinishedAt - p.Drone.Stage.StartedAt
}
}
envs["TPL_BUILD_CONSUMING"] = fmt.Sprintf("%v", consuming)
envs["TPL_COMMIT_SHA"] = p.Drone.Commit.Sha
envs["TPL_COMMIT_REF"] = p.Drone.Commit.Ref
envs["TPL_COMMIT_LINK"] = p.Drone.Commit.Link
envs["TPL_COMMIT_MSG"] = p.Drone.Commit.Message
envs["TPL_COMMIT_BRANCH"] = p.Drone.Commit.Branch
if p.Tpl.Commit.Branch != "" {
envs["TPL_COMMIT_BRANCH"] = p.Tpl.Commit.Branch
}
envs["TPL_AUTHOR_NAME"] = p.Drone.Commit.Author.Name
envs["TPL_AUTHOR_USERNAME"] = p.Drone.Commit.Author.Username
envs["TPL_AUTHOR_EMAIL"] = p.Drone.Commit.Author.Email
envs["TPL_AUTHOR_AVATAR"] = p.Drone.Commit.Author.Avatar
envs["TPL_STATUS_PIC"] = p.getPicURL()
envs["TPL_STATUS_COLOR"] = p.getColor()
envs["TPL_STATUS_EMOTICON"] = p.getEmoticon()
return envs
}
// getMessage get message tpl
func (p *Plugin) getMessage() (tpl string, err error) {
tpl, err = p.getTpl()
if err != nil {
return "", err
}
return p.fillTpl(tpl), nil
}
// getStatus
func (p *Plugin) getStatus() string {
if p.Drone.Build.Status == "success" {
if p.Tpl.Build.Status.Success != "" {
return p.Tpl.Build.Status.Success
}
return p.Drone.Build.Status
}
if p.Tpl.Build.Status.Failure != "" {
return p.Tpl.Build.Status.Failure
}
return p.Drone.Build.Status
}
// get emoticon
/**
get emoticon
*/
func (p *Plugin) getEmoticon() string {
emoticons := make(map[string]string)
emoticons["success"] = ":)"
@@ -386,41 +231,44 @@ func (p *Plugin) getEmoticon() string {
return ":("
}
// get picture url
/**
get picture url
*/
func (p *Plugin) getPicURL() string {
pics := make(map[string]string)
// success picture url
pics["success"] = "https://wx1.sinaimg.cn/large/006tNc79gy1fz05g5a7utj30he0bfjry.jpg"
if p.Custom.Pic.SuccessPicURL != "" {
pics["success"] = p.Custom.Pic.SuccessPicURL
if p.Extra.Pic.SuccessPicURL != "" {
pics["success"] = p.Extra.Pic.SuccessPicURL
}
// failure picture url
pics["failure"] = "https://wx1.sinaimg.cn/large/006tNc79gy1fz0b4fghpnj30hd0bdmxn.jpg"
if p.Custom.Pic.FailurePicURL != "" {
pics["failure"] = p.Custom.Pic.FailurePicURL
if p.Extra.Pic.FailurePicURL != "" {
pics["failure"] = p.Extra.Pic.FailurePicURL
}
picURL, ok := pics[p.Drone.Build.Status]
url, ok := pics[p.Drone.Build.Status]
if ok {
return picURL
return url
}
return ""
}
// get color for message title
/**
get color for message title
*/
func (p *Plugin) getColor() string {
colors := make(map[string]string)
// success color
colors["success"] = "#008000"
if p.Custom.Color.SuccessColor != "" {
colors["success"] = "#" + p.Custom.Color.SuccessColor
if p.Extra.Color.SuccessColor != "" {
colors["success"] = "#" + p.Extra.Color.SuccessColor
}
// failure color
colors["failure"] = "#FF0000"
if p.Custom.Color.FailureColor != "" {
colors["failure"] = "#" + p.Custom.Color.FailureColor
if p.Extra.Color.FailureColor != "" {
colors["failure"] = "#" + p.Extra.Color.FailureColor
}
color, ok := colors[p.Drone.Build.Status]
+14 -16
View File
@@ -12,45 +12,43 @@ func TestPlugin(t *testing.T) {
}
p.Config.AccessToken = "example-access-token"
p.Custom.Tpl = "tpls/markdown.tpl"
err = p.Exec()
if nil == err {
t.Error("commit sha length error should be catch!")
}
p.Drone.Commit.Sha = "53729847dfksj"
err = p.Exec()
if nil == err {
t.Error("not support message type error should be catch!")
}
p.Config.MsgType = "link"
err = p.Exec()
if nil == err {
t.Error("access token invalid error should be catch!")
}
p.Custom.Tpl = "https://aaa.com"
p.Config.MsgType = "text"
err = p.Exec()
if nil == err {
t.Error("access token invalid error should be catch!")
}
p.Custom.Tpl = ""
p.Config.MsgType = "link"
err = p.Exec()
if nil == err {
t.Error("access token invalid error should be catch!")
}
p.Custom.Color.FailureColor = "#555555"
p.Custom.Color.SuccessColor = "#222222"
p.Custom.Pic.FailurePicURL = "https://www.baidu.com"
p.Custom.Pic.SuccessPicURL = "https://www.baidu.com"
p.Extra.Color.WithColor = true
p.Extra.Color.FailureColor = "#555555"
p.Extra.Color.SuccessColor = "#222222"
p.Extra.Pic.WithPic = true
p.Extra.Pic.FailurePicURL = "https://www.baidu.com"
p.Extra.Pic.SuccessPicURL = "https://www.baidu.com"
p.Extra.LinkSha = true
// p.Drone.Build.Status = "failure"
p.Config.MsgType = "markdown"
p.Custom.Tpl = "tpls/markdown.tpl"
err = p.Exec()
if nil == err {
t.Error("access token invalid error should be catch!")
}
p.Custom.Tpl = "https://gist.githubusercontent.com/lddsb/87065e73678dcf56cd222a3c2f1f32b0/raw/fce9fb28b2c8c768eb93df5598beee8c98cba610/md.tpl"
p.Drone.Build.Status = "failure"
err = p.Exec()
if nil == err {
-9
View File
@@ -1,9 +0,0 @@
### **[CI_PROJECT_TITLE]**'s **[CI_COMMIT_BRANCH]** build **[TPL_BUILD_STATUS]**
Message: [CI_COMMIT_MESSAGE]
Detail: [[CI_COMMIT_SHA]]([CI_PROJECT_URL]/commit/[CI_COMMIT_SHA])
Author: [[GITLAB_USER_NAME]([GITLAB_USER_EMAIL])](mailto:[GITLAB_USER_EMAIL])
[Click To The Build Detail Page [TPL_STATUS_EMOTICON]]([CI_PIPELINE_URL])
-9
View File
@@ -1,9 +0,0 @@
### [TPL_REPO_SHORT_NAME] build [TPL_BUILD_STATUS] (`takes [TPL_BUILD_CONSUMING]s`)
Message: [TPL_COMMIT_MSG]
Detail: [[TPL_COMMIT_SHA]]([TPL_COMMIT_LINK])
Author: [[TPL_AUTHOR_NAME]([TPL_AUTHOR_EMAIL])](mailto:[TPL_AUTHOR_EMAIL])
[Click To The Build Detail Page [TPL_STATUS_EMOTICON]]([TPL_BUILD_LINK])
-5
View File
@@ -1,5 +0,0 @@
[TPL_REPO_NAME] build [TPL_BUILD_STATUS] (takes [TPL_BUILD_CONSUMING]s)
[TPL_COMMIT_MSG]
[TPL_COMMIT_SHA] ([TPL_COMMIT_LINK])
[TPL_AUTHOR_NAME] ([TPL_AUTHOR_EMAIL])
Click To The Build Detail Page [TPL_STATUS_EMOTICON] ([TPL_BUILD_LINK])