initial file

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
Bo-Yi Wu
2016-10-15 13:30:34 +08:00
parent 7f7e7cf12c
commit 74735d5fa4
11 changed files with 716 additions and 2 deletions
+42
View 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
View File
@@ -22,3 +22,6 @@ _testmain.go
*.exe
*.test
*.prof
vendor
drone-telegram
coverage.txt
+53
View 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
View File
@@ -0,0 +1,5 @@
FROM centurylink/ca-certs
ADD drone-jenkins /
ENTRYPOINT ["/drone-jenkins"]
+8
View 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"]
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 Bo-Yi Wu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+45
View File
@@ -0,0 +1,45 @@
.PHONY: install build test html update docker_build docker_image docker_deploy clean
VERSION := $(shell git describe --tags || git rev-parse --short HEAD)
DEPLOY_ACCOUNT := "appleboy"
DEPLOY_IMAGE := "drone-jenkins"
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}
+81 -2
View File
@@ -1,2 +1,81 @@
# drone-jenkins
Trigger jenkins jobs from Drone CI
# 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](https://github.com/drone/drone) plugin for sending telegram notifications.
## Feature
* [x] Send with Text Message. (`markdown` or `html` format)
* [x] Send with New Photo.
* [x] Send with New Document.
* [x] Send with New Audio.
* [x] Send with New Voice.
* [x] Send with New Location.
* [x] Send with New Venue.
* [x] Send with New Video.
* [x] Send with New Sticker.
## 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 PLUGIN_PHOTO=tests/github.png \
-e PLUGIN_DOCUMENT=tests/gophercolor.png \
-e PLUGIN_STICKER=tests/github-logo.png \
-e PLUGIN_AUDIO=tests/audio.mp3 \
-e PLUGIN_VOICE=tests/voice.ogg \
-e PLUGIN_LOCATION=24.9163213,121.1424972 \
-e PLUGIN_VENUE=24.9163213,121.1424972,title,address \
-e PLUGIN_VIDEO=tests/video.mp4 \
-e PLUGIN_DEBUG=true \
-e PLUGIN_FORMAT=markdown \
-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 \
-v $(pwd):$(pwd) \
-w $(pwd) \
appleboy/drone-telegram
```
+172
View File
@@ -0,0 +1,172 @@
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: "base.url",
Usage: "jenkins base url",
EnvVar: "PLUGIN_BASE_URL,JENKINS_BASE_URL",
},
cli.StringFlag{
Name: "token",
Usage: "jenkins token",
EnvVar: "PLUGIN_TOKEN,JENKINS_TOKEN",
},
cli.StringSliceFlag{
Name: "to",
Usage: "telegram user",
EnvVar: "PLUGIN_TO",
},
cli.StringSliceFlag{
Name: "message",
Usage: "send telegram message",
EnvVar: "PLUGIN_MESSAGE",
},
cli.StringSliceFlag{
Name: "photo",
Usage: "send photo message",
EnvVar: "PLUGIN_PHOTO",
},
cli.StringSliceFlag{
Name: "document",
Usage: "send document message",
EnvVar: "PLUGIN_DOCUMENT",
},
cli.StringSliceFlag{
Name: "sticker",
Usage: "send sticker message",
EnvVar: "PLUGIN_STICKER",
},
cli.StringSliceFlag{
Name: "audio",
Usage: "send audio message",
EnvVar: "PLUGIN_AUDIO",
},
cli.StringSliceFlag{
Name: "voice",
Usage: "send voice message",
EnvVar: "PLUGIN_VOICE",
},
cli.StringSliceFlag{
Name: "location",
Usage: "send location message",
EnvVar: "PLUGIN_LOCATION",
},
cli.StringSliceFlag{
Name: "venue",
Usage: "send venue message",
EnvVar: "PLUGIN_VENUE",
},
cli.StringSliceFlag{
Name: "video",
Usage: "send video message",
EnvVar: "PLUGIN_VIDEO",
},
cli.BoolFlag{
Name: "debug",
Usage: "enable debug message",
EnvVar: "PLUGIN_DEBUG",
},
cli.StringFlag{
Name: "format",
Value: "markdown",
Usage: "telegram message format",
EnvVar: "PLUGIN_FORMAT",
},
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{
URL: c.String("base.url"),
Token: c.String("token"),
Job: c.StringSlice("job"),
},
}
return plugin.Exec()
}
+72
View File
@@ -0,0 +1,72 @@
package main
import (
"errors"
"fmt"
"log"
"os"
"strconv"
"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 {
URL string
Token string
Job []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
}
// Exec executes the plugin.
func (p Plugin) Exec() error {
if len(p.Config.Token) == 0 || len(p.Config.To) == 0 {
log.Println("missing jenkins auth config")
return errors.New("missing jenkins auth config")
}
return nil
}
+214
View File
@@ -0,0 +1,214 @@
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", " "},
Photo: []string{"tests/github.png", "1234", " "},
Document: []string{"tests/gophercolor.png", "1234", " "},
Sticker: []string{"tests/github-logo.png", "tests/github.png", "1234", " "},
Audio: []string{"tests/audio.mp3", "1234", " "},
Voice: []string{"tests/voice.ogg", "1234", " "},
Location: []string{"24.9163213,121.1424972", "1", " "},
Venue: []string{"35.661777,139.704051,竹北體育館,新竹縣竹北市", "24.9163213,121.1424972", "1", " "},
Video: []string{"tests/video.mp4", "1234", " "},
Debug: false,
},
}
err := plugin.Exec()
assert.Nil(t, err)
// disable message
plugin.Config.Message = []string{}
err = plugin.Exec()
assert.Nil(t, err)
}
func TestBotError(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: "appleboy",
To: []string{os.Getenv("TELEGRAM_TO"), "中文ID", "1234567890"},
Message: []string{"Test Telegram Chat Bot From Travis or Local", " "},
},
}
err := plugin.Exec()
assert.NotNil(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))
}
func TestCheckFileExist(t *testing.T) {
var input []string
var result []string
input = []string{"tests/gophercolor.png", "測試", "3"}
result = []string{"tests/gophercolor.png"}
assert.Equal(t, result, fileExist(input))
}
func TestConvertLocation(t *testing.T) {
var input string
var result Location
var empty bool
input = "1"
result, empty = convertLocation(input)
assert.Equal(t, true, empty)
assert.Equal(t, Location{}, result)
// strconv.ParseInt: parsing "測試": invalid syntax
input = "測試,139.704051"
result, empty = convertLocation(input)
assert.Equal(t, true, empty)
assert.Equal(t, Location{}, result)
// strconv.ParseInt: parsing "測試": invalid syntax
input = "35.661777,測試"
result, empty = convertLocation(input)
assert.Equal(t, true, empty)
assert.Equal(t, Location{}, result)
input = "35.661777,139.704051"
result, empty = convertLocation(input)
assert.Equal(t, false, empty)
assert.Equal(t, Location{
Latitude: float64(35.661777),
Longitude: float64(139.704051),
}, result)
input = "35.661777,139.704051,title"
result, empty = convertLocation(input)
assert.Equal(t, false, empty)
assert.Equal(t, Location{
Title: "title",
Address: "",
Latitude: float64(35.661777),
Longitude: float64(139.704051),
}, result)
input = "35.661777,139.704051,title,address"
result, empty = convertLocation(input)
assert.Equal(t, false, empty)
assert.Equal(t, Location{
Title: "title",
Address: "address",
Latitude: float64(35.661777),
Longitude: float64(139.704051),
}, result)
}