├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── README.md ├── glide.lock ├── glide.yaml ├── main.go └── main_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | bin/* 2 | /vendor/ 3 | drone-trigger 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | services: 3 | - docker 4 | 5 | env: 6 | global: 7 | - secure: "CwC8kcW+DP1t21R3gFNr3jskcNSre9W7ztstL+fa2R9AE8rkli9VHJ1qajbOjlzsjUOZFR8mGftwHHHKcPbyn0jpLNnFOj3JSmq+DyVpiizQjr+QJyqwhr4OTfzcKSxe9AUFlHu7kHNj5Ccs0sA4cqnp4Zk7Byt8GoKo5OOiFWjS3oLmFRkBhhycLGZ80k98cces600dgm6+1/pnwCc5g/40GSGKsIxX6mT2b6drVxs3yzKejf5HtN8OiBhj+Kh/q9C2cFtYBcQ0llyhQPhaS2qGz2CJsL97322vxoizUPPz9ULlPvQkFynEMBAvO3mqN5+AYnS8UnuZrp+iOP6ouPls//a8OkqwBLGNVi4dn+tuwtfEZiELwa8k73UTfmKdNCtwPT4ROKvC+hXq+xsLlW5PW3U7mIk25XdjHY8sGyUVQ44mG8VR0d8lVZz20WkoIq/Hb/fXwcWb/IFN0M/FVBSNy+XXbM6BOP1zJYG/ovGq67VNVnphkQuYlh2h8tsKHa7bW3JQM9PTJcGiSOrQx5Et60bUVULhkKwfnBSy6LNRsidEIjKuUCSBUCt5MARJnWTGQqXw+o/hGSGRkeiPiGjBNMNfqaUJlCJGlYazikhdElbEeBQBeB3O1sEjQ8RdLQAkut2IiVoQBOUcFSgFFTKMnyrauOVKkUWYCpsY85w=" 8 | 9 | language: go 10 | go: 1.8 11 | 12 | install: 13 | - curl https://glide.sh/get | sh 14 | script: 15 | - glide install 16 | - go test -v -cover 17 | - go vet -x 18 | - mkdir -p bin 19 | - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-X main.Version=${TRAVIS_TAG:-git+${TRAVIS_COMMIT}}" -o bin/drone-trigger_linux_amd64 20 | - GOOS=linux GOARCH=386 CGO_ENABLED=0 go build -ldflags "-X main.Version=${TRAVIS_TAG:-git+${TRAVIS_COMMIT}}" -o bin/drone-trigger_linux_386 21 | - GOOS=linux GOARCH=arm CGO_ENABLED=0 go build -ldflags "-X main.Version=${TRAVIS_TAG:-git+${TRAVIS_COMMIT}}" -o bin/drone-trigger_linux_arm 22 | - GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-X main.Version=${TRAVIS_TAG:-git+${TRAVIS_COMMIT}}" -o bin/drone-trigger_darwin_amd64 23 | - GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-X main.Version=${TRAVIS_TAG:-git+${TRAVIS_COMMIT}}" -o bin/drone-trigger_windows_amd64.exe 24 | - if ([[ ${TRAVIS_BRANCH} == "master" ]] && [[ ${TRAVIS_EVENT_TYPE} == "push" ]]) || [[ -n ${TRAVIS_TAG} ]]; then 25 | docker login -u "ukhomeofficedigital+drone_trigger" -p ${DOCKER_PASSWORD} quay.io; 26 | docker build -t quay.io/ukhomeofficedigital/drone-trigger:${TRAVIS_TAG:-latest} .; 27 | docker push quay.io/ukhomeofficedigital/drone-trigger:${TRAVIS_TAG:-latest}; 28 | fi 29 | deploy: 30 | provider: releases 31 | skip_cleanup: true 32 | api_key: 33 | secure: Z0VPkgJ2TYY2E66Z3Np2CmIOiSb6jfTtKAijmjyP9BNprxQpqpTIGch1RU3tFRj79rab7lOCJ/jUr4F1pOth4JjMWWmhoKLsSEP6KphSgapuh4++TU/9+Qy0hCvOYW5+HP/TozGwFcjEJvD6W3jOZbYh0jbKIFPifXJNraWzKddSaYkww94ZgN/m2sjygO5cOvrvKqwMoBKaKpJWbZ8JMvgBf+jbwtMwbMXMFg4OW4CLMKpRibY7IEQOHHogYV9s+ly32jFyrpFNaP5CMeho6KE3KmJQaYn21mcDSFrBS90xtJGPdJwVbutuPZ04y1J+IypfgIJ7qBxewTRmsxWcn2Ziyg3gwP/bCmVQzOXA8+/ZFaax/WCdbXyzF2kRXlpU23C5lWbtQKO02B657xD6GOs9vB76UjWx9yEpmzV3OwSsqFz0IjMDt6VhjYTtkK30AV2XapykroHgshpug7K7mMdruugU9g6jjRKFyx0ITd6njNFrbBN009DawlRRrOhPoh6dPJ/fu6gbgTyk3AIjKBRlE6U6t97OUiPaLXAAUL/JrHwYvU/PFaNm1kxzvLevqJAIChU2eIViB2tRgdQiEWIyIQEV2KiyoY3w05BscFLB45TiyYkogYaxrvXimFfFx6fXl7Luk1lFNmPqIsH7ttgp+2bagYegNHS1hFGqS00= 34 | file: 35 | - bin/drone-trigger_linux_amd64 36 | - bin/drone-trigger_linux_386 37 | - bin/drone-trigger_linux_arm 38 | - bin/drone-trigger_darwin_amd64 39 | - bin/drone-trigger_windows_amd64.exe 40 | on: 41 | tags: true 42 | repo: UKHomeOffice/drone-trigger 43 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.6 2 | 3 | RUN apk upgrade --no-cache 4 | RUN apk add --no-cache ca-certificates 5 | 6 | COPY bin/drone-trigger_linux_amd64 /bin/drone-trigger 7 | 8 | ENTRYPOINT ["/bin/drone-trigger"] 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Crown Copyright 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # drone-trigger 2 | 3 | **[DEPRECATED - NO LONGER MAINTAINED] With the adoption of Drone V1, either use the Drone [CLI](https://docs.drone.io/cli/install/) or when used in a pipeline step the [drone-downstream](https://github.com/drone-plugins/drone-downstream) plugin offer alternatives to what this tool was offering.** 4 | 5 | [![Build Status](https://travis-ci.org/UKHomeOffice/drone-trigger.svg?branch=master)](https://travis-ci.org/UKHomeOffice/drone-trigger) [![Docker Repository on Quay](https://quay.io/repository/ukhomeofficedigital/drone-trigger/status "Docker Repository on Quay")](https://quay.io/repository/ukhomeofficedigital/drone-trigger) 6 | 7 | Drone plugin for triggering downstream builds with custom parameters 8 | 9 | This plugin allows for triggering remote or local builds. You can specify 10 | various filters, like `tag`, `branch`, `number`, `commit`, etc. It will find an 11 | existing build which matches specified filters and trigger the build restart or 12 | deployment, in addition, custom parameters can also be set. 13 | 14 | ## Build 15 | 16 | Dependencies are located in the vendor directory and managed using 17 | [govendor](https://github.com/kardianos/govendor) cli tool. 18 | 19 | ``` 20 | go test -v -cover 21 | 22 | mkdir -p bin 23 | GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-X main.Version=dev+git" -o bin/drone-trigger_linux_amd64 24 | ``` 25 | 26 | ## Configuration 27 | 28 | The following parameters are used to configure the plugin: 29 | 30 | - `drone_server`: full URL to the drone server, it can be a remote drone server as well 31 | - `drone_token` or `${DRONE_TOKEN}`: drone user secret token. Just create a `DRONE_TOKEN` secret, the plugin will pick it up 32 | - `repo`: git repository in owner/name format 33 | - `status`: build status filter, default is `success` 34 | - `event`: build event type filter. If unset, no event filter will be done 35 | - `deploy_to`: sends a deployment trigger, which also sets a `DRONE_DEPLOY_TO` environment variable in the target job 36 | - `params`: list of custom parameters that will be passed into a build environment as environment variables 37 | - `verbose`: displays a more verbose output 38 | 39 | Only one filter from the below list can be specified. 40 | - `number`: filter by specific build number 41 | - `commit`: filter by long commit sha 42 | - `branch`: filter by branch name 43 | - `tag`: filter by tag name. Please note that event type will be `tag`. 44 | - `deployed-to`: filter by the environment deployed to. Please note that event type will be `deployment`. 45 | 46 | 47 | ### Drone configuration 48 | 49 | ```yaml 50 | pipeline: 51 | build: 52 | image: golang 53 | commands: 54 | - go get -v 55 | - ... 56 | 57 | docker_build: 58 | image: docker:1.11 59 | commands: 60 | - docker login ... 61 | - docker build -t foo/bar:${DRONE_COMMIT_SHA} . 62 | - docker push foo/bar:${DRONE_COMMIT_SHA} 63 | 64 | trigger_deploy: 65 | image: quay.io/ukhomeofficedigital/drone-trigger:latest 66 | drone_server: https://drone.example.com 67 | repo: owner/go-deploy-scripts 68 | branch: master 69 | deploy_to: prod 70 | params: "IMAGE_NAME=foo/bar:${DRONE_COMMIT_SHA},APP_ID=123" 71 | ``` 72 | 73 | 74 | Since drone-trigger can be run as a standalone tool, configuration can be 75 | provided via cli flags and arguments as well as environment variables. 76 | 77 | ```bash 78 | drone-trigger --help 79 | NAME: 80 | drone-trigger - trigger drone builds or deployments 81 | 82 | USAGE: 83 | drone-trigger_linux_amd64 [global options] command [command options] [arguments...] 84 | 85 | COMMANDS: 86 | help, h Shows a list of commands or help for one command 87 | 88 | GLOBAL OPTIONS: 89 | --verbose verbose output [$VERBOSE, $PLUGIN_VERBOSE] 90 | --drone-server URL, -s URL drone server URL [$DRONE_SERVER, $PLUGIN_DRONE_SERVER] 91 | --drone-token TOKEN, -t TOKEN drone auth TOKEN [$DRONE_TOKEN, $PLUGIN_DRONE_TOKEN] 92 | --repo REPO, -r REPO REPO, eg. foo/bar [$REPO, $PLUGIN_REPO] 93 | --commit value, -c value filter by commit sha [$FILTER_COMMIT, $PLUGIN_COMMIT] 94 | --tag value filter by tag [$FILTER_TAG, $PLUGIN_TAG] 95 | --branch value, -b value filter by branch [$FILTER_BRANCH, $PLUGIN_BRANCH] 96 | --status value filter by build status (default: "success") [$FILTER_STATUS, $PLUGIN_STATUS] 97 | --number value filter by build number (default: 0) [$FILTER_NUMBER, $PLUGIN_NUMBER] 98 | --event value filter by trigger event [$FILTER_EVENT, $PLUGIN_EVENT] 99 | --deploy-to value, -d value environment to deploy to, if set a deployment event will be triggered [$DEPLOY_TO, $PLUGIN_DEPLOY_TO] 100 | --param value, -p value custom parameters to include in the trigger in KEY=value format [$PARAMS, $PLUGIN_PARAMS] 101 | --help, -h show help 102 | --version, -v print the version 103 | 104 | ``` 105 | 106 | ## Release process 107 | 108 | Push / Merge to master will produce a docker 109 | [image](https://quay.io/repository/ukhomeofficedigital/drone-trigger?tab=tags) with a tag `latest`. 110 | 111 | To create a new release, just create a new tag off master. 112 | 113 | ## Contributing 114 | 115 | We welcome pull requests. Please check issues and existing PRs before submitting a patch. 116 | 117 | ## Author 118 | 119 | Vaidas Jablonskis [vaijab](https://github.com/vaijab) 120 | 121 | -------------------------------------------------------------------------------- /glide.lock: -------------------------------------------------------------------------------- 1 | hash: 08f5d64a41673a69ea6a656826e57435d7bc90d84175764bc9c063c175605275 2 | updated: 2017-08-07T17:07:33.861320828+03:00 3 | imports: 4 | - name: github.com/drone/drone-go 5 | version: 327c9594f784216a651dbaed30731600e496dd4e 6 | subpackages: 7 | - drone 8 | - name: github.com/golang/protobuf 9 | version: 748d386b5c1ea99658fd69fe9f03991ce86a90c1 10 | subpackages: 11 | - proto 12 | - name: github.com/urfave/cli 13 | version: 0bdeddeeb0f650497d603c4ad7b20cfe685682f6 14 | - name: golang.org/x/net 15 | version: f5079bd7f6f74e23c4d65efa0f4ce14cbd6a3c0f 16 | subpackages: 17 | - context 18 | - context/ctxhttp 19 | - name: golang.org/x/oauth2 20 | version: 96fca6c793ec32f068f97942ae3c7c073810dfc1 21 | subpackages: 22 | - internal 23 | - name: google.golang.org/appengine 24 | version: c5a90ac045b779001847fec87403f5cba090deae 25 | subpackages: 26 | - internal 27 | - internal/base 28 | - internal/datastore 29 | - internal/log 30 | - internal/remote_api 31 | - internal/urlfetch 32 | - urlfetch 33 | testImports: [] 34 | -------------------------------------------------------------------------------- /glide.yaml: -------------------------------------------------------------------------------- 1 | package: github.com/UKHomeOffice/drone-trigger 2 | import: 3 | - package: github.com/drone/drone-go 4 | subpackages: 5 | - drone 6 | - package: github.com/urfave/cli 7 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "os" 8 | "path" 9 | "strconv" 10 | "strings" 11 | 12 | "github.com/drone/drone-go/drone" 13 | "github.com/urfave/cli" 14 | "golang.org/x/oauth2" 15 | ) 16 | 17 | // Version is set at compile time, passing -ldflags "-X main.Version=" 18 | var Version string 19 | 20 | func main() { 21 | app := cli.NewApp() 22 | app.Name = "drone-trigger" 23 | app.Author = "Vaidas Jablonskis " 24 | app.Version = Version 25 | app.Usage = "trigger drone builds or deployments" 26 | 27 | app.Flags = []cli.Flag{ 28 | cli.BoolFlag{ 29 | Name: "verbose", 30 | Usage: "verbose output", 31 | EnvVar: "VERBOSE,PLUGIN_VERBOSE", 32 | }, 33 | cli.StringFlag{ 34 | Name: "drone-server, s", 35 | Usage: "drone server `URL`", 36 | EnvVar: "DRONE_SERVER,PLUGIN_DRONE_SERVER", 37 | }, 38 | cli.StringFlag{ 39 | Name: "drone-token, t", 40 | Usage: "drone auth `TOKEN`", 41 | EnvVar: "DRONE_TOKEN,PLUGIN_DRONE_TOKEN", 42 | }, 43 | cli.StringFlag{ 44 | Name: "repo, r", 45 | Usage: "`REPO`, eg. foo/bar", 46 | EnvVar: "REPO,PLUGIN_REPO", 47 | }, 48 | cli.StringFlag{ 49 | Name: "commit, c", 50 | Usage: "filter by commit sha", 51 | EnvVar: "FILTER_COMMIT,PLUGIN_COMMIT", 52 | }, 53 | cli.StringFlag{ 54 | Name: "tag", 55 | Usage: "filter by tag", 56 | EnvVar: "FILTER_TAG,PLUGIN_TAG", 57 | }, 58 | cli.StringFlag{ 59 | Name: "branch, b", 60 | Usage: "filter by branch", 61 | EnvVar: "FILTER_BRANCH,PLUGIN_BRANCH", 62 | }, 63 | cli.StringFlag{ 64 | Name: "status", 65 | Usage: "filter by build status", 66 | EnvVar: "FILTER_STATUS,PLUGIN_STATUS", 67 | Value: "success", 68 | }, 69 | cli.IntFlag{ 70 | Name: "number", 71 | Usage: "filter by build number", 72 | EnvVar: "FILTER_NUMBER,PLUGIN_NUMBER", 73 | }, 74 | cli.StringFlag{ 75 | Name: "event", 76 | Usage: "filter by trigger event", 77 | EnvVar: "FILTER_EVENT,PLUGIN_EVENT", 78 | }, 79 | cli.StringFlag{ 80 | Name: "deployed-to", 81 | Usage: "filter by environment deployed to", 82 | EnvVar: "FILTER_DEPLOYED_TO,PLUGIN_DEPLOYED_TO", 83 | }, 84 | cli.StringFlag{ 85 | Name: "deploy-to, d", 86 | Usage: "environment to deploy to, if set a deployment event will be triggered", 87 | EnvVar: "DEPLOY_TO,PLUGIN_DEPLOY_TO", 88 | }, 89 | cli.StringSliceFlag{ 90 | Name: "param, p", 91 | Usage: "custom parameters to include in the trigger in KEY=value format", 92 | EnvVar: "PARAMS,PLUGIN_PARAMS", 93 | }, 94 | } 95 | 96 | app.Action = run 97 | app.Run(os.Args) 98 | } 99 | 100 | // Trigger represent drone trigger. 101 | type Trigger struct { 102 | client drone.Client 103 | } 104 | 105 | func newTrigger(ctx *cli.Context) *Trigger { 106 | oauthCfg := &oauth2.Config{} 107 | httpClient := oauthCfg.Client( 108 | context.Background(), 109 | &oauth2.Token{ 110 | AccessToken: ctx.String("drone-token"), 111 | }, 112 | ) 113 | 114 | return &Trigger{ 115 | client: drone.NewClient(ctx.String("drone-server"), httpClient), 116 | } 117 | } 118 | 119 | func run(ctx *cli.Context) error { 120 | // Exit if required flags are not set 121 | if !ctx.IsSet("drone-server") && !isAnyEnvSet("DRONE_SERVER", "PLUGIN_DRONE_SERVER") { 122 | if err := cli.ShowAppHelp(ctx); err != nil { 123 | return cli.NewExitError(err, 1) 124 | } 125 | return cli.NewExitError("error: drone server is not set", 3) 126 | } 127 | if !ctx.IsSet("drone-token") && !isAnyEnvSet("DRONE_TOKEN", "PLUGIN_DRONE_TOKEN") { 128 | if err := cli.ShowAppHelp(ctx); err != nil { 129 | return cli.NewExitError(err, 1) 130 | } 131 | return cli.NewExitError("error: drone token is not set", 3) 132 | } 133 | if !ctx.IsSet("repo") && !isAnyEnvSet("REPO", "PLUGIN_REPO") { 134 | if err := cli.ShowAppHelp(ctx); err != nil { 135 | return cli.NewExitError(err, 1) 136 | } 137 | return cli.NewExitError("error: repo is not set", 3) 138 | } 139 | 140 | loneFilters := 0 141 | 142 | if ctx.IsSet("tag") || isAnyEnvSet("FILTER_TAG", "PLUGIN_TAG") { 143 | loneFilters++ 144 | } 145 | 146 | if ctx.IsSet("branch") || isAnyEnvSet("FILTER_BRANCH", "PLUGIN_BRANCH") { 147 | loneFilters++ 148 | } 149 | 150 | if ctx.IsSet("commit") || isAnyEnvSet("FILTER_COMMIT", "PLUGIN_COMMIT") { 151 | loneFilters++ 152 | } 153 | 154 | if ctx.IsSet("deployed-to") || isAnyEnvSet("FILTER_DEPLOYED_TO", "PLUGIN_DEPLOYED_TO") { 155 | loneFilters++ 156 | } 157 | 158 | if loneFilters > 1 { 159 | return cli.NewExitError("error: tag, branch, commit or deployed-to cannot be set at the same time, pick one filter", 3) 160 | } 161 | 162 | t := newTrigger(ctx) 163 | build, err := t.findBuild(ctx) 164 | if err != nil { 165 | return cli.NewExitError(err.Error(), 1) 166 | } 167 | if build == nil { 168 | return cli.NewExitError("No previous builds found", 1) 169 | } 170 | 171 | params := parsePairs(ctx.StringSlice("param")) 172 | var newBuild *drone.Build 173 | owner, repo, err := parseRepo(ctx.String("repo")) 174 | if err != nil { 175 | return cli.NewExitError(err.Error(), 1) 176 | } 177 | 178 | if ctx.IsSet("deploy-to") || isAnyEnvSet("DEPLOY_TO", "PLUGIN_DEPLOY_TO") { 179 | b, err := t.client.Deploy(owner, repo, build.Number, ctx.String("deploy-to"), params) 180 | if err != nil { 181 | return cli.NewExitError(err.Error(), 1) 182 | } 183 | newBuild = b 184 | } else { 185 | b, err := t.client.BuildStart(owner, repo, build.Number, params) 186 | if err != nil { 187 | return cli.NewExitError(err.Error(), 1) 188 | } 189 | newBuild = b 190 | } 191 | 192 | newBuildURL := path.Join(ctx.String("drone-server"), ctx.String("repo"), strconv.Itoa(newBuild.Number)) 193 | fmt.Fprintf(os.Stderr, "Follow new build status at: %s\n", newBuildURL) 194 | 195 | if ctx.Bool("verbose") { 196 | j, err := json.MarshalIndent(newBuild, "", " ") 197 | if err != nil { 198 | return cli.NewExitError(err.Error(), 1) 199 | } 200 | fmt.Println(string(j)) 201 | } 202 | return nil 203 | } 204 | 205 | // findBuild requests an array of previous repo builds from drone API and finds 206 | // the one that matches given filters 207 | func (t *Trigger) findBuild(ctx *cli.Context) (*drone.Build, error) { 208 | user, repo, err := parseRepo(ctx.String("repo")) 209 | if err != nil { 210 | return nil, err 211 | } 212 | builds, err := t.client.BuildList(user, repo) 213 | if err != nil { 214 | return nil, err 215 | } 216 | for _, b := range builds { 217 | if match(ctx, b) { 218 | return b, nil 219 | } 220 | } 221 | return nil, nil 222 | } 223 | 224 | // match returns true for the first build that matches cli filter flags. 225 | func match(ctx *cli.Context, build *drone.Build) bool { 226 | if ctx.String("status") != build.Status { 227 | return false 228 | } 229 | if ctx.IsSet("event") && ctx.String("event") != build.Event { 230 | return false 231 | } 232 | // Build number always takes precedence 233 | if ctx.IsSet("number") { 234 | if ctx.Int("number") == build.Number { 235 | return true 236 | } 237 | return false 238 | } 239 | if ctx.IsSet("commit") { 240 | if ctx.String("commit") == build.Commit { 241 | return true 242 | } 243 | return false 244 | } 245 | if ctx.IsSet("tag") { 246 | if "refs/tags/"+ctx.String("tag") == build.Ref { 247 | return true 248 | } 249 | return false 250 | } 251 | if ctx.IsSet("deployed-to") { 252 | if ctx.String("deployed-to") == build.Deploy { 253 | return true 254 | } 255 | return false 256 | } 257 | // Matching on branch does not make sense for pull_request events, because 258 | // the branch for PR events is the base branch. 259 | if ctx.IsSet("branch") { 260 | if ctx.String("branch") == build.Branch && build.Event != "pull_request" { 261 | return true 262 | } 263 | return false 264 | } 265 | // Return latest successful build if no specific filters are set 266 | return true 267 | } 268 | 269 | // parseRepo parses a owner/repo string into two parts 270 | func parseRepo(s string) (owner, repo string, err error) { 271 | var parts = strings.Split(s, "/") 272 | if len(parts) != 2 { 273 | err = fmt.Errorf("error: invalid or missing repository. eg octocat/hello-world") 274 | return 275 | } 276 | owner = parts[0] 277 | repo = parts[1] 278 | return 279 | } 280 | 281 | // parsePairs parses an array of KEY=VALUE strings into a map 282 | func parsePairs(p []string) map[string]string { 283 | params := map[string]string{} 284 | for _, i := range p { 285 | parts := strings.Split(i, "=") 286 | if len(parts) != 2 { 287 | continue 288 | } 289 | params[parts[0]] = parts[1] 290 | } 291 | return params 292 | } 293 | 294 | // isAnyEnvSet checks if any of given environment vars is set and returns a boolean 295 | func isAnyEnvSet(vars ...string) bool { 296 | for _, v := range vars { 297 | _, r := os.LookupEnv(v) 298 | if r { 299 | return r 300 | } 301 | } 302 | return false 303 | } 304 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func TestParsePairs(t *testing.T) { 6 | s := []string{"FOO=bar/something:tag", "BAR=", "INVALID"} 7 | p := parsePairs(s) 8 | if p["FOO"] != "bar/something:tag" { 9 | t.Errorf("Wanted %q, got %q.", "bar/something:tag", p["FOO"]) 10 | } 11 | if _, exists := p["BAR"]; !exists { 12 | t.Error("Missing a key with no value. Keys with empty values are also valid.") 13 | } 14 | if _, exists := p["INVALID"]; exists { 15 | t.Error("Keys without an equal sign suffix are invalid.") 16 | } 17 | } 18 | --------------------------------------------------------------------------------