mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 20:01:02 +00:00
migrate almost all CLI commands to core
This commit is contained in:
parent
eaf2d30335
commit
c07e8f1520
34 changed files with 1224 additions and 212 deletions
|
@ -21,4 +21,4 @@ ADD drone/drone /drone
|
||||||
#RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
|
#RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
|
||||||
|
|
||||||
ENTRYPOINT ["/drone"]
|
ENTRYPOINT ["/drone"]
|
||||||
CMD ["daemon"]
|
CMD ["server"]
|
||||||
|
|
|
@ -9,6 +9,43 @@ import (
|
||||||
|
|
||||||
// Client is used to communicate with a Drone server.
|
// Client is used to communicate with a Drone server.
|
||||||
type Client interface {
|
type Client interface {
|
||||||
|
// Self returns the currently authenticated user.
|
||||||
|
Self() (*model.User, error)
|
||||||
|
|
||||||
|
// User returns a user by login.
|
||||||
|
User(string) (*model.User, error)
|
||||||
|
|
||||||
|
// UserList returns a list of all registered users.
|
||||||
|
UserList() ([]*model.User, error)
|
||||||
|
|
||||||
|
// UserPost creates a new user account.
|
||||||
|
UserPost(*model.User) (*model.User, error)
|
||||||
|
|
||||||
|
// UserPatch updates a user account.
|
||||||
|
UserPatch(*model.User) (*model.User, error)
|
||||||
|
|
||||||
|
// UserDel deletes a user account.
|
||||||
|
UserDel(string) error
|
||||||
|
|
||||||
|
// // UserFeed returns the user's activity feed.
|
||||||
|
// UserFeed() ([]*Activity, error)
|
||||||
|
|
||||||
|
// Repo returns a repository by name.
|
||||||
|
Repo(string, string) (*model.Repo, error)
|
||||||
|
|
||||||
|
// RepoList returns a list of all repositories to which
|
||||||
|
// the user has explicit access in the host system.
|
||||||
|
RepoList() ([]*model.Repo, error)
|
||||||
|
|
||||||
|
// RepoPost activates a repository.
|
||||||
|
RepoPost(string, string) (*model.Repo, error)
|
||||||
|
|
||||||
|
// RepoPatch updates a repository.
|
||||||
|
RepoPatch(*model.Repo) (*model.Repo, error)
|
||||||
|
|
||||||
|
// RepoDel deletes a repository.
|
||||||
|
RepoDel(string, string) error
|
||||||
|
|
||||||
// Sign returns a cryptographic signature for the input string.
|
// Sign returns a cryptographic signature for the input string.
|
||||||
Sign(string, string, []byte) ([]byte, error)
|
Sign(string, string, []byte) ([]byte, error)
|
||||||
|
|
||||||
|
@ -18,6 +55,38 @@ type Client interface {
|
||||||
// SecretDel deletes a named repository secret.
|
// SecretDel deletes a named repository secret.
|
||||||
SecretDel(string, string, string) error
|
SecretDel(string, string, string) error
|
||||||
|
|
||||||
|
// Build returns a repository build by number.
|
||||||
|
Build(string, string, int) (*model.Build, error)
|
||||||
|
|
||||||
|
// BuildLast returns the latest repository build by branch.
|
||||||
|
// An empty branch will result in the default branch.
|
||||||
|
BuildLast(string, string, string) (*model.Build, error)
|
||||||
|
|
||||||
|
// BuildList returns a list of recent builds for the
|
||||||
|
// the specified repository.
|
||||||
|
BuildList(string, string) ([]*model.Build, error)
|
||||||
|
|
||||||
|
// BuildStart re-starts a stopped build.
|
||||||
|
BuildStart(string, string, int) (*model.Build, error)
|
||||||
|
|
||||||
|
// BuildStop stops the specified running job for given build.
|
||||||
|
BuildStop(string, string, int, int) error
|
||||||
|
|
||||||
|
// BuildFork re-starts a stopped build with a new build number,
|
||||||
|
// preserving the prior history.
|
||||||
|
BuildFork(string, string, int) (*model.Build, error)
|
||||||
|
|
||||||
|
// BuildLogs returns the build logs for the specified job.
|
||||||
|
BuildLogs(string, string, int, int) (io.ReadCloser, error)
|
||||||
|
|
||||||
|
// Deploy triggers a deployment for an existing build using the
|
||||||
|
// specified target environment.
|
||||||
|
Deploy(string, string, int, string) (*model.Build, error)
|
||||||
|
|
||||||
|
//
|
||||||
|
// queue functions
|
||||||
|
//
|
||||||
|
|
||||||
// Pull pulls work from the server queue.
|
// Pull pulls work from the server queue.
|
||||||
Pull(os, arch string) (*queue.Work, error)
|
Pull(os, arch string) (*queue.Work, error)
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,164 @@ func NewClientTokenTLS(uri, token string, c *tls.Config) Client {
|
||||||
return &client{auther, uri}
|
return &client{auther, uri}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Self returns the currently authenticated user.
|
||||||
|
func (c *client) Self() (*model.User, error) {
|
||||||
|
out := new(model.User)
|
||||||
|
uri := fmt.Sprintf(pathSelf, c.base)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// User returns a user by login.
|
||||||
|
func (c *client) User(login string) (*model.User, error) {
|
||||||
|
out := new(model.User)
|
||||||
|
uri := fmt.Sprintf(pathUser, c.base, login)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserList returns a list of all registered users.
|
||||||
|
func (c *client) UserList() ([]*model.User, error) {
|
||||||
|
var out []*model.User
|
||||||
|
uri := fmt.Sprintf(pathUsers, c.base)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserPost creates a new user account.
|
||||||
|
func (c *client) UserPost(in *model.User) (*model.User, error) {
|
||||||
|
out := new(model.User)
|
||||||
|
uri := fmt.Sprintf(pathUsers, c.base)
|
||||||
|
err := c.post(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserPatch updates a user account.
|
||||||
|
func (c *client) UserPatch(in *model.User) (*model.User, error) {
|
||||||
|
out := new(model.User)
|
||||||
|
uri := fmt.Sprintf(pathUser, c.base, in.Login)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserDel deletes a user account.
|
||||||
|
func (c *client) UserDel(login string) error {
|
||||||
|
uri := fmt.Sprintf(pathUser, c.base, login)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repo returns a repository by name.
|
||||||
|
func (c *client) Repo(owner string, name string) (*model.Repo, error) {
|
||||||
|
out := new(model.Repo)
|
||||||
|
uri := fmt.Sprintf(pathRepo, c.base, owner, name)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoList returns a list of all repositories to which
|
||||||
|
// the user has explicit access in the host system.
|
||||||
|
func (c *client) RepoList() ([]*model.Repo, error) {
|
||||||
|
var out []*model.Repo
|
||||||
|
uri := fmt.Sprintf(pathRepos, c.base)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoPost activates a repository.
|
||||||
|
func (c *client) RepoPost(owner string, name string) (*model.Repo, error) {
|
||||||
|
out := new(model.Repo)
|
||||||
|
uri := fmt.Sprintf(pathRepo, c.base, owner, name)
|
||||||
|
err := c.post(uri, nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoPatch updates a repository.
|
||||||
|
func (c *client) RepoPatch(in *model.Repo) (*model.Repo, error) {
|
||||||
|
out := new(model.Repo)
|
||||||
|
uri := fmt.Sprintf(pathRepo, c.base, in.Owner, in.Name)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoDel deletes a repository.
|
||||||
|
func (c *client) RepoDel(owner, name string) error {
|
||||||
|
uri := fmt.Sprintf(pathRepo, c.base, owner, name)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build returns a repository build by number.
|
||||||
|
func (c *client) Build(owner, name string, num int) (*model.Build, error) {
|
||||||
|
out := new(model.Build)
|
||||||
|
uri := fmt.Sprintf(pathBuild, c.base, owner, name, num)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build returns the latest repository build by branch.
|
||||||
|
func (c *client) BuildLast(owner, name, branch string) (*model.Build, error) {
|
||||||
|
out := new(model.Build)
|
||||||
|
uri := fmt.Sprintf(pathBuild, c.base, owner, name, "latest")
|
||||||
|
if len(branch) != 0 {
|
||||||
|
uri += "?branch=" + branch
|
||||||
|
}
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildList returns a list of recent builds for the
|
||||||
|
// the specified repository.
|
||||||
|
func (c *client) BuildList(owner, name string) ([]*model.Build, error) {
|
||||||
|
var out []*model.Build
|
||||||
|
uri := fmt.Sprintf(pathBuilds, c.base, owner, name)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildStart re-starts a stopped build.
|
||||||
|
func (c *client) BuildStart(owner, name string, num int) (*model.Build, error) {
|
||||||
|
out := new(model.Build)
|
||||||
|
uri := fmt.Sprintf(pathBuild, c.base, owner, name, num)
|
||||||
|
err := c.post(uri, nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildStop cancels the running job.
|
||||||
|
func (c *client) BuildStop(owner, name string, num, job int) error {
|
||||||
|
uri := fmt.Sprintf(pathJob, c.base, owner, name, num, job)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildFork re-starts a stopped build with a new build number,
|
||||||
|
// preserving the prior history.
|
||||||
|
func (c *client) BuildFork(owner, name string, num int) (*model.Build, error) {
|
||||||
|
out := new(model.Build)
|
||||||
|
uri := fmt.Sprintf(pathBuild+"?fork=true", c.base, owner, name, num)
|
||||||
|
err := c.post(uri, nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildLogs returns the build logs for the specified job.
|
||||||
|
func (c *client) BuildLogs(owner, name string, num, job int) (io.ReadCloser, error) {
|
||||||
|
uri := fmt.Sprintf(pathLog, c.base, owner, name, num, job)
|
||||||
|
return stream(c.client, uri, "GET", nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deploy triggers a deployment for an existing build using the
|
||||||
|
// specified target environment.
|
||||||
|
func (c *client) Deploy(owner, name string, num int, env string) (*model.Build, error) {
|
||||||
|
out := new(model.Build)
|
||||||
|
val := url.Values{}
|
||||||
|
val.Set("fork", "true")
|
||||||
|
val.Set("event", "deployment")
|
||||||
|
val.Set("deploy_to", env)
|
||||||
|
uri := fmt.Sprintf(pathBuild+"?"+val.Encode(), c.base, owner, name, num)
|
||||||
|
err := c.post(uri, nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
// SecretPost create or updates a repository secret.
|
// SecretPost create or updates a repository secret.
|
||||||
func (c *client) SecretPost(owner, name string, secret *model.Secret) error {
|
func (c *client) SecretPost(owner, name string, secret *model.Secret) error {
|
||||||
uri := fmt.Sprintf(pathSecrets, c.base, owner, name)
|
uri := fmt.Sprintf(pathSecrets, c.base, owner, name)
|
||||||
|
|
|
@ -90,12 +90,7 @@ func (r *pipeline) run() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
trans := []compiler.Transform{
|
trans := []compiler.Transform{
|
||||||
builtin.NewCloneOp("git", true),
|
builtin.NewCloneOp(w.Repo.Kind, true),
|
||||||
builtin.NewCacheOp(
|
|
||||||
"plugins/cache:latest",
|
|
||||||
"/var/lib/drone/cache/"+w.Repo.FullName,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
builtin.NewSecretOp(w.Build.Event, secrets),
|
builtin.NewSecretOp(w.Build.Event, secrets),
|
||||||
builtin.NewNormalizeOp(r.config.namespace),
|
builtin.NewNormalizeOp(r.config.namespace),
|
||||||
builtin.NewWorkspaceOp("/drone", "/drone/src/github.com/"+w.Repo.FullName),
|
builtin.NewWorkspaceOp("/drone", "/drone/src/github.com/"+w.Repo.FullName),
|
||||||
|
|
15
drone/build.go
Normal file
15
drone/build.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/codegangsta/cli"
|
||||||
|
|
||||||
|
var buildCmd = cli.Command{
|
||||||
|
Name: "build",
|
||||||
|
Usage: "manage builds",
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
buildListCmd,
|
||||||
|
buildLastCmd,
|
||||||
|
buildInfoCmd,
|
||||||
|
buildStopCmd,
|
||||||
|
buildStartCmd,
|
||||||
|
},
|
||||||
|
}
|
66
drone/build_info.go
Normal file
66
drone/build_info.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var buildInfoCmd = cli.Command{
|
||||||
|
Name: "info",
|
||||||
|
Usage: "show build details",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := buildInfo(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplBuildInfo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildInfo(c *cli.Context) error {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
number, err := strconv.Atoi(c.Args().Get(1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
build, err := client.Build(owner, name, number)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tmpl.Execute(os.Stdout, build)
|
||||||
|
}
|
||||||
|
|
||||||
|
// template for build information
|
||||||
|
var tmplBuildInfo = `Number: {{ .Number }}
|
||||||
|
Status: {{ .Status }}
|
||||||
|
Event: {{ .Event }}
|
||||||
|
Commit: {{ .Commit }}
|
||||||
|
Branch: {{ .Branch }}
|
||||||
|
Ref: {{ .Ref }}
|
||||||
|
Message: {{ .Message }}
|
||||||
|
Author: {{ .Author }}
|
||||||
|
`
|
55
drone/build_last.go
Normal file
55
drone/build_last.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var buildLastCmd = cli.Command{
|
||||||
|
Name: "last",
|
||||||
|
Usage: "show latest build details",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := buildLast(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplBuildInfo,
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "branch",
|
||||||
|
Usage: "branch name",
|
||||||
|
Value: "master",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildLast(c *cli.Context) error {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
build, err := client.BuildLast(owner, name, c.String("branch"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tmpl.Execute(os.Stdout, build)
|
||||||
|
}
|
101
drone/build_list.go
Normal file
101
drone/build_list.go
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var buildListCmd = cli.Command{
|
||||||
|
Name: "list",
|
||||||
|
Usage: "show build history",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := buildList(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplBuildList,
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "branch",
|
||||||
|
Usage: "branch filter",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "event",
|
||||||
|
Usage: "event filter",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "status",
|
||||||
|
Usage: "status filter",
|
||||||
|
},
|
||||||
|
cli.IntFlag{
|
||||||
|
Name: "limit",
|
||||||
|
Usage: "limit the list size",
|
||||||
|
Value: 25,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildList(c *cli.Context) error {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
builds, err := client.BuildList(owner, name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
branch := c.String("branch")
|
||||||
|
event := c.String("event")
|
||||||
|
status := c.String("status")
|
||||||
|
limit := c.Int("limit")
|
||||||
|
|
||||||
|
var count int
|
||||||
|
for _, build := range builds {
|
||||||
|
if count >= limit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if branch != "" && build.Branch != branch {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if event != "" && build.Event != event {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if status != "" && build.Status != status {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tmpl.Execute(os.Stdout, build)
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// template for build list information
|
||||||
|
var tmplBuildList = "\x1b[33mBuild #{{ .Number }} \x1b[0m" + `
|
||||||
|
Status: {{ .Status }}
|
||||||
|
Event: {{ .Event }}
|
||||||
|
Commit: {{ .Commit }}
|
||||||
|
Branch: {{ .Branch }}
|
||||||
|
Ref: {{ .Ref }}
|
||||||
|
Author: {{ .Author }} {{ if .Email }}<{{.Email}}>{{ end }}
|
||||||
|
Message: {{ .Message }}
|
||||||
|
`
|
56
drone/build_start.go
Normal file
56
drone/build_start.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/drone/drone/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var buildStartCmd = cli.Command{
|
||||||
|
Name: "start",
|
||||||
|
Usage: "start a build",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := buildStart(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "fork",
|
||||||
|
Usage: "fork the build",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildStart(c *cli.Context) (err error) {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
number, err := strconv.Atoi(c.Args().Get(1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var build *model.Build
|
||||||
|
if c.Bool("fork") {
|
||||||
|
build, err = client.BuildStart(owner, name, number)
|
||||||
|
} else {
|
||||||
|
build, err = client.BuildFork(owner, name, number)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Starting build %s/%s#%d\n", owner, name, build.Number)
|
||||||
|
return nil
|
||||||
|
}
|
48
drone/build_stop.go
Normal file
48
drone/build_stop.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var buildStopCmd = cli.Command{
|
||||||
|
Name: "stop",
|
||||||
|
Usage: "stop a build",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := buildStop(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildStop(c *cli.Context) (err error) {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
number, err := strconv.Atoi(c.Args().Get(1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
job, _ := strconv.Atoi(c.Args().Get(2))
|
||||||
|
if job == 0 {
|
||||||
|
job = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.BuildStop(owner, name, number, job)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Stopping build %s/%s#%d.%d\n", owner, name, number, job)
|
||||||
|
return nil
|
||||||
|
}
|
1
drone/compile.go
Normal file
1
drone/compile.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package main
|
80
drone/deploy.go
Normal file
80
drone/deploy.go
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/drone/drone-go/drone"
|
||||||
|
)
|
||||||
|
|
||||||
|
var deployCmd = cli.Command{
|
||||||
|
Name: "deploy",
|
||||||
|
Usage: "deploy code",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := deploy(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplDeployInfo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func deploy(c *cli.Context) error {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
number, err := strconv.Atoi(c.Args().Get(1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
build, err := client.Build(owner, name, number)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if build.Event == drone.EventPull {
|
||||||
|
return fmt.Errorf("Cannot deploy a pull request")
|
||||||
|
}
|
||||||
|
env := c.Args().Get(2)
|
||||||
|
if env == "" {
|
||||||
|
return fmt.Errorf("Please specify the target environment (ie production)")
|
||||||
|
}
|
||||||
|
|
||||||
|
deploy, err := client.Deploy(owner, name, number, env)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tmpl.Execute(os.Stdout, deploy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// template for deployment information
|
||||||
|
var tmplDeployInfo = `Number: {{ .Number }}
|
||||||
|
Status: {{ .Status }}
|
||||||
|
Commit: {{ .Commit }}
|
||||||
|
Branch: {{ .Branch }}
|
||||||
|
Ref: {{ .Ref }}
|
||||||
|
Message: {{ .Message }}
|
||||||
|
Author: {{ .Author }}
|
||||||
|
Target: {{ .Deploy }}
|
||||||
|
`
|
1
drone/exec.go
Normal file
1
drone/exec.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package main
|
49
drone/info.go
Normal file
49
drone/info.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var infoCmd = cli.Command{
|
||||||
|
Name: "info",
|
||||||
|
Usage: "should information about the current user",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := info(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplUserInfo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func info(c *cli.Context) error {
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := client.Self()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpl.Execute(os.Stdout, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
// template for user information
|
||||||
|
var tmplInfo = `User: {{ .Login }}
|
||||||
|
Email: {{ .Email }}`
|
|
@ -21,22 +21,25 @@ func main() {
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "t, token",
|
Name: "t, token",
|
||||||
Value: "",
|
|
||||||
Usage: "server auth token",
|
Usage: "server auth token",
|
||||||
EnvVar: "DRONE_TOKEN",
|
EnvVar: "DRONE_TOKEN",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "s, server",
|
Name: "s, server",
|
||||||
Value: "",
|
|
||||||
Usage: "server location",
|
Usage: "server location",
|
||||||
EnvVar: "DRONE_SERVER",
|
EnvVar: "DRONE_SERVER",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
agent.AgentCmd,
|
agent.AgentCmd,
|
||||||
DaemonCmd,
|
buildCmd,
|
||||||
SignCmd,
|
deployCmd,
|
||||||
SecretCmd,
|
infoCmd,
|
||||||
|
secretCmd,
|
||||||
|
serverCmd,
|
||||||
|
signCmd,
|
||||||
|
repoCmd,
|
||||||
|
userCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Run(os.Args)
|
app.Run(os.Args)
|
14
drone/repo.go
Normal file
14
drone/repo.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/codegangsta/cli"
|
||||||
|
|
||||||
|
var repoCmd = cli.Command{
|
||||||
|
Name: "repo",
|
||||||
|
Usage: "manage repositories",
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
repoListCmd,
|
||||||
|
repoInfoCmd,
|
||||||
|
repoAddCmd,
|
||||||
|
repoRemoveCmd,
|
||||||
|
},
|
||||||
|
}
|
37
drone/repo_add.go
Normal file
37
drone/repo_add.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var repoAddCmd = cli.Command{
|
||||||
|
Name: "add",
|
||||||
|
Usage: "add a repository",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := repoRemove(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func repoAdd(c *cli.Context) error {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := client.RepoPost(owner, name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Successfully activated repository %s/%s\n", owner, name)
|
||||||
|
return nil
|
||||||
|
}
|
58
drone/repo_info.go
Normal file
58
drone/repo_info.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var repoInfoCmd = cli.Command{
|
||||||
|
Name: "info",
|
||||||
|
Usage: "show repository details",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := repoInfo(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplRepoInfo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func repoInfo(c *cli.Context) error {
|
||||||
|
arg := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(arg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := client.Repo(owner, name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tmpl.Execute(os.Stdout, repo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// template for repo information
|
||||||
|
var tmplRepoInfo = `Owner: {{ .Owner }}
|
||||||
|
Repo: {{ .Name }}
|
||||||
|
Type: {{ .Kind }}
|
||||||
|
Private: {{ .IsPrivate }}
|
||||||
|
Remote: {{ .Clone }}
|
||||||
|
`
|
59
drone/repo_list.go
Normal file
59
drone/repo_list.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var repoListCmd = cli.Command{
|
||||||
|
Name: "ls",
|
||||||
|
Usage: "list all repos",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := repoList(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplRepoList,
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "org",
|
||||||
|
Usage: "filter by organization",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func repoList(c *cli.Context) error {
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
repos, err := client.RepoList()
|
||||||
|
if err != nil || len(repos) == 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
org := c.String("org")
|
||||||
|
for _, repo := range repos {
|
||||||
|
if org != "" && org != repo.Owner {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tmpl.Execute(os.Stdout, repo)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// template for repository list items
|
||||||
|
var tmplRepoList = `{{ .FullName }}`
|
37
drone/repo_rm.go
Normal file
37
drone/repo_rm.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var repoRemoveCmd = cli.Command{
|
||||||
|
Name: "rm",
|
||||||
|
Usage: "remove a repository",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := repoRemove(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func repoRemove(c *cli.Context) error {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := client.RepoDel(owner, name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Successfully removed repository %s/%s\n", owner, name)
|
||||||
|
return nil
|
||||||
|
}
|
80
drone/secert_add.go
Normal file
80
drone/secert_add.go
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/drone/drone/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var secretAddCmd = cli.Command{
|
||||||
|
Name: "add",
|
||||||
|
Usage: "adds a secret",
|
||||||
|
ArgsUsage: "[repo] [key] [value]",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := secretAdd(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringSliceFlag{
|
||||||
|
Name: "event",
|
||||||
|
Usage: "inject the secret for these event types",
|
||||||
|
Value: &cli.StringSlice{
|
||||||
|
model.EventPush,
|
||||||
|
model.EventTag,
|
||||||
|
model.EventDeploy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cli.StringSliceFlag{
|
||||||
|
Name: "image",
|
||||||
|
Usage: "inject the secret for these image types",
|
||||||
|
Value: &cli.StringSlice{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func secretAdd(c *cli.Context) error {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tail := c.Args().Tail()
|
||||||
|
if len(tail) != 2 {
|
||||||
|
cli.ShowSubcommandHelp(c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
secret := &model.Secret{}
|
||||||
|
secret.Name = tail[0]
|
||||||
|
secret.Value = tail[1]
|
||||||
|
secret.Images = c.StringSlice("image")
|
||||||
|
secret.Events = c.StringSlice("event")
|
||||||
|
|
||||||
|
if len(secret.Images) == 0 {
|
||||||
|
return fmt.Errorf("Please specify the --image parameter")
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow secret value to come from a file when prefixed with the @ symbol,
|
||||||
|
// similar to curl conventions.
|
||||||
|
if strings.HasPrefix(secret.Value, "@") {
|
||||||
|
path := secret.Value[1:]
|
||||||
|
out, ferr := ioutil.ReadFile(path)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
secret.Value = string(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.SecretPost(owner, name, secret)
|
||||||
|
}
|
|
@ -1,103 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "github.com/codegangsta/cli"
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
var secretCmd = cli.Command{
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SecretCmd is the exported command for managing secrets.
|
|
||||||
var SecretCmd = cli.Command{
|
|
||||||
Name: "secret",
|
Name: "secret",
|
||||||
Usage: "manage secrets",
|
Usage: "manage secrets",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
// Secret Add
|
secretAddCmd,
|
||||||
{
|
secretRemoveCmd,
|
||||||
Name: "add",
|
|
||||||
Usage: "add a secret",
|
|
||||||
ArgsUsage: "[repo] [key] [value]",
|
|
||||||
Action: func(c *cli.Context) {
|
|
||||||
if err := secretAdd(c); err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringSliceFlag{
|
|
||||||
Name: "event",
|
|
||||||
Usage: "inject the secret for these event types",
|
|
||||||
Value: &cli.StringSlice{
|
|
||||||
model.EventPush,
|
|
||||||
model.EventTag,
|
|
||||||
model.EventDeploy,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
cli.StringSliceFlag{
|
|
||||||
Name: "image",
|
|
||||||
Usage: "inject the secret for these image types",
|
|
||||||
Value: &cli.StringSlice{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Secret Delete
|
|
||||||
{
|
|
||||||
Name: "rm",
|
|
||||||
Usage: "remove a secret",
|
|
||||||
Action: func(c *cli.Context) {
|
|
||||||
if err := secretDel(c); err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func secretAdd(c *cli.Context) error {
|
|
||||||
|
|
||||||
repo := c.Args().First()
|
|
||||||
owner, name, err := parseRepo(repo)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
tail := c.Args().Tail()
|
|
||||||
if len(tail) != 2 {
|
|
||||||
cli.ShowSubcommandHelp(c)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
secret := &model.Secret{}
|
|
||||||
secret.Name = tail[0]
|
|
||||||
secret.Value = tail[1]
|
|
||||||
secret.Images = c.StringSlice("image")
|
|
||||||
secret.Events = c.StringSlice("event")
|
|
||||||
|
|
||||||
if len(secret.Images) == 0 {
|
|
||||||
return fmt.Errorf("Please specify the --image parameter")
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := newClient(c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return client.SecretPost(owner, name, secret)
|
|
||||||
}
|
|
||||||
|
|
||||||
func secretDel(c *cli.Context) error {
|
|
||||||
repo := c.Args().First()
|
|
||||||
owner, name, err := parseRepo(repo)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
secret := c.Args().Get(1)
|
|
||||||
|
|
||||||
client, err := newClient(c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return client.SecretDel(owner, name, secret)
|
|
||||||
}
|
|
||||||
|
|
1
drone/secret_info.go
Normal file
1
drone/secret_info.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package main
|
1
drone/secret_list.go
Normal file
1
drone/secret_list.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package main
|
33
drone/secret_rm.go
Normal file
33
drone/secret_rm.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var secretRemoveCmd = cli.Command{
|
||||||
|
Name: "rm",
|
||||||
|
Usage: "remove a secret",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := secretRemove(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func secretRemove(c *cli.Context) error {
|
||||||
|
repo := c.Args().First()
|
||||||
|
owner, name, err := parseRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
secret := c.Args().Get(1)
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return client.SecretDel(owner, name, secret)
|
||||||
|
}
|
|
@ -14,12 +14,11 @@ import (
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DaemonCmd is the exported command for starting the drone server daemon.
|
var serverCmd = cli.Command{
|
||||||
var DaemonCmd = cli.Command{
|
Name: "server",
|
||||||
Name: "daemon",
|
|
||||||
Usage: "starts the drone server daemon",
|
Usage: "starts the drone server daemon",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
if err := start(c); err != nil {
|
if err := server(c); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -275,7 +274,7 @@ var DaemonCmd = cli.Command{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func start(c *cli.Context) error {
|
func server(c *cli.Context) error {
|
||||||
|
|
||||||
if c.Bool("agreement.ack") == false || c.Bool("agreement.fix") == false {
|
if c.Bool("agreement.ack") == false || c.Bool("agreement.fix") == false {
|
||||||
fmt.Println(agreement)
|
fmt.Println(agreement)
|
|
@ -7,8 +7,7 @@ import (
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignCmd is the exported command for signing the yaml.
|
var signCmd = cli.Command{
|
||||||
var SignCmd = cli.Command{
|
|
||||||
Name: "sign",
|
Name: "sign",
|
||||||
Usage: "creates a secure yaml file",
|
Usage: "creates a secure yaml file",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
|
|
14
drone/user.go
Normal file
14
drone/user.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/codegangsta/cli"
|
||||||
|
|
||||||
|
var userCmd = cli.Command{
|
||||||
|
Name: "user",
|
||||||
|
Usage: "manage users",
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
userListCmd,
|
||||||
|
userInfoCmd,
|
||||||
|
userAddCmd,
|
||||||
|
userRemoveCmd,
|
||||||
|
},
|
||||||
|
}
|
35
drone/user_add.go
Normal file
35
drone/user_add.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/drone/drone/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var userAddCmd = cli.Command{
|
||||||
|
Name: "add",
|
||||||
|
Usage: "adds a user",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := userAdd(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func userAdd(c *cli.Context) error {
|
||||||
|
login := c.Args().First()
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := client.UserPost(&model.User{Login: login})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Successfully added user %s\n", user.Login)
|
||||||
|
return nil
|
||||||
|
}
|
54
drone/user_info.go
Normal file
54
drone/user_info.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var userInfoCmd = cli.Command{
|
||||||
|
Name: "info",
|
||||||
|
Usage: "show user details",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := userInfo(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplUserInfo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func userInfo(c *cli.Context) error {
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
login := c.Args().First()
|
||||||
|
if len(login) == 0 {
|
||||||
|
return fmt.Errorf("Missing or invalid user login")
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := client.User(login)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tmpl.Execute(os.Stdout, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
// template for user information
|
||||||
|
var tmplUserInfo = `User: {{ .Login }}
|
||||||
|
Email: {{ .Email }}`
|
50
drone/user_list.go
Normal file
50
drone/user_list.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var userListCmd = cli.Command{
|
||||||
|
Name: "ls",
|
||||||
|
Usage: "list all users",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := userList(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "format output",
|
||||||
|
Value: tmplUserList,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func userList(c *cli.Context) error {
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
users, err := client.UserList()
|
||||||
|
if err != nil || len(users) == 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, user := range users {
|
||||||
|
tmpl.Execute(os.Stdout, user)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// template for user list items
|
||||||
|
var tmplUserList = `{{ .Login }}`
|
33
drone/user_rm.go
Normal file
33
drone/user_rm.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var userRemoveCmd = cli.Command{
|
||||||
|
Name: "rm",
|
||||||
|
Usage: "remove a user",
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
if err := userRemove(c); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func userRemove(c *cli.Context) error {
|
||||||
|
login := c.Args().First()
|
||||||
|
|
||||||
|
client, err := newClient(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := client.UserDel(login); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Successfully removed user %s\n", login)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,61 +0,0 @@
|
||||||
package builtin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/drone/drone/engine/runner"
|
|
||||||
"github.com/drone/drone/engine/compiler/parse"
|
|
||||||
)
|
|
||||||
|
|
||||||
type cacheOp struct {
|
|
||||||
visitor
|
|
||||||
enable bool
|
|
||||||
plugin string
|
|
||||||
mount string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCacheOp returns a transformer that configures the default cache plugin.
|
|
||||||
func NewCacheOp(plugin, mount string, enable bool) Visitor {
|
|
||||||
return &cacheOp{
|
|
||||||
mount: mount,
|
|
||||||
enable: enable,
|
|
||||||
plugin: plugin,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *cacheOp) VisitContainer(node *parse.ContainerNode) error {
|
|
||||||
if node.Type() != parse.NodeCache {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(node.Vargs) == 0 || v.enable == false {
|
|
||||||
node.Disabled = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if node.Container.Name == "" {
|
|
||||||
node.Container.Name = "cache"
|
|
||||||
}
|
|
||||||
if node.Container.Image == "" {
|
|
||||||
node.Container.Image = v.plugin
|
|
||||||
}
|
|
||||||
|
|
||||||
// discard any other cache properties except the image name.
|
|
||||||
// everything else is discard for security reasons.
|
|
||||||
node.Container = runner.Container{
|
|
||||||
Name: node.Container.Name,
|
|
||||||
Alias: node.Container.Alias,
|
|
||||||
Image: node.Container.Image,
|
|
||||||
Volumes: []string{
|
|
||||||
v.mount + ":/cache",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is a hack until I can come up with a better solution.
|
|
||||||
// this copies the clone name, and appends at the end of the
|
|
||||||
// build. When it is executed a second time the build should
|
|
||||||
// have a completed status, so it knows to cache instead
|
|
||||||
// of restore.
|
|
||||||
cache := node.Root().NewCacheNode()
|
|
||||||
cache.Vargs = node.Vargs
|
|
||||||
cache.Container = node.Container
|
|
||||||
node.Root().Script = append(node.Root().Script, cache)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package builtin
|
|
||||||
|
|
||||||
// import (
|
|
||||||
// "testing"
|
|
||||||
|
|
||||||
// "github.com/libcd/libcd"
|
|
||||||
// "github.com/libcd/libyaml/parse"
|
|
||||||
|
|
||||||
// "github.com/franela/goblin"
|
|
||||||
// )
|
|
||||||
|
|
||||||
// func Test_cache(t *testing.T) {
|
|
||||||
// root := parse.NewRootNode()
|
|
||||||
|
|
||||||
// g := goblin.Goblin(t)
|
|
||||||
// g.Describe("cache", func() {
|
|
||||||
|
|
||||||
// g.It("should use default when nil", func() {
|
|
||||||
// op := NewCacheOp("plugins/cache:latest", "/tmp/cache")
|
|
||||||
|
|
||||||
// op.VisitRoot(root)
|
|
||||||
// g.Assert(root.Cache.(*parse.ContainerNode).Container.Image).Equal("plugins/cache:latest")
|
|
||||||
// g.Assert(root.Cache.(*parse.ContainerNode).Container.Volumes[0]).Equal("/tmp/cache:/cache")
|
|
||||||
// })
|
|
||||||
|
|
||||||
// g.It("should use user-defined cache plugin", func() {
|
|
||||||
// op := NewCacheOp("plugins/cache:latest", "/tmp/cache")
|
|
||||||
// cache := root.NewCacheNode()
|
|
||||||
// cache.Container = libcd.Container{}
|
|
||||||
// cache.Container.Image = "custom/cacher:latest"
|
|
||||||
// root.Cache = cache
|
|
||||||
|
|
||||||
// op.VisitRoot(root)
|
|
||||||
// g.Assert(cache.Container.Image).Equal("custom/cacher:latest")
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// }
|
|
Loading…
Reference in a new issue