parent
2929ff833e
commit
70ca6255f4
@ -0,0 +1,31 @@ |
|||||||
|
build: |
||||||
|
image: golang:1.5 |
||||||
|
environment: |
||||||
|
- GO15VENDOREXPERIMENT=1 |
||||||
|
- GOOS=linux |
||||||
|
- GOARCH=amd64 |
||||||
|
- CGO_ENABLED=0 |
||||||
|
commands: |
||||||
|
- go get |
||||||
|
- go build |
||||||
|
- go test |
||||||
|
|
||||||
|
publish: |
||||||
|
docker: |
||||||
|
username: drone |
||||||
|
password: $$DOCKER_PASS |
||||||
|
email: $$DOCKER_EMAIL |
||||||
|
repo: plugins/drone-github-release |
||||||
|
when: |
||||||
|
branch: master |
||||||
|
|
||||||
|
plugin: |
||||||
|
name: GitHub Release |
||||||
|
desc: Publish files and artifacts to GitHub releases |
||||||
|
type: publish |
||||||
|
image: plugins/drone-github-release |
||||||
|
labels: |
||||||
|
- publish |
||||||
|
- github |
||||||
|
- release |
||||||
|
- dpl |
@ -0,0 +1,17 @@ |
|||||||
|
Use this plugin for publishing files and artifacts to GitHub releases. You |
||||||
|
can override the default configuration with the following parameters: |
||||||
|
|
||||||
|
* `api_key` - GitHub oauth token with public_repo or repo permission |
||||||
|
* `files` - Files to upload to GitHub Release; globs are allowed |
||||||
|
* `base_url` - GitHub base URL; only required for GHE |
||||||
|
* `upload_url` - GitHub upload URL; only required for GHE |
||||||
|
|
||||||
|
Sample configuration: |
||||||
|
|
||||||
|
```yaml |
||||||
|
publish: |
||||||
|
github_release: |
||||||
|
api_key: my_github_api_key |
||||||
|
files: |
||||||
|
- dist/* |
||||||
|
``` |
@ -0,0 +1,10 @@ |
|||||||
|
# Docker image for the Drone GitHub Release plugin |
||||||
|
# |
||||||
|
# cd $GOPATH/src/github.com/drone-plugins/drone-github-release |
||||||
|
# GO15VENDOREXPERIMENT=1 CGO_ENABLED=0 go build -a -tags netgo |
||||||
|
# docker build --rm=true -t plugins/drone-github-release . |
||||||
|
|
||||||
|
FROM alpine:3.2 |
||||||
|
RUN apk add -U ca-certificates git && rm -rf /var/cache/apk/* |
||||||
|
ADD drone-github-release /bin/ |
||||||
|
ENTRYPOINT ["/bin/drone-github-release"] |
@ -1,2 +1,47 @@ |
|||||||
# drone-github-release |
# drone-github-release |
||||||
https://github.com/travis-ci/dpl/blob/master/README.md?#github-releases |
|
||||||
|
Drone plugin for publishing GitHub releases |
||||||
|
|
||||||
|
## Usage |
||||||
|
|
||||||
|
Publish a release: |
||||||
|
|
||||||
|
``` |
||||||
|
./drone-github-release <<EOF |
||||||
|
{ |
||||||
|
"repo": { |
||||||
|
"clone_url": "git://github.com/drone/drone", |
||||||
|
"full_name": "drone/drone", |
||||||
|
"owner": "drone", |
||||||
|
"name": "drone" |
||||||
|
}, |
||||||
|
"build": { |
||||||
|
"event": "tag", |
||||||
|
"branch": "refs/heads/v0.0.1", |
||||||
|
"commit": "8f5d3b2ce38562bedb48b798328f5bb2e4077a2f", |
||||||
|
"ref": "refs/heads/v0.0.1" |
||||||
|
}, |
||||||
|
"workspace": { |
||||||
|
"root": "/drone/src", |
||||||
|
"path": "drone/src/github.com/drone/drone" |
||||||
|
}, |
||||||
|
"vargs": { |
||||||
|
"api_key": "your_api_key", |
||||||
|
"files": [ |
||||||
|
"dist/*.txt", |
||||||
|
"dist/other-file" |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
EOF |
||||||
|
``` |
||||||
|
|
||||||
|
## Docker |
||||||
|
|
||||||
|
Build the Docker container using the `netgo` build tag to eliminate the CGO |
||||||
|
dependency: |
||||||
|
|
||||||
|
``` |
||||||
|
GO15VENDOREXPERIMENT=1 CGO_ENABLED=0 go build -a -tags netgo |
||||||
|
docker build --rm=true -t plugins/drone-github-release . |
||||||
|
``` |
||||||
|
@ -0,0 +1,13 @@ |
|||||||
|
package: github.com/drone-plugins/drone-github-release |
||||||
|
|
||||||
|
import: |
||||||
|
- package: github.com/drone/drone-go |
||||||
|
ref: 085fdbd71700fb1a27fdc60b09689ab92cee8ceb |
||||||
|
- package: github.com/google/go-github |
||||||
|
ref: 47f2593dad1971eec2f0a0971aa007fef5edbc50 |
||||||
|
- package: github.com/google/go-querystring |
||||||
|
ref: 2a60fc2ba6c19de80291203597d752e9ba58e4c0 |
||||||
|
- package: golang.org/x/net |
||||||
|
ref: 4f2fc6c1e69d41baf187332ee08fbd2b296f21ed |
||||||
|
- package: golang.org/x/oauth2 |
||||||
|
ref: 442624c9ec9243441e83b374a9e22ac549b5c51d |
@ -0,0 +1,262 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"net/url" |
||||||
|
"os" |
||||||
|
"path" |
||||||
|
"path/filepath" |
||||||
|
"strings" |
||||||
|
|
||||||
|
"github.com/drone/drone-go/drone" |
||||||
|
"github.com/drone/drone-go/plugin" |
||||||
|
"github.com/google/go-github/github" |
||||||
|
"golang.org/x/oauth2" |
||||||
|
) |
||||||
|
|
||||||
|
type Params struct { |
||||||
|
BaseUrl string `json:"base_url"` |
||||||
|
UploadUrl string `json:"upload_url"` |
||||||
|
APIKey string `json:"api_key"` |
||||||
|
Files []string `json:"files"` |
||||||
|
} |
||||||
|
|
||||||
|
func main() { |
||||||
|
r := drone.Repo{} |
||||||
|
b := drone.Build{} |
||||||
|
w := drone.Workspace{} |
||||||
|
v := Params{} |
||||||
|
|
||||||
|
plugin.Param("repo", &r) |
||||||
|
plugin.Param("build", &b) |
||||||
|
plugin.Param("workspace", &w) |
||||||
|
plugin.Param("vargs", &v) |
||||||
|
|
||||||
|
plugin.MustParse() |
||||||
|
|
||||||
|
if b.Event != "tag" { |
||||||
|
fmt.Printf("The GitHub Release plugin is only available for tags\n") |
||||||
|
os.Exit(0) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if len(v.BaseUrl) == 0 { |
||||||
|
v.BaseUrl = "https://api.github.com/" |
||||||
|
} else { |
||||||
|
if !strings.HasSuffix(v.BaseUrl, "/") { |
||||||
|
v.BaseUrl = v.BaseUrl + "/" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if len(v.UploadUrl) == 0 { |
||||||
|
v.UploadUrl = "https://uploads.github.com/" |
||||||
|
} else { |
||||||
|
if !strings.HasSuffix(v.UploadUrl, "/") { |
||||||
|
v.UploadUrl = v.UploadUrl + "/" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if len(v.APIKey) == 0 { |
||||||
|
fmt.Printf("You must provide an API key\n") |
||||||
|
os.Exit(1) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
files := make([]string, 0) |
||||||
|
|
||||||
|
for _, glob := range v.Files { |
||||||
|
globed, err := filepath.Glob(glob) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
fmt.Printf("Failed to glob %s\n", glob) |
||||||
|
os.Exit(1) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if globed != nil { |
||||||
|
files = append(files, globed...) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
baseUrl, err := url.Parse(v.BaseUrl) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
fmt.Printf("Failed to parse base URL\n") |
||||||
|
os.Exit(1) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
uploadUrl, err := url.Parse(v.UploadUrl) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
fmt.Printf("Failed to parse upload URL\n") |
||||||
|
os.Exit(1) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
ts := oauth2.StaticTokenSource( |
||||||
|
&oauth2.Token{ |
||||||
|
AccessToken: v.APIKey, |
||||||
|
}) |
||||||
|
|
||||||
|
tc := oauth2.NewClient( |
||||||
|
oauth2.NoContext, |
||||||
|
ts) |
||||||
|
|
||||||
|
client := github.NewClient(tc) |
||||||
|
client.BaseURL = baseUrl |
||||||
|
client.UploadURL = uploadUrl |
||||||
|
|
||||||
|
release, releaseErr := retrieveRelease( |
||||||
|
client, |
||||||
|
r.Owner, |
||||||
|
r.Name, |
||||||
|
filepath.Base(b.Ref)) |
||||||
|
|
||||||
|
if releaseErr != nil { |
||||||
|
fmt.Println(releaseErr) |
||||||
|
os.Exit(1) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
uploadErr := appendFiles( |
||||||
|
client, |
||||||
|
r.Owner, |
||||||
|
r.Name, |
||||||
|
*release.ID, |
||||||
|
files) |
||||||
|
|
||||||
|
if uploadErr != nil { |
||||||
|
fmt.Println(uploadErr) |
||||||
|
os.Exit(1) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func prepareRelease(client *github.Client, owner string, repo string, tag string) (*github.RepositoryRelease, error) { |
||||||
|
var release *github.RepositoryRelease |
||||||
|
var releaseErr error |
||||||
|
|
||||||
|
release, releaseErr = retrieveRelease( |
||||||
|
client, |
||||||
|
owner, |
||||||
|
repo, |
||||||
|
tag) |
||||||
|
|
||||||
|
if releaseErr != nil { |
||||||
|
return nil, releaseErr |
||||||
|
} |
||||||
|
|
||||||
|
if release != nil { |
||||||
|
return release, nil |
||||||
|
} |
||||||
|
|
||||||
|
release, releaseErr = createRelease( |
||||||
|
client, |
||||||
|
owner, |
||||||
|
repo, |
||||||
|
tag) |
||||||
|
|
||||||
|
if releaseErr != nil { |
||||||
|
return nil, releaseErr |
||||||
|
} |
||||||
|
|
||||||
|
if release != nil { |
||||||
|
return release, nil |
||||||
|
} |
||||||
|
|
||||||
|
return nil, errors.New( |
||||||
|
"Failed to retrieve or create a release") |
||||||
|
} |
||||||
|
|
||||||
|
func retrieveRelease(client *github.Client, owner string, repo string, tag string) (*github.RepositoryRelease, error) { |
||||||
|
release, _, err := client.Repositories.GetReleaseByTag( |
||||||
|
owner, |
||||||
|
repo, |
||||||
|
tag) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
return nil, errors.New( |
||||||
|
"Failed to retrieve release") |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Printf("Successfully retrieved %s release\n", tag) |
||||||
|
return release, nil |
||||||
|
} |
||||||
|
|
||||||
|
func createRelease(client *github.Client, owner string, repo string, tag string) (*github.RepositoryRelease, error) { |
||||||
|
release, _, err := client.Repositories.CreateRelease( |
||||||
|
owner, |
||||||
|
repo, |
||||||
|
&github.RepositoryRelease{TagName: github.String(tag)}) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
return nil, errors.New( |
||||||
|
"Failed to create release") |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Printf("Successfully created %s release\n", tag) |
||||||
|
return release, nil |
||||||
|
} |
||||||
|
|
||||||
|
func appendFiles(client *github.Client, owner string, repo string, id int, files []string) error { |
||||||
|
assets, _, err := client.Repositories.ListReleaseAssets( |
||||||
|
owner, |
||||||
|
repo, |
||||||
|
id, |
||||||
|
&github.ListOptions{}) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
return errors.New( |
||||||
|
"Failed to fetch existing assets") |
||||||
|
} |
||||||
|
|
||||||
|
for _, file := range files { |
||||||
|
handle, err := os.Open(file) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
return errors.New( |
||||||
|
fmt.Sprintf("Failed to read %s artifact", file)) |
||||||
|
} |
||||||
|
|
||||||
|
for _, asset := range assets { |
||||||
|
if *asset.Name == path.Base(file) { |
||||||
|
_, deleteErr := client.Repositories.DeleteReleaseAsset( |
||||||
|
owner, |
||||||
|
repo, |
||||||
|
*asset.ID) |
||||||
|
|
||||||
|
if deleteErr != nil { |
||||||
|
return errors.New( |
||||||
|
fmt.Sprintf("Failed to delete %s artifact", file)) |
||||||
|
} else { |
||||||
|
fmt.Printf("Successfully deleted old %s artifact\n", *asset.Name) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
_, _, uploadErr := client.Repositories.UploadReleaseAsset( |
||||||
|
owner, |
||||||
|
repo, |
||||||
|
id, |
||||||
|
&github.UploadOptions{Name: path.Base(file)}, |
||||||
|
handle) |
||||||
|
|
||||||
|
if uploadErr != nil { |
||||||
|
return errors.New( |
||||||
|
fmt.Sprintf("Failed to upload %s artifact", file)) |
||||||
|
} else { |
||||||
|
fmt.Printf("Successfully uploaded %s artifact\n", file) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
Subproject commit 085fdbd71700fb1a27fdc60b09689ab92cee8ceb |
@ -0,0 +1 @@ |
|||||||
|
Subproject commit 47f2593dad1971eec2f0a0971aa007fef5edbc50 |
@ -0,0 +1 @@ |
|||||||
|
Subproject commit 2a60fc2ba6c19de80291203597d752e9ba58e4c0 |
@ -0,0 +1 @@ |
|||||||
|
Subproject commit 4f2fc6c1e69d41baf187332ee08fbd2b296f21ed |
@ -0,0 +1 @@ |
|||||||
|
Subproject commit 442624c9ec9243441e83b374a9e22ac549b5c51d |
Loading…
Reference in new issue