initial project.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
parent
be56cccc0a
commit
56feed0dab
42
.editorconfig
Normal file
42
.editorconfig
Normal file
@ -0,0 +1,42 @@
|
||||
# unifying the coding style for different editors and IDEs => editorconfig.org
|
||||
|
||||
; indicate this is the root of the project
|
||||
root = true
|
||||
|
||||
###########################################################
|
||||
; common
|
||||
###########################################################
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
|
||||
end_of_line = LF
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
###########################################################
|
||||
; make
|
||||
###########################################################
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
[makefile]
|
||||
indent_style = tab
|
||||
|
||||
###########################################################
|
||||
; markdown
|
||||
###########################################################
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
###########################################################
|
||||
; golang
|
||||
###########################################################
|
||||
|
||||
[*.go]
|
||||
indent_style = tab
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -22,3 +22,6 @@ _testmain.go
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
vendor
|
||||
drone-telegram
|
||||
coverage.txt
|
||||
|
53
.travis.yml
Normal file
53
.travis.yml
Normal file
@ -0,0 +1,53 @@
|
||||
sudo: required
|
||||
language: go
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
go:
|
||||
- 1.5.4
|
||||
- 1.6.3
|
||||
- 1.7.1
|
||||
- tip
|
||||
|
||||
env:
|
||||
global:
|
||||
- DOCKER_CACHE_FILE=${HOME}/docker/cache.tar.gz
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
- ${HOME}/.glide
|
||||
- ${HOME}/docker
|
||||
|
||||
before_install:
|
||||
- mkdir -p $GOPATH/bin
|
||||
- curl https://glide.sh/get | sh
|
||||
- if [ -f ${DOCKER_CACHE_FILE} ]; then gunzip -c ${DOCKER_CACHE_FILE} | docker load; fi
|
||||
|
||||
install:
|
||||
- export GO15VENDOREXPERIMENT=1
|
||||
- make install
|
||||
|
||||
script:
|
||||
- make test
|
||||
- make docker
|
||||
- if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
||||
mkdir -p $(dirname ${DOCKER_CACHE_FILE});
|
||||
docker save $(docker history -q $TRAVIS_REPO_SLUG:latest | grep -v '<missing>') | gzip > ${DOCKER_CACHE_FILE};
|
||||
fi
|
||||
|
||||
after_success:
|
||||
# ignore main.go coverage
|
||||
- sed -i '/main.go/d' coverage.txt
|
||||
- bash <(curl -s https://codecov.io/bash) -f coverage.txt
|
||||
# deploy from master
|
||||
- if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_GO_VERSION" == "1.7.1" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
||||
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD";
|
||||
make docker_deploy tag=latest;
|
||||
fi
|
||||
# deploy from tag
|
||||
- if [ "$TRAVIS_GO_VERSION" == "1.7.1" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then
|
||||
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD";
|
||||
make docker_deploy tag=$TRAVIS_TAG;
|
||||
fi
|
5
Dockerfile
Normal file
5
Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM centurylink/ca-certs
|
||||
|
||||
ADD drone-telegram /
|
||||
|
||||
ENTRYPOINT ["/drone-telegram"]
|
8
Dockerfile.armhf
Normal file
8
Dockerfile.armhf
Normal file
@ -0,0 +1,8 @@
|
||||
FROM armhfbuild/alpine:3.4
|
||||
|
||||
RUN apk update && \
|
||||
apk add ca-certificates && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
ADD drone-telegram /bin/
|
||||
ENTRYPOINT ["/bin/drone-telegram"]
|
45
Makefile
Normal file
45
Makefile
Normal file
@ -0,0 +1,45 @@
|
||||
.PHONY:
|
||||
|
||||
VERSION := $(shell git describe --tags || git rev-parse --short HEAD)
|
||||
DEPLOY_ACCOUNT := "appleboy"
|
||||
DEPLOY_IMAGE := "drone-telegram"
|
||||
|
||||
ifneq ($(shell uname), Darwin)
|
||||
EXTLDFLAGS = -extldflags "-static" $(null)
|
||||
else
|
||||
EXTLDFLAGS =
|
||||
endif
|
||||
|
||||
install:
|
||||
glide install
|
||||
|
||||
build:
|
||||
go build -ldflags="$(EXTLDFLAGS)-s -w -X main.Version=$(VERSION)"
|
||||
|
||||
test:
|
||||
go test -v -coverprofile=coverage.txt
|
||||
|
||||
html:
|
||||
go tool cover -html=coverage.txt
|
||||
|
||||
update:
|
||||
glide up
|
||||
|
||||
docker_build:
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo -ldflags="-X main.Version=$(VERSION)"
|
||||
|
||||
docker_image:
|
||||
docker build --rm -t $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE) .
|
||||
|
||||
docker: docker_build docker_image
|
||||
|
||||
docker_deploy:
|
||||
ifeq ($(tag),)
|
||||
@echo "Usage: make $@ tag=<tag>"
|
||||
@exit 1
|
||||
endif
|
||||
docker tag $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):latest $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):$(tag)
|
||||
docker push $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):$(tag)
|
||||
|
||||
clean:
|
||||
rm -rf coverage.txt ${DEPLOY_IMAGE}
|
57
README.md
Normal file
57
README.md
Normal file
@ -0,0 +1,57 @@
|
||||
# drone-telegram
|
||||
|
||||
[![Build Status](https://travis-ci.org/appleboy/drone-telegram.svg?branch=master)](https://travis-ci.org/appleboy/drone-telegram) [![codecov](https://codecov.io/gh/appleboy/drone-telegram/branch/master/graph/badge.svg)](https://codecov.io/gh/appleboy/drone-telegram) [![Go Report Card](https://goreportcard.com/badge/github.com/appleboy/drone-telegram)](https://goreportcard.com/report/github.com/appleboy/drone-telegram)
|
||||
|
||||
Drone plugin for sending telegram notifications.
|
||||
|
||||
## Build
|
||||
|
||||
Build the binary with the following commands:
|
||||
|
||||
```
|
||||
$ make build
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Test the package with the following command:
|
||||
|
||||
```
|
||||
$ make test
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
Build the docker image with the following commands:
|
||||
|
||||
```
|
||||
$ make docker
|
||||
```
|
||||
|
||||
Please note incorrectly building the image for the correct x64 linux and with
|
||||
GCO disabled will result in an error when running the Docker image:
|
||||
|
||||
```
|
||||
docker: Error response from daemon: Container command
|
||||
'/bin/drone-telegram' not found or does not exist..
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Execute from the working directory:
|
||||
|
||||
```
|
||||
docker run --rm \
|
||||
-e PLUGIN_TOKEN=xxxxxxx \
|
||||
-e PLUGIN_TO=xxxxxxx \
|
||||
-e PLUGIN_MESSAGE=test \
|
||||
-e DRONE_REPO_OWNER=appleboy \
|
||||
-e DRONE_REPO_NAME=go-hello \
|
||||
-e DRONE_COMMIT_SHA=e5e82b5eb3737205c25955dcc3dcacc839b7be52 \
|
||||
-e DRONE_COMMIT_BRANCH=master \
|
||||
-e DRONE_COMMIT_AUTHOR=appleboy \
|
||||
-e DRONE_BUILD_NUMBER=1 \
|
||||
-e DRONE_BUILD_STATUS=success \
|
||||
-e DRONE_BUILD_LINK=http://github.com/appleboy/go-hello \
|
||||
appleboy/drone-telegram
|
||||
```
|
11
glide.yaml
Normal file
11
glide.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
package: github.com/appleboy/drone-telegram
|
||||
import:
|
||||
- package: github.com/joho/godotenv
|
||||
subpackages:
|
||||
- autoload
|
||||
- package: github.com/urfave/cli
|
||||
- package: gopkg.in/telegram-bot-api.v4
|
||||
testImport:
|
||||
- package: github.com/stretchr/testify
|
||||
subpackages:
|
||||
- assert
|
116
main.go
Normal file
116
main.go
Normal file
@ -0,0 +1,116 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Version for command line
|
||||
var Version string
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
app.Name = "telegram plugin"
|
||||
app.Usage = "telegram plugin"
|
||||
app.Action = run
|
||||
app.Version = Version
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "telegram.token",
|
||||
Usage: "telegram token",
|
||||
EnvVar: "PLUGIN_TELEGRAM_TOKEN,TELEGRAM_TOKEN",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "to",
|
||||
Usage: "send message to user",
|
||||
EnvVar: "PLUGIN_TO",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "message",
|
||||
Usage: "send telegram message",
|
||||
EnvVar: "PLUGIN_MESSAGE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo.owner",
|
||||
Usage: "repository owner",
|
||||
EnvVar: "DRONE_REPO_OWNER",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo.name",
|
||||
Usage: "repository name",
|
||||
EnvVar: "DRONE_REPO_NAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit.sha",
|
||||
Usage: "git commit sha",
|
||||
EnvVar: "DRONE_COMMIT_SHA",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit.branch",
|
||||
Value: "master",
|
||||
Usage: "git commit branch",
|
||||
EnvVar: "DRONE_COMMIT_BRANCH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit.author",
|
||||
Usage: "git author name",
|
||||
EnvVar: "DRONE_COMMIT_AUTHOR",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit.message",
|
||||
Usage: "commit message",
|
||||
EnvVar: "DRONE_COMMIT_MESSAGE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.event",
|
||||
Value: "push",
|
||||
Usage: "build event",
|
||||
EnvVar: "DRONE_BUILD_EVENT",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "build.number",
|
||||
Usage: "build number",
|
||||
EnvVar: "DRONE_BUILD_NUMBER",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.status",
|
||||
Usage: "build status",
|
||||
Value: "success",
|
||||
EnvVar: "DRONE_BUILD_STATUS",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.link",
|
||||
Usage: "build link",
|
||||
EnvVar: "DRONE_BUILD_LINK",
|
||||
},
|
||||
}
|
||||
app.Run(os.Args)
|
||||
}
|
||||
|
||||
func run(c *cli.Context) error {
|
||||
plugin := Plugin{
|
||||
Repo: Repo{
|
||||
Owner: c.String("repo.owner"),
|
||||
Name: c.String("repo.name"),
|
||||
},
|
||||
Build: Build{
|
||||
Number: c.Int("build.number"),
|
||||
Event: c.String("build.event"),
|
||||
Status: c.String("build.status"),
|
||||
Commit: c.String("commit.sha"),
|
||||
Branch: c.String("commit.branch"),
|
||||
Author: c.String("commit.author"),
|
||||
Message: c.String("commit.message"),
|
||||
Link: c.String("build.link"),
|
||||
},
|
||||
Config: Config{
|
||||
Token: c.String("telegram.token"),
|
||||
To: c.StringSlice("to"),
|
||||
Message: c.StringSlice("message"),
|
||||
},
|
||||
}
|
||||
|
||||
return plugin.Exec()
|
||||
}
|
125
plugin.go
Normal file
125
plugin.go
Normal file
@ -0,0 +1,125 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/telegram-bot-api.v4"
|
||||
)
|
||||
|
||||
type (
|
||||
// Repo information.
|
||||
Repo struct {
|
||||
Owner string
|
||||
Name string
|
||||
}
|
||||
|
||||
// Build information.
|
||||
Build struct {
|
||||
Event string
|
||||
Number int
|
||||
Commit string
|
||||
Message string
|
||||
Branch string
|
||||
Author string
|
||||
Status string
|
||||
Link string
|
||||
}
|
||||
|
||||
// Config for the plugin.
|
||||
Config struct {
|
||||
Token string
|
||||
To []string
|
||||
Message []string
|
||||
}
|
||||
|
||||
// Plugin values.
|
||||
Plugin struct {
|
||||
Repo Repo
|
||||
Build Build
|
||||
Config Config
|
||||
}
|
||||
)
|
||||
|
||||
func trimElement(keys []string) []string {
|
||||
var newKeys []string
|
||||
|
||||
for _, value := range keys {
|
||||
value = strings.Trim(value, " ")
|
||||
if len(value) == 0 {
|
||||
continue
|
||||
}
|
||||
newKeys = append(newKeys, value)
|
||||
}
|
||||
|
||||
return newKeys
|
||||
}
|
||||
|
||||
func parseID(keys []string) []int64 {
|
||||
var newKeys []int64
|
||||
|
||||
for _, value := range keys {
|
||||
id, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
|
||||
continue
|
||||
}
|
||||
newKeys = append(newKeys, id)
|
||||
}
|
||||
|
||||
return newKeys
|
||||
}
|
||||
|
||||
// Exec executes the plugin.
|
||||
func (p Plugin) Exec() error {
|
||||
|
||||
if len(p.Config.Token) == 0 || len(p.Config.To) == 0 {
|
||||
log.Println("missing telegram token or user list")
|
||||
|
||||
return errors.New("missing telegram token or user list")
|
||||
}
|
||||
|
||||
var message []string
|
||||
if len(p.Config.Message) > 0 {
|
||||
message = p.Config.Message
|
||||
} else {
|
||||
message = p.Message(p.Repo, p.Build)
|
||||
}
|
||||
|
||||
bot, err := tgbotapi.NewBotAPI("219364688:AAETlB6U1OZGnadM6-pLC1QUiXdeHlPUu1E")
|
||||
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
bot.Debug = true
|
||||
|
||||
// parse ids
|
||||
ids := parseID(p.Config.To)
|
||||
|
||||
// send message.
|
||||
for _, user := range ids {
|
||||
for _, value := range trimElement(message) {
|
||||
msg := tgbotapi.NewMessage(user, value)
|
||||
bot.Send(msg)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Message is plugin default message.
|
||||
func (p Plugin) Message(repo Repo, build Build) []string {
|
||||
return []string{fmt.Sprintf("[%s] <%s> (%s)『%s』by %s",
|
||||
build.Status,
|
||||
build.Link,
|
||||
build.Branch,
|
||||
build.Message,
|
||||
build.Author,
|
||||
)}
|
||||
}
|
111
plugin_test.go
Normal file
111
plugin_test.go
Normal file
@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMissingDefaultConfig(t *testing.T) {
|
||||
var plugin Plugin
|
||||
|
||||
err := plugin.Exec()
|
||||
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestMissingUserConfig(t *testing.T) {
|
||||
plugin := Plugin{
|
||||
Config: Config{
|
||||
Token: "123456789",
|
||||
},
|
||||
}
|
||||
|
||||
err := plugin.Exec()
|
||||
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestDefaultMessageFormat(t *testing.T) {
|
||||
plugin := Plugin{
|
||||
Repo: Repo{
|
||||
Name: "go-hello",
|
||||
Owner: "appleboy",
|
||||
},
|
||||
Build: Build{
|
||||
Number: 101,
|
||||
Status: "success",
|
||||
Link: "https://github.com/appleboy/go-hello",
|
||||
Author: "Bo-Yi Wu",
|
||||
Branch: "master",
|
||||
Message: "update travis",
|
||||
Commit: "e7c4f0a63ceeb42a39ac7806f7b51f3f0d204fd2",
|
||||
},
|
||||
}
|
||||
|
||||
message := plugin.Message(plugin.Repo, plugin.Build)
|
||||
|
||||
assert.Equal(t, []string{"[success] <https://github.com/appleboy/go-hello> (master)『update travis』by Bo-Yi Wu"}, message)
|
||||
}
|
||||
|
||||
func TestSendMessage(t *testing.T) {
|
||||
plugin := Plugin{
|
||||
Repo: Repo{
|
||||
Name: "go-hello",
|
||||
Owner: "appleboy",
|
||||
},
|
||||
Build: Build{
|
||||
Number: 101,
|
||||
Status: "success",
|
||||
Link: "https://github.com/appleboy/go-hello",
|
||||
Author: "Bo-Yi Wu",
|
||||
Branch: "master",
|
||||
Message: "update travis by drone plugin",
|
||||
Commit: "e7c4f0a63ceeb42a39ac7806f7b51f3f0d204fd2",
|
||||
},
|
||||
|
||||
Config: Config{
|
||||
Token: os.Getenv("TELEGRAM_TOKEN"),
|
||||
To: []string{os.Getenv("TELEGRAM_TO"), "中文ID", "1234567890"},
|
||||
Message: []string{"Test Telegram Chat Bot From Travis or Local", " "},
|
||||
},
|
||||
}
|
||||
|
||||
err := plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
|
||||
// disable message
|
||||
plugin.Config.Message = []string{}
|
||||
err = plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestTrimElement(t *testing.T) {
|
||||
var input, result []string
|
||||
|
||||
input = []string{"1", " ", "3"}
|
||||
result = []string{"1", "3"}
|
||||
|
||||
assert.Equal(t, result, trimElement(input))
|
||||
|
||||
input = []string{"1", "2"}
|
||||
result = []string{"1", "2"}
|
||||
|
||||
assert.Equal(t, result, trimElement(input))
|
||||
}
|
||||
|
||||
func TestParseID(t *testing.T) {
|
||||
var input []string
|
||||
var result []int64
|
||||
|
||||
input = []string{"1", "測試", "3"}
|
||||
result = []int64{int64(1), int64(3)}
|
||||
|
||||
assert.Equal(t, result, parseID(input))
|
||||
|
||||
input = []string{"1", "2"}
|
||||
result = []int64{int64(1), int64(2)}
|
||||
|
||||
assert.Equal(t, result, parseID(input))
|
||||
}
|
Loading…
Reference in New Issue
Block a user