mirror of
https://github.com/drone/drone-cli.git
synced 2024-11-26 06:07:05 +01:00
Merge branch 'master' into secret-info
This commit is contained in:
commit
5400456c24
14
.drone.sh
14
.drone.sh
@ -6,17 +6,19 @@ set -x
|
||||
export CGO_ENABLED=0
|
||||
|
||||
# compile for all architectures
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/linux/amd64/drone github.com/drone/drone-cli/drone
|
||||
GOOS=linux GOARCH=arm64 go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/linux/arm64/drone github.com/drone/drone-cli/drone
|
||||
GOOS=linux GOARCH=arm go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/linux/arm/drone github.com/drone/drone-cli/drone
|
||||
GOOS=windows GOARCH=amd64 go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/windows/amd64/drone github.com/drone/drone-cli/drone
|
||||
GOOS=darwin GOARCH=amd64 go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/darwin/amd64/drone github.com/drone/drone-cli/drone
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/linux/amd64/drone ./drone
|
||||
GOOS=linux GOARCH=arm64 go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/linux/arm64/drone ./drone
|
||||
GOOS=linux GOARCH=ppc64le go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/linux/ppc64le/drone ./drone
|
||||
GOOS=linux GOARCH=arm go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/linux/arm/drone ./drone
|
||||
GOOS=windows GOARCH=amd64 go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/windows/amd64/drone.exe ./drone
|
||||
GOOS=darwin GOARCH=amd64 go build -ldflags "-X main.version=${DRONE_TAG##v}" -o release/darwin/amd64/drone ./drone
|
||||
|
||||
# tar binary files prior to upload
|
||||
tar -cvzf release/drone_linux_amd64.tar.gz -C release/linux/amd64 drone
|
||||
tar -cvzf release/drone_linux_arm64.tar.gz -C release/linux/arm64 drone
|
||||
tar -cvzf release/drone_linux_ppc64le.tar.gz -C release/linux/ppc64le drone
|
||||
tar -cvzf release/drone_linux_arm.tar.gz -C release/linux/arm drone
|
||||
tar -cvzf release/drone_windows_amd64.tar.gz -C release/windows/amd64 drone
|
||||
tar -cvzf release/drone_windows_amd64.tar.gz -C release/windows/amd64 drone.exe
|
||||
tar -cvzf release/drone_darwin_amd64.tar.gz -C release/darwin/amd64 drone
|
||||
|
||||
# generate shas for tar files
|
||||
|
69
.drone.yml
69
.drone.yml
@ -1,57 +1,88 @@
|
||||
workspace:
|
||||
base: /go
|
||||
path: src/github.com/drone/drone-cli
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
pipeline:
|
||||
build:
|
||||
image: golang:1.9
|
||||
commands: sh .drone.sh
|
||||
steps:
|
||||
- name: build
|
||||
image: golang:1.13
|
||||
commands:
|
||||
- sh .drone.sh
|
||||
|
||||
publish_latest:
|
||||
- name: publish_latest
|
||||
image: plugins/docker
|
||||
settings:
|
||||
repo: drone/cli
|
||||
secrets: [docker_username, docker_password]
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
auto_tag: true
|
||||
when:
|
||||
event: [push, tag]
|
||||
|
||||
publish_alpine:
|
||||
- name: publish_alpine
|
||||
image: plugins/docker
|
||||
settings:
|
||||
repo: drone/cli
|
||||
secrets: [docker_username, docker_password]
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
auto_tag: true
|
||||
auto_tag_suffix: alpine
|
||||
dockerfile: Dockerfile.alpine
|
||||
when:
|
||||
event: [push, tag]
|
||||
|
||||
publish_linux_arm:
|
||||
- name: publish_linux_arm
|
||||
image: plugins/docker
|
||||
settings:
|
||||
repo: drone/cli
|
||||
secrets: [docker_username, docker_password]
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-arm
|
||||
dockerfile: Dockerfile.linux.arm
|
||||
when:
|
||||
event: [push, tag]
|
||||
|
||||
publish_linux_arm64:
|
||||
- name: publish_linux_arm64
|
||||
image: plugins/docker
|
||||
settings:
|
||||
repo: drone/cli
|
||||
secrets: [docker_username, docker_password]
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-arm64
|
||||
dockerfile: Dockerfile.linux.arm64
|
||||
when:
|
||||
event: [push, tag]
|
||||
|
||||
release:
|
||||
- name: publish_linux_ppc64le
|
||||
image: plugins/docker
|
||||
settings:
|
||||
repo: drone/cli
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-ppc64le
|
||||
dockerfile: Dockerfile.linux.ppc64le
|
||||
when:
|
||||
event: [push, tag]
|
||||
|
||||
- name: release
|
||||
image: plugins/github-release
|
||||
settings:
|
||||
files:
|
||||
- release/drone_*.tar.gz
|
||||
- release/drone_checksums.txt
|
||||
secrets:
|
||||
- source: github_token
|
||||
target: github_release_api_key
|
||||
api_key:
|
||||
from_secret: github_token
|
||||
when:
|
||||
event: tag
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
drone/drone
|
||||
release
|
||||
.env
|
||||
|
6
Dockerfile.linux.ppc64le
Normal file
6
Dockerfile.linux.ppc64le
Normal file
@ -0,0 +1,6 @@
|
||||
FROM drone/ca-certs
|
||||
|
||||
COPY release/linux/ppc64le/drone /bin/
|
||||
|
||||
ENTRYPOINT ["/bin/drone"]
|
||||
|
250
Gopkg.lock
generated
250
Gopkg.lock
generated
@ -1,250 +0,0 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/Microsoft/go-winio"
|
||||
packages = ["."]
|
||||
revision = "7da180ee92d8bd8bb8c37fc560e673e6557c392f"
|
||||
version = "v0.4.7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/Sirupsen/logrus"
|
||||
packages = ["."]
|
||||
revision = "d682213848ed68c0a260ca37d6dd5ace8423f5ba"
|
||||
version = "v1.0.4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/cncd/pipeline"
|
||||
packages = [
|
||||
"pipeline",
|
||||
"pipeline/backend",
|
||||
"pipeline/backend/docker",
|
||||
"pipeline/frontend",
|
||||
"pipeline/frontend/yaml",
|
||||
"pipeline/frontend/yaml/compiler",
|
||||
"pipeline/frontend/yaml/linter",
|
||||
"pipeline/frontend/yaml/types",
|
||||
"pipeline/interrupt",
|
||||
"pipeline/multipart"
|
||||
]
|
||||
revision = "3a09486affc9215ba52f55b1f6e10182458d1aba"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/docker/distribution"
|
||||
packages = ["reference"]
|
||||
revision = "7dba427612198a11b161a27f9d40bb2dca1ccd20"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/docker/docker"
|
||||
packages = [
|
||||
"api/types",
|
||||
"api/types/blkiodev",
|
||||
"api/types/container",
|
||||
"api/types/events",
|
||||
"api/types/filters",
|
||||
"api/types/mount",
|
||||
"api/types/network",
|
||||
"api/types/reference",
|
||||
"api/types/registry",
|
||||
"api/types/strslice",
|
||||
"api/types/swarm",
|
||||
"api/types/time",
|
||||
"api/types/versions",
|
||||
"api/types/volume",
|
||||
"client",
|
||||
"pkg/ioutils",
|
||||
"pkg/longpath",
|
||||
"pkg/random",
|
||||
"pkg/stdcopy",
|
||||
"pkg/stringid",
|
||||
"pkg/tlsconfig",
|
||||
"reference"
|
||||
]
|
||||
revision = "f645ffca04abf2dd6c89ac9057a1eb7d2b0ac338"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/docker/go-connections"
|
||||
packages = [
|
||||
"nat",
|
||||
"sockets",
|
||||
"tlsconfig"
|
||||
]
|
||||
revision = "eb315e36415380e7c2fdee175262560ff42359da"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/docker/go-units"
|
||||
packages = ["."]
|
||||
revision = "f2145db703495b2e525c59662db69a7344b00bb8"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/docker/libcompose"
|
||||
packages = ["yaml"]
|
||||
revision = "1c4bd4542afb20db0b51afd71d9ebceaf206e2dd"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/drone/drone-go"
|
||||
packages = ["drone"]
|
||||
revision = "7f20e6c113d3ffa2af80401c4eba7d510c8fd875"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/drone/envsubst"
|
||||
packages = [
|
||||
".",
|
||||
"parse"
|
||||
]
|
||||
revision = "f4d1a8ef8670afc9eea1fb95ee09a979fd2763a3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fatih/color"
|
||||
packages = ["."]
|
||||
revision = "507f6050b8568533fb3f5504de8e5205fa62a114"
|
||||
version = "v1.6.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/flynn/go-shlex"
|
||||
packages = ["."]
|
||||
revision = "3f9db97f856818214da2e1057f8ad84803971cff"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/ghodss/yaml"
|
||||
packages = ["."]
|
||||
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
revision = "925541529c1fa6821df4e44ce2723319eb2be768"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/google/go-jsonnet"
|
||||
packages = [
|
||||
".",
|
||||
"ast",
|
||||
"parser"
|
||||
]
|
||||
revision = "0274286eef945e5e24be6ebfc13a9deefdd312ee"
|
||||
source = "https://github.com/drone/go-jsonnet.git"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/jackspirou/syscerts"
|
||||
packages = ["."]
|
||||
revision = "b68f5469dff16e102bd6a2d5b3e79341c938d736"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/joho/godotenv"
|
||||
packages = [
|
||||
".",
|
||||
"autoload"
|
||||
]
|
||||
revision = "a79fa1e548e2c689c241d10173efd51e5d689d5b"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/opencontainers/go-digest"
|
||||
packages = ["."]
|
||||
revision = "279bed98673dd5bef374d3b6e4b09e2af76183bf"
|
||||
version = "v1.0.0-rc1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/pkg/browser"
|
||||
packages = ["."]
|
||||
revision = "c90ca0c84f15f81c982e32665bffd8d7aac8f097"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/urfave/cli"
|
||||
packages = ["."]
|
||||
revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1"
|
||||
version = "v1.20.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
revision = "650f4a345ab4e5b245a3034b110ebc7299e68186"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"context/ctxhttp",
|
||||
"proxy"
|
||||
]
|
||||
revision = "f5dfe339be1d06f81b22525fe34671ee7d2c8904"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
"internal"
|
||||
]
|
||||
revision = "543e37812f10c46c622c9575afd7ad22f22a12ba"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sync"
|
||||
packages = ["errgroup"]
|
||||
revision = "fd80eb99c8f653c847d294a001bdf2a3a6f768f5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows"
|
||||
]
|
||||
revision = "37707fdb30a5b38865cfb95e5aab41707daec7fd"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [
|
||||
"internal",
|
||||
"internal/base",
|
||||
"internal/datastore",
|
||||
"internal/log",
|
||||
"internal/remote_api",
|
||||
"internal/urlfetch",
|
||||
"urlfetch"
|
||||
]
|
||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "3c2492a2f392e0e4d42f2247aca5631e020aed1e2dea238bb56e27739866927a"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
74
Gopkg.toml
74
Gopkg.toml
@ -1,74 +0,0 @@
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/cncd/pipeline"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/drone/drone-go"
|
||||
revision = "7f20e6c113d3ffa2af80401c4eba7d510c8fd875"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/drone/envsubst"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/jackspirou/syscerts"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/joho/godotenv"
|
||||
version = "1.2.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/pkg/browser"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/urfave/cli"
|
||||
version = "1.20.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/google/go-jsonnet"
|
||||
source = "https://github.com/drone/go-jsonnet.git"
|
||||
|
||||
#
|
||||
# Some project dependencies hale from the dark ages
|
||||
# of Go dependnecy management and require that we point
|
||||
# to specific revisions.
|
||||
#
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/docker"
|
||||
revision = "f645ffca04abf2dd6c89ac9057a1eb7d2b0ac338"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/distribution"
|
||||
revision = "7dba427612198a11b161a27f9d40bb2dca1ccd20"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/go-connections"
|
||||
revision = "eb315e36415380e7c2fdee175262560ff42359da"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/go-units"
|
||||
revision = "f2145db703495b2e525c59662db69a7344b00bb8"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/libcompose"
|
||||
revision = "1c4bd4542afb20db0b51afd71d9ebceaf206e2dd"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
non-go = true
|
13
README.md
13
README.md
@ -1 +1,12 @@
|
||||
Command line client for the Drone continuous integration server. Please see the official documentation at http://docs.drone.io/cli-installation/
|
||||
# drone-cli
|
||||
|
||||
Command line client for the Drone continuous integration server.
|
||||
|
||||
Documentation:<br/>
|
||||
https://docs.drone.io/cli
|
||||
|
||||
Technical Support:<br/>
|
||||
https://discourse.drone.io
|
||||
|
||||
Bug Tracker:<br/>
|
||||
https://discourse.drone.io/c/bugs
|
||||
|
@ -4,9 +4,9 @@ import (
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var autoscaleVersionCmd = cli.Command{
|
||||
@ -18,7 +18,6 @@ var autoscaleVersionCmd = cli.Command{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplAutoscaleVersion,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -34,7 +33,7 @@ func autoscaleVersion(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -9,14 +9,14 @@ var Command = cli.Command{
|
||||
Subcommands: []cli.Command{
|
||||
buildListCmd,
|
||||
buildLastCmd,
|
||||
buildLogsCmd,
|
||||
buildInfoCmd,
|
||||
buildCreateCmd,
|
||||
buildStopCmd,
|
||||
buildStartCmd,
|
||||
buildApproveCmd,
|
||||
buildDeclineCmd,
|
||||
buildPromoteCmd,
|
||||
buildRollbackCmd,
|
||||
buildQueueCmd,
|
||||
buildKillCmd,
|
||||
buildPsCmd,
|
||||
},
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ import (
|
||||
|
||||
var buildApproveCmd = cli.Command{
|
||||
Name: "approve",
|
||||
Usage: "approve a build",
|
||||
ArgsUsage: "<repo/name> <build>",
|
||||
Usage: "approve a build stage",
|
||||
ArgsUsage: "<repo/name> <build> <stage>",
|
||||
Action: buildApprove,
|
||||
}
|
||||
|
||||
@ -25,13 +25,17 @@ func buildApprove(c *cli.Context) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stage, err := strconv.Atoi(c.Args().Get(2))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = client.BuildApprove(owner, name, number)
|
||||
err = client.Approve(owner, name, number, stage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
56
drone/build/build_create.go
Normal file
56
drone/build/build_create.go
Normal file
@ -0,0 +1,56 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var buildCreateCmd = cli.Command{
|
||||
Name: "create",
|
||||
Usage: "create a build",
|
||||
ArgsUsage: "<repo/name>",
|
||||
Action: buildCreate,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "commit",
|
||||
Usage: "source commit",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "branch",
|
||||
Usage: "source branch",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplBuildInfo,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func buildCreate(c *cli.Context) (err error) {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
build, err := client.BuildCreate(owner, name, c.String("commit"), c.String("branch"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, build)
|
||||
}
|
@ -10,8 +10,8 @@ import (
|
||||
|
||||
var buildDeclineCmd = cli.Command{
|
||||
Name: "decline",
|
||||
Usage: "decline a build",
|
||||
ArgsUsage: "<repo/name> <build>",
|
||||
Usage: "decline a build stage",
|
||||
ArgsUsage: "<repo/name> <build> <stage>",
|
||||
Action: buildDecline,
|
||||
}
|
||||
|
||||
@ -25,13 +25,17 @@ func buildDecline(c *cli.Context) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stage, err := strconv.Atoi(c.Args().Get(2))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = client.BuildDecline(owner, name, number)
|
||||
err = client.Decline(owner, name, number, stage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@ -43,7 +44,7 @@ func buildInfo(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
number = build.Number
|
||||
number = int(build.Number)
|
||||
} else {
|
||||
number, err = strconv.Atoi(buildArg)
|
||||
if err != nil {
|
||||
@ -56,7 +57,7 @@ func buildInfo(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format"))
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -67,9 +68,9 @@ func buildInfo(c *cli.Context) error {
|
||||
var tmplBuildInfo = `Number: {{ .Number }}
|
||||
Status: {{ .Status }}
|
||||
Event: {{ .Event }}
|
||||
Commit: {{ .Commit }}
|
||||
Branch: {{ .Branch }}
|
||||
Commit: {{ .After }}
|
||||
Branch: {{ .Target }}
|
||||
Ref: {{ .Ref }}
|
||||
Author: {{ .Author }} {{ if .AuthorEmail }}<{{.AuthorEmail}}>{{ end }}
|
||||
Message: {{ .Message }}
|
||||
Author: {{ .Author }}
|
||||
`
|
||||
|
@ -1,42 +0,0 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var buildKillCmd = cli.Command{
|
||||
Name: "kill",
|
||||
Usage: "force kill a build",
|
||||
ArgsUsage: "<repo/name> <build>",
|
||||
Action: buildKill,
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
func buildKill(c *cli.Context) (err error) {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
number, err := strconv.Atoi(c.Args().Get(1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = client.BuildKill(owner, name, number)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Force killing build %s/%s#%d\n", owner, name, number)
|
||||
return nil
|
||||
}
|
@ -5,6 +5,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@ -44,7 +45,7 @@ func buildLast(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format"))
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@ -36,6 +38,11 @@ var buildListCmd = cli.Command{
|
||||
Usage: "limit the list size",
|
||||
Value: 25,
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "page",
|
||||
Usage: "page number",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -51,12 +58,12 @@ func buildList(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
builds, err := client.BuildList(owner, name)
|
||||
builds, err := client.BuildList(owner, name, drone.ListOptions{Page: c.Int("page")})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -71,7 +78,7 @@ func buildList(c *cli.Context) error {
|
||||
if count >= limit {
|
||||
break
|
||||
}
|
||||
if branch != "" && build.Branch != branch {
|
||||
if branch != "" && build.Target != branch {
|
||||
continue
|
||||
}
|
||||
if event != "" && build.Event != event {
|
||||
@ -90,9 +97,9 @@ func buildList(c *cli.Context) error {
|
||||
var tmplBuildList = "\x1b[33mBuild #{{ .Number }} \x1b[0m" + `
|
||||
Status: {{ .Status }}
|
||||
Event: {{ .Event }}
|
||||
Commit: {{ .Commit }}
|
||||
Branch: {{ .Branch }}
|
||||
Commit: {{ .After }}
|
||||
Branch: {{ .Target }}
|
||||
Ref: {{ .Ref }}
|
||||
Author: {{ .Author }} {{ if .Email }}<{{.Email}}>{{ end }}
|
||||
Author: {{ .Author }} {{ if .AuthorEmail }}<{{.AuthorEmail}}>{{ end }}
|
||||
Message: {{ .Message }}
|
||||
`
|
||||
|
@ -1,18 +0,0 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var buildLogsCmd = cli.Command{
|
||||
Name: "logs",
|
||||
Usage: "show build logs",
|
||||
ArgsUsage: "<repo/name> [build] [job]",
|
||||
Action: buildLogs,
|
||||
}
|
||||
|
||||
func buildLogs(c *cli.Context) error {
|
||||
return fmt.Errorf("Command temporarily disabled. See https://github.com/drone/drone/issues/2005")
|
||||
}
|
59
drone/build/build_promote.go
Normal file
59
drone/build/build_promote.go
Normal file
@ -0,0 +1,59 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var buildPromoteCmd = cli.Command{
|
||||
Name: "promote",
|
||||
Usage: "promote a build",
|
||||
ArgsUsage: "<repo/name> <build> <environment>",
|
||||
Action: buildPromote,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringSliceFlag{
|
||||
Name: "param, p",
|
||||
Usage: "custom parameters to be injected into the job environment. Format: KEY=value",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplBuildInfo,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func buildPromote(c *cli.Context) (err error) {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
number, err := strconv.Atoi(c.Args().Get(1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target := c.Args().Get(2)
|
||||
params := internal.ParseKeyPair(c.StringSlice("param"))
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
build, err := client.Promote(owner, name, number, target, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, build)
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var buildPsCmd = cli.Command{
|
||||
Name: "ps",
|
||||
Usage: "show build steps",
|
||||
ArgsUsage: "<repo/name> [build]",
|
||||
Action: buildPs,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplBuildPs,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func buildPs(c *cli.Context) error {
|
||||
repo := c.Args().First()
|
||||
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buildArg := c.Args().Get(1)
|
||||
var number int
|
||||
|
||||
if buildArg == "last" || len(buildArg) == 0 {
|
||||
// Fetch the build number from the last build
|
||||
build, err := client.BuildLast(owner, name, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
number = build.Number
|
||||
} else {
|
||||
number, err = strconv.Atoi(buildArg)
|
||||
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") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, proc := range build.Procs {
|
||||
for _, child := range proc.Children {
|
||||
if err := tmpl.Execute(os.Stdout, child); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// template for build ps information
|
||||
var tmplBuildPs = "\x1b[33mProc #{{ .PID }} \x1b[0m" + `
|
||||
Step: {{ .Name }}
|
||||
State: {{ .State }}
|
||||
`
|
@ -1,18 +1,18 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var buildQueueCmd = cli.Command{
|
||||
Name: "queue",
|
||||
Usage: "show build queue",
|
||||
ArgsUsage: " ",
|
||||
ArgsUsage: "",
|
||||
Action: buildQueue,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
@ -20,44 +20,74 @@ var buildQueueCmd = cli.Command{
|
||||
Usage: "format output",
|
||||
Value: tmplBuildQueue,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo",
|
||||
Usage: "repo filter",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "branch",
|
||||
Usage: "branch filter",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "event",
|
||||
Usage: "event filter",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "status",
|
||||
Usage: "status filter",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func buildQueue(c *cli.Context) error {
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
builds, err := client.BuildQueue()
|
||||
repos, err := client.Incomplete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(builds) == 0 {
|
||||
fmt.Println("there are no pending or running builds")
|
||||
return nil
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, build := range builds {
|
||||
tmpl.Execute(os.Stdout, build)
|
||||
slug := c.String("repo")
|
||||
branch := c.String("branch")
|
||||
event := c.String("event")
|
||||
status := c.String("status")
|
||||
|
||||
for _, repo := range repos {
|
||||
if slug != "" && repo.Slug != slug {
|
||||
continue
|
||||
}
|
||||
if branch != "" && repo.Build.Target != branch {
|
||||
continue
|
||||
}
|
||||
if event != "" && repo.Build.Event != event {
|
||||
continue
|
||||
}
|
||||
if status != "" && repo.Build.Status != status {
|
||||
continue
|
||||
}
|
||||
tmpl.Execute(os.Stdout, repo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// template for build list information
|
||||
var tmplBuildQueue = "\x1b[33m{{ .FullName }} #{{ .Number }} \x1b[0m" + `
|
||||
Status: {{ .Status }}
|
||||
Event: {{ .Event }}
|
||||
Commit: {{ .Commit }}
|
||||
Branch: {{ .Branch }}
|
||||
Ref: {{ .Ref }}
|
||||
Author: {{ .Author }} {{ if .Email }}<{{.Email}}>{{ end }}
|
||||
Message: {{ .Message }}
|
||||
// template for build queue information
|
||||
var tmplBuildQueue = "\x1b[33m{{ .Slug }}#{{ .Build.Number }} \x1b[0m" + `
|
||||
Name: {{ .Slug }}
|
||||
Build: {{ .Build.Number }}
|
||||
Status: {{ .Build.Status }}
|
||||
Event: {{ .Build.Event }}
|
||||
Branch: {{ .Build.Target }}
|
||||
Ref: {{ .Build.Ref }}
|
||||
Author: {{ .Build.Author }}{{ if .Build.AuthorEmail }} <{{ .Build.AuthorEmail }}>{{ end }}
|
||||
Created: {{ .Build.Created | time }}
|
||||
Started: {{ .Build.Started | time }}
|
||||
Updated: {{ .Build.Updated | time }}
|
||||
`
|
||||
|
47
drone/build/build_rollback.go
Normal file
47
drone/build/build_rollback.go
Normal file
@ -0,0 +1,47 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var buildRollbackCmd = cli.Command{
|
||||
Name: "rollback",
|
||||
Usage: "rollback a build",
|
||||
ArgsUsage: "<repo/name> <build> <environment>",
|
||||
Action: buildRollback,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringSliceFlag{
|
||||
Name: "param, p",
|
||||
Usage: "custom parameters to be injected into the job environment. Format: KEY=value",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func buildRollback(c *cli.Context) (err error) {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
number, err := strconv.Atoi(c.Args().Get(1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target := c.Args().Get(2)
|
||||
params := internal.ParseKeyPair(c.StringSlice("param"))
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = client.Rollback(owner, name, number, target, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -2,16 +2,18 @@ package build
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var buildStartCmd = cli.Command{
|
||||
Name: "start",
|
||||
Usage: "start a build",
|
||||
Name: "restart",
|
||||
Usage: "restart a build",
|
||||
ArgsUsage: "<repo/name> [build]",
|
||||
Action: buildStart,
|
||||
Flags: []cli.Flag{
|
||||
@ -19,6 +21,11 @@ var buildStartCmd = cli.Command{
|
||||
Name: "param, p",
|
||||
Usage: "custom parameters to be injected into the job environment. Format: KEY=value",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplBuildInfo,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -42,7 +49,7 @@ func buildStart(c *cli.Context) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
number = build.Number
|
||||
number = int(build.Number)
|
||||
} else {
|
||||
if len(buildArg) == 0 {
|
||||
return errors.New("missing job number")
|
||||
@ -55,11 +62,14 @@ func buildStart(c *cli.Context) (err error) {
|
||||
|
||||
params := internal.ParseKeyPair(c.StringSlice("param"))
|
||||
|
||||
build, err := client.BuildStart(owner, name, number, params)
|
||||
build, err := client.BuildRestart(owner, name, number, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Starting build %s/%s#%d\n", owner, name, build.Number)
|
||||
return nil
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, build)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
var buildStopCmd = cli.Command{
|
||||
Name: "stop",
|
||||
Usage: "stop a build",
|
||||
ArgsUsage: "<repo/name> [build] [job]",
|
||||
ArgsUsage: "<repo/name> [build]",
|
||||
Action: buildStop,
|
||||
}
|
||||
|
||||
@ -25,21 +25,17 @@ func buildStop(c *cli.Context) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
job, _ := strconv.Atoi(c.Args().Get(2))
|
||||
if job == 0 {
|
||||
job = 1
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = client.BuildStop(owner, name, number, job)
|
||||
err = client.BuildCancel(owner, name, number)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Stopping build %s/%s#%d.%d\n", owner, name, number, job)
|
||||
fmt.Printf("Stopping build %s/%s#%d\n", owner, name, number)
|
||||
return nil
|
||||
}
|
||||
|
49
drone/convert/convert.go
Normal file
49
drone/convert/convert.go
Normal file
@ -0,0 +1,49 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-yaml/yaml/converter"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the convert command.
|
||||
var Command = cli.Command{
|
||||
Name: "convert",
|
||||
Usage: "convert legacy format",
|
||||
ArgsUsage: "<source>",
|
||||
Action: convert,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "save",
|
||||
Usage: "save result to source",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func convert(c *cli.Context) error {
|
||||
path := c.Args().First()
|
||||
if path == "" {
|
||||
path = ".drone.yml"
|
||||
}
|
||||
|
||||
raw, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := converter.Convert(raw, converter.Metadata{Filename: path})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.Bool("save") {
|
||||
return ioutil.WriteFile(path, res, 0644)
|
||||
}
|
||||
|
||||
_, err = io.Copy(os.Stderr, bytes.NewReader(res))
|
||||
return err
|
||||
}
|
16
drone/cron/cron.go
Normal file
16
drone/cron/cron.go
Normal file
@ -0,0 +1,16 @@
|
||||
package cron
|
||||
|
||||
import "github.com/urfave/cli"
|
||||
|
||||
// Command exports the registry command set.
|
||||
var Command = cli.Command{
|
||||
Name: "cron",
|
||||
Usage: "manage cron jobs",
|
||||
Subcommands: []cli.Command{
|
||||
cronListCmd,
|
||||
cronInfoCmd,
|
||||
cronCreateCmd,
|
||||
cronDisableCmd,
|
||||
cronEnableCmd,
|
||||
},
|
||||
}
|
44
drone/cron/cron_add.go
Normal file
44
drone/cron/cron_add.go
Normal file
@ -0,0 +1,44 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var cronCreateCmd = cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a cronjob",
|
||||
ArgsUsage: "[repo/name] [cronjob] [cronexpr]",
|
||||
Action: cronCreate,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "branch",
|
||||
Usage: "branch name",
|
||||
Value: "master",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func cronCreate(c *cli.Context) error {
|
||||
slug := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(slug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cron := &drone.Cron{
|
||||
Name: c.Args().Get(1),
|
||||
Expr: c.Args().Get(2),
|
||||
Branch: c.String("branch"),
|
||||
}
|
||||
_, err = client.CronCreate(owner, name, cron)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
39
drone/cron/cron_disable.go
Normal file
39
drone/cron/cron_disable.go
Normal file
@ -0,0 +1,39 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var cronDisableCmd = cli.Command{
|
||||
Name: "disable",
|
||||
Usage: "disable cron jobs",
|
||||
ArgsUsage: "[repo/name] [cronjob]",
|
||||
Action: cronDisable,
|
||||
}
|
||||
|
||||
func cronDisable(c *cli.Context) error {
|
||||
slug := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(slug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cron := c.Args().Get(1)
|
||||
if cron == "" {
|
||||
return errors.New("missing cronjob name")
|
||||
}
|
||||
disabled := true
|
||||
in := &drone.CronPatch{
|
||||
Disabled: &disabled,
|
||||
}
|
||||
_, err = client.CronUpdate(owner, name, cron, in)
|
||||
return err
|
||||
}
|
39
drone/cron/cron_enable.go
Normal file
39
drone/cron/cron_enable.go
Normal file
@ -0,0 +1,39 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var cronEnableCmd = cli.Command{
|
||||
Name: "enable",
|
||||
Usage: "enable cron jobs",
|
||||
ArgsUsage: "[repo/name] [cronjob]",
|
||||
Action: cronEnable,
|
||||
}
|
||||
|
||||
func cronEnable(c *cli.Context) error {
|
||||
slug := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(slug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cron := c.Args().Get(1)
|
||||
if cron == "" {
|
||||
return errors.New("missing cronjob name")
|
||||
}
|
||||
disabled := false
|
||||
in := &drone.CronPatch{
|
||||
Disabled: &disabled,
|
||||
}
|
||||
_, err = client.CronUpdate(owner, name, cron, in)
|
||||
return err
|
||||
}
|
47
drone/cron/cron_info.go
Normal file
47
drone/cron/cron_info.go
Normal file
@ -0,0 +1,47 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var cronInfoCmd = cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display cron info",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: cronInfo,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplCronList,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func cronInfo(c *cli.Context) error {
|
||||
slug := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(slug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cronjob := c.Args().Get(1)
|
||||
cron, err := client.Cron(owner, name, cronjob)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
format := c.String("format")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, cron)
|
||||
}
|
59
drone/cron/cron_list.go
Normal file
59
drone/cron/cron_list.go
Normal file
@ -0,0 +1,59 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var cronListCmd = cli.Command{
|
||||
Name: "ls",
|
||||
Usage: "list cron jobs",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: cronList,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplCronList,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func cronList(c *cli.Context) error {
|
||||
slug := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(slug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
list, err := client.CronList(owner, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
format := c.String("format") + "\n"
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, cron := range list {
|
||||
tmpl.Execute(os.Stdout, cron)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// template for build list information
|
||||
var tmplCronList = "\x1b[33m{{ .Name }} \x1b[0m" + `
|
||||
Expr: {{ .Expr }}
|
||||
Next: {{ .Next | time }}
|
||||
{{- if .Disabled }}
|
||||
Disabled: true
|
||||
{{- end }}
|
||||
`
|
@ -1,125 +0,0 @@
|
||||
package deploy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the deploy command.
|
||||
var Command = cli.Command{
|
||||
Name: "deploy",
|
||||
Usage: "deploy code",
|
||||
ArgsUsage: "<repo/name> <build> <environment>",
|
||||
Action: deploy,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplDeployInfo,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "branch",
|
||||
Usage: "branch filter",
|
||||
Value: "master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "event",
|
||||
Usage: "event filter",
|
||||
Value: drone.EventPush,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "status",
|
||||
Usage: "status filter",
|
||||
Value: drone.StatusSuccess,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "param, p",
|
||||
Usage: "custom parameters to be injected into the job environment. Format: KEY=value",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func deploy(c *cli.Context) error {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
branch := c.String("branch")
|
||||
event := c.String("event")
|
||||
status := c.String("status")
|
||||
|
||||
buildArg := c.Args().Get(1)
|
||||
var number int
|
||||
if buildArg == "last" {
|
||||
// Fetch the build number from the last build
|
||||
builds, berr := client.BuildList(owner, name)
|
||||
if berr != nil {
|
||||
return berr
|
||||
}
|
||||
for _, build := range builds {
|
||||
if branch != "" && build.Branch != branch {
|
||||
continue
|
||||
}
|
||||
if event != "" && build.Event != event {
|
||||
continue
|
||||
}
|
||||
if status != "" && build.Status != status {
|
||||
continue
|
||||
}
|
||||
if build.Number > number {
|
||||
number = build.Number
|
||||
}
|
||||
}
|
||||
if number == 0 {
|
||||
return fmt.Errorf("Cannot deploy failure build")
|
||||
}
|
||||
} else {
|
||||
number, err = strconv.Atoi(buildArg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
env := c.Args().Get(2)
|
||||
if env == "" {
|
||||
return fmt.Errorf("Please specify the target environment (ie production)")
|
||||
}
|
||||
|
||||
params := internal.ParseKeyPair(c.StringSlice("param"))
|
||||
|
||||
deploy, err := client.Deploy(owner, name, number, env, params)
|
||||
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 }}
|
||||
`
|
65
drone/encrypt/encrypt.go
Normal file
65
drone/encrypt/encrypt.go
Normal file
@ -0,0 +1,65 @@
|
||||
package encrypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command is an encryption cli.Command
|
||||
var Command = cli.Command{
|
||||
Name: "encrypt",
|
||||
Usage: "encrypt a secret",
|
||||
ArgsUsage: "<repo/name> <string>",
|
||||
Action: encryptSecret,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "allow-pull-request",
|
||||
Usage: "permit read access to pull requests",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "allow-push-on-pull-request",
|
||||
Usage: "permit write access to pull requests (e.g. allow docker push)",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func encryptSecret(c *cli.Context) error {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
plaintext := c.Args().Get(1)
|
||||
if strings.HasPrefix(plaintext, "@") {
|
||||
path := strings.TrimPrefix(plaintext, "@")
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plaintext = string(data)
|
||||
}
|
||||
|
||||
secret := &drone.Secret{
|
||||
Data: plaintext,
|
||||
PullRequest: c.Bool("allow-pull-request"),
|
||||
PullRequestPush: c.Bool("allow-push-on-pull-request"),
|
||||
}
|
||||
encrypted, err := client.Encrypt(owner, name, secret)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(encrypted)
|
||||
return nil
|
||||
}
|
77
drone/encrypt/registry.go
Normal file
77
drone/encrypt/registry.go
Normal file
@ -0,0 +1,77 @@
|
||||
package encrypt
|
||||
|
||||
// import (
|
||||
// "fmt"
|
||||
// "io/ioutil"
|
||||
// "strings"
|
||||
|
||||
// "github.com/drone/drone-cli/drone/internal"
|
||||
// "github.com/drone/drone-go/drone"
|
||||
|
||||
// "github.com/urfave/cli"
|
||||
// )
|
||||
|
||||
// var encryptRegistryCommand = cli.Command{
|
||||
// Name: "registry",
|
||||
// Usage: "encrypt registry credentials",
|
||||
// ArgsUsage: "<repo/name> <string>",
|
||||
// Action: encryptRegistry,
|
||||
// Flags: []cli.Flag{
|
||||
// cli.StringFlag{
|
||||
// Name: "username",
|
||||
// Usage: "registry username",
|
||||
// },
|
||||
// cli.StringFlag{
|
||||
// Name: "password",
|
||||
// Usage: "registry password",
|
||||
// },
|
||||
// cli.StringFlag{
|
||||
// Name: "server",
|
||||
// Usage: "registry server",
|
||||
// Value: "docker.io",
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
|
||||
// func encryptRegistry(c *cli.Context) error {
|
||||
// repo := c.Args().First()
|
||||
// owner, name, err := internal.ParseRepo(repo)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// client, err := internal.NewClient(c)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// password := c.String("password")
|
||||
// if strings.HasPrefix(password, "@") {
|
||||
// data, err := ioutil.ReadFile(password)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// password = string(data)
|
||||
// }
|
||||
|
||||
// policy := "pull"
|
||||
// switch {
|
||||
// case c.Bool("push"):
|
||||
// policy = "push"
|
||||
// case c.Bool("push-pull-request"):
|
||||
// policy = "push-pull-request"
|
||||
// }
|
||||
|
||||
// registry := &drone.Registry{
|
||||
// Address: c.String("server"),
|
||||
// Username: c.String("username"),
|
||||
// Password: password,
|
||||
// Policy: policy,
|
||||
// }
|
||||
// encrypted, err := client.EncryptRegistry(owner, name, registry)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// fmt.Println(encrypted)
|
||||
// return nil
|
||||
// }
|
493
drone/exec/_backup/exec.go
Normal file
493
drone/exec/_backup/exec.go
Normal file
@ -0,0 +1,493 @@
|
||||
package exec
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cncd/pipeline/pipeline"
|
||||
"github.com/cncd/pipeline/pipeline/backend"
|
||||
"github.com/cncd/pipeline/pipeline/backend/docker"
|
||||
"github.com/cncd/pipeline/pipeline/frontend"
|
||||
"github.com/cncd/pipeline/pipeline/frontend/yaml"
|
||||
"github.com/cncd/pipeline/pipeline/frontend/yaml/compiler"
|
||||
"github.com/cncd/pipeline/pipeline/frontend/yaml/linter"
|
||||
"github.com/cncd/pipeline/pipeline/interrupt"
|
||||
"github.com/cncd/pipeline/pipeline/multipart"
|
||||
"github.com/drone/envsubst"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the exec command.
|
||||
var Command = cli.Command{
|
||||
Name: "exec",
|
||||
Usage: "execute a local build",
|
||||
ArgsUsage: "[path/to/.drone.yml]",
|
||||
Action: func(c *cli.Context) {
|
||||
if err := exec(c); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolTFlag{
|
||||
Name: "local",
|
||||
Usage: "build from local directory",
|
||||
EnvVar: "DRONE_LOCAL",
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "timeout",
|
||||
Usage: "build timeout",
|
||||
Value: time.Hour,
|
||||
EnvVar: "DRONE_TIMEOUT",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "volumes",
|
||||
Usage: "build volumes",
|
||||
EnvVar: "DRONE_VOLUMES",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "network",
|
||||
Usage: "external networks",
|
||||
EnvVar: "DRONE_NETWORKS",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prefix",
|
||||
Value: "drone",
|
||||
Usage: "prefix containers created by drone",
|
||||
EnvVar: "DRONE_DOCKER_PREFIX",
|
||||
Hidden: true,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "privileged",
|
||||
Usage: "privileged plugins",
|
||||
Value: &cli.StringSlice{
|
||||
"plugins/docker",
|
||||
"plugins/acr",
|
||||
"plugins/ecr",
|
||||
"plugins/gcr",
|
||||
"plugins/heroku",
|
||||
},
|
||||
},
|
||||
|
||||
//
|
||||
// workspace default
|
||||
//
|
||||
cli.StringFlag{
|
||||
Name: "workspace-base",
|
||||
Value: "/drone",
|
||||
EnvVar: "DRONE_WORKSPACE_BASE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "workspace-path",
|
||||
Value: "src",
|
||||
EnvVar: "DRONE_WORKSPACE_PATH",
|
||||
},
|
||||
//
|
||||
// netrc parameters
|
||||
//
|
||||
cli.StringFlag{
|
||||
Name: "netrc-username",
|
||||
EnvVar: "DRONE_NETRC_USERNAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "netrc-password",
|
||||
EnvVar: "DRONE_NETRC_PASSWORD",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "netrc-machine",
|
||||
EnvVar: "DRONE_NETRC_MACHINE",
|
||||
},
|
||||
//
|
||||
// metadata parameters
|
||||
//
|
||||
cli.StringFlag{
|
||||
Name: "system-arch",
|
||||
Value: "linux/amd64",
|
||||
EnvVar: "DRONE_SYSTEM_ARCH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "system-name",
|
||||
Value: "pipec",
|
||||
EnvVar: "DRONE_SYSTEM_NAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "system-link",
|
||||
Value: "https://github.com/cncd/pipec",
|
||||
EnvVar: "DRONE_SYSTEM_LINK",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo-name",
|
||||
EnvVar: "DRONE_REPO_NAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo-link",
|
||||
EnvVar: "DRONE_REPO_LINK",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo-remote-url",
|
||||
EnvVar: "DRONE_REPO_REMOTE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo-private",
|
||||
EnvVar: "DRONE_REPO_PRIVATE",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "build-number",
|
||||
EnvVar: "DRONE_BUILD_NUMBER",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "parent-build-number",
|
||||
EnvVar: "DRONE_PARENT_BUILD_NUMBER",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "build-created",
|
||||
EnvVar: "DRONE_BUILD_CREATED",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "build-started",
|
||||
EnvVar: "DRONE_BUILD_STARTED",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "build-finished",
|
||||
EnvVar: "DRONE_BUILD_FINISHED",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build-status",
|
||||
EnvVar: "DRONE_BUILD_STATUS",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build-event",
|
||||
EnvVar: "DRONE_BUILD_EVENT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build-link",
|
||||
EnvVar: "DRONE_BUILD_LINK",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build-target",
|
||||
EnvVar: "DRONE_BUILD_TARGET",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-sha",
|
||||
EnvVar: "DRONE_COMMIT_SHA",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-ref",
|
||||
EnvVar: "DRONE_COMMIT_REF",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-refspec",
|
||||
EnvVar: "DRONE_COMMIT_REFSPEC",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-branch",
|
||||
EnvVar: "DRONE_COMMIT_BRANCH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-message",
|
||||
EnvVar: "DRONE_COMMIT_MESSAGE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-author-name",
|
||||
EnvVar: "DRONE_COMMIT_AUTHOR_NAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-author-avatar",
|
||||
EnvVar: "DRONE_COMMIT_AUTHOR_AVATAR",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-author-email",
|
||||
EnvVar: "DRONE_COMMIT_AUTHOR_EMAIL",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "prev-build-number",
|
||||
EnvVar: "DRONE_PREV_BUILD_NUMBER",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "prev-build-created",
|
||||
EnvVar: "DRONE_PREV_BUILD_CREATED",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "prev-build-started",
|
||||
EnvVar: "DRONE_PREV_BUILD_STARTED",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "prev-build-finished",
|
||||
EnvVar: "DRONE_PREV_BUILD_FINISHED",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-build-status",
|
||||
EnvVar: "DRONE_PREV_BUILD_STATUS",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-build-event",
|
||||
EnvVar: "DRONE_PREV_BUILD_EVENT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-build-link",
|
||||
EnvVar: "DRONE_PREV_BUILD_LINK",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-sha",
|
||||
EnvVar: "DRONE_PREV_COMMIT_SHA",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-ref",
|
||||
EnvVar: "DRONE_PREV_COMMIT_REF",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-refspec",
|
||||
EnvVar: "DRONE_PREV_COMMIT_REFSPEC",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-branch",
|
||||
EnvVar: "DRONE_PREV_COMMIT_BRANCH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-message",
|
||||
EnvVar: "DRONE_PREV_COMMIT_MESSAGE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-author-name",
|
||||
EnvVar: "DRONE_PREV_COMMIT_AUTHOR_NAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-author-avatar",
|
||||
EnvVar: "DRONE_PREV_COMMIT_AUTHOR_AVATAR",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-author-email",
|
||||
EnvVar: "DRONE_PREV_COMMIT_AUTHOR_EMAIL",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "job-number",
|
||||
EnvVar: "DRONE_JOB_NUMBER",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "env, e",
|
||||
EnvVar: "DRONE_ENV",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func exec(c *cli.Context) error {
|
||||
file := c.Args().First()
|
||||
if file == "" {
|
||||
file = ".drone.yml"
|
||||
}
|
||||
|
||||
metadata := metadataFromContext(c)
|
||||
environ := metadata.Environ()
|
||||
secrets := []compiler.Secret{}
|
||||
for k, v := range metadata.EnvironDrone() {
|
||||
environ[k] = v
|
||||
}
|
||||
for key, val := range metadata.Job.Matrix {
|
||||
environ[key] = val
|
||||
secrets = append(secrets, compiler.Secret{
|
||||
Name: key,
|
||||
Value: val,
|
||||
})
|
||||
}
|
||||
|
||||
droneEnv := make(map[string]string)
|
||||
for _, env := range c.StringSlice("env") {
|
||||
envs := strings.SplitN(env, "=", 2)
|
||||
droneEnv[envs[0]] = envs[1]
|
||||
}
|
||||
|
||||
tmpl, err := envsubst.ParseFile(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
confstr, err := tmpl.Execute(func(name string) string {
|
||||
return environ[name]
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conf, err := yaml.ParseString(confstr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// configure volumes for local execution
|
||||
volumes := c.StringSlice("volumes")
|
||||
if c.Bool("local") {
|
||||
var (
|
||||
workspaceBase = conf.Workspace.Base
|
||||
workspacePath = conf.Workspace.Path
|
||||
)
|
||||
if workspaceBase == "" {
|
||||
workspaceBase = c.String("workspace-base")
|
||||
}
|
||||
if workspacePath == "" {
|
||||
workspacePath = c.String("workspace-path")
|
||||
}
|
||||
dir, _ := filepath.Abs(filepath.Dir(file))
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
dir = convertPathForWindows(dir)
|
||||
}
|
||||
volumes = append(volumes, c.String("prefix")+"_default:"+workspaceBase)
|
||||
volumes = append(volumes, dir+":"+path.Join(workspaceBase, workspacePath))
|
||||
}
|
||||
|
||||
// lint the yaml file
|
||||
if lerr := linter.New(linter.WithTrusted(true)).Lint(conf); lerr != nil {
|
||||
return lerr
|
||||
}
|
||||
|
||||
// compiles the yaml file
|
||||
compiled := compiler.New(
|
||||
compiler.WithEscalated(
|
||||
c.StringSlice("privileged")...,
|
||||
),
|
||||
compiler.WithVolumes(volumes...),
|
||||
compiler.WithWorkspace(
|
||||
c.String("workspace-base"),
|
||||
c.String("workspace-path"),
|
||||
),
|
||||
compiler.WithNetworks(
|
||||
c.StringSlice("network")...,
|
||||
),
|
||||
compiler.WithPrefix(
|
||||
c.String("prefix"),
|
||||
),
|
||||
compiler.WithProxy(),
|
||||
compiler.WithLocal(
|
||||
c.Bool("local"),
|
||||
),
|
||||
compiler.WithNetrc(
|
||||
c.String("netrc-username"),
|
||||
c.String("netrc-password"),
|
||||
c.String("netrc-machine"),
|
||||
),
|
||||
compiler.WithMetadata(metadata),
|
||||
compiler.WithSecret(secrets...),
|
||||
compiler.WithEnviron(droneEnv),
|
||||
).Compile(conf)
|
||||
|
||||
engine, err := docker.NewEnv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), c.Duration("timeout"))
|
||||
defer cancel()
|
||||
ctx = interrupt.WithContext(ctx)
|
||||
|
||||
return pipeline.New(compiled,
|
||||
pipeline.WithContext(ctx),
|
||||
pipeline.WithTracer(pipeline.DefaultTracer),
|
||||
pipeline.WithLogger(defaultLogger),
|
||||
pipeline.WithEngine(engine),
|
||||
).Run()
|
||||
}
|
||||
|
||||
// return the metadata from the cli context.
|
||||
func metadataFromContext(c *cli.Context) frontend.Metadata {
|
||||
return frontend.Metadata{
|
||||
Repo: frontend.Repo{
|
||||
Name: c.String("repo-name"),
|
||||
Link: c.String("repo-link"),
|
||||
Remote: c.String("repo-remote-url"),
|
||||
Private: c.Bool("repo-private"),
|
||||
},
|
||||
Curr: frontend.Build{
|
||||
Number: c.Int("build-number"),
|
||||
Parent: c.Int("parent-build-number"),
|
||||
Created: c.Int64("build-created"),
|
||||
Started: c.Int64("build-started"),
|
||||
Finished: c.Int64("build-finished"),
|
||||
Status: c.String("build-status"),
|
||||
Event: c.String("build-event"),
|
||||
Link: c.String("build-link"),
|
||||
Target: c.String("build-target"),
|
||||
Commit: frontend.Commit{
|
||||
Sha: c.String("commit-sha"),
|
||||
Ref: c.String("commit-ref"),
|
||||
Refspec: c.String("commit-refspec"),
|
||||
Branch: c.String("commit-branch"),
|
||||
Message: c.String("commit-message"),
|
||||
Author: frontend.Author{
|
||||
Name: c.String("commit-author-name"),
|
||||
Email: c.String("commit-author-email"),
|
||||
Avatar: c.String("commit-author-avatar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Prev: frontend.Build{
|
||||
Number: c.Int("prev-build-number"),
|
||||
Created: c.Int64("prev-build-created"),
|
||||
Started: c.Int64("prev-build-started"),
|
||||
Finished: c.Int64("prev-build-finished"),
|
||||
Status: c.String("prev-build-status"),
|
||||
Event: c.String("prev-build-event"),
|
||||
Link: c.String("prev-build-link"),
|
||||
Commit: frontend.Commit{
|
||||
Sha: c.String("prev-commit-sha"),
|
||||
Ref: c.String("prev-commit-ref"),
|
||||
Refspec: c.String("prev-commit-refspec"),
|
||||
Branch: c.String("prev-commit-branch"),
|
||||
Message: c.String("prev-commit-message"),
|
||||
Author: frontend.Author{
|
||||
Name: c.String("prev-commit-author-name"),
|
||||
Email: c.String("prev-commit-author-email"),
|
||||
Avatar: c.String("prev-commit-author-avatar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Job: frontend.Job{
|
||||
Number: c.Int("job-number"),
|
||||
Matrix: availableEnvironment(),
|
||||
},
|
||||
Sys: frontend.System{
|
||||
Name: c.String("system-name"),
|
||||
Link: c.String("system-link"),
|
||||
Arch: c.String("system-arch"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func availableEnvironment() map[string]string {
|
||||
result := make(map[string]string, 0)
|
||||
|
||||
for _, env := range os.Environ() {
|
||||
pair := strings.SplitN(env, "=", 2)
|
||||
result[pair[0]] = pair[1]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func convertPathForWindows(path string) string {
|
||||
base := filepath.VolumeName(path)
|
||||
if len(base) == 2 {
|
||||
path = strings.TrimPrefix(path, base)
|
||||
base = strings.ToLower(strings.TrimSuffix(base, ":"))
|
||||
return "/" + base + filepath.ToSlash(path)
|
||||
}
|
||||
|
||||
return filepath.ToSlash(path)
|
||||
}
|
||||
|
||||
var defaultLogger = pipeline.LogFunc(func(proc *backend.Step, rc multipart.Reader) error {
|
||||
part, err := rc.NextPart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logstream := NewLineWriter(proc.Alias)
|
||||
io.Copy(logstream, part)
|
||||
|
||||
return nil
|
||||
})
|
73
drone/exec/env.go
Normal file
73
drone/exec/env.go
Normal file
@ -0,0 +1,73 @@
|
||||
package exec
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func getEnv(c *cli.Context) map[string]string {
|
||||
env := prefixedEnviron(
|
||||
os.Environ(),
|
||||
)
|
||||
if c.IsSet("branch") {
|
||||
v := c.String("branch")
|
||||
env["DRONE_BRANCH"] = v
|
||||
env["DRONE_COMMIT_BRANCH"] = v
|
||||
env["DRONE_TARGET_BRANCH"] = v
|
||||
}
|
||||
if c.IsSet("event") {
|
||||
v := c.String("event")
|
||||
env["DRONE_EVENT"] = v
|
||||
}
|
||||
if c.IsSet("instance") {
|
||||
v := c.String("instance")
|
||||
env["DRONE_SYSTEM_HOST"] = v
|
||||
env["DRONE_SYSTEM_HOSTNAME"] = v
|
||||
}
|
||||
if c.IsSet("ref") {
|
||||
v := c.String("ref")
|
||||
env["DRONE_COMMIT_REF"] = v
|
||||
}
|
||||
if c.IsSet("repo") {
|
||||
v := c.String("repo")
|
||||
env["DRONE_REPO"] = v
|
||||
}
|
||||
if c.IsSet("deploy-to") {
|
||||
v := c.String("deploy-to")
|
||||
env["DRONE_DEPLOY_TO"] = v
|
||||
}
|
||||
return env
|
||||
}
|
||||
|
||||
// helper function returns all environment variables
|
||||
// prefixed with DRONE_.
|
||||
func prefixedEnviron(environ []string) map[string]string {
|
||||
envs := map[string]string{}
|
||||
for _, env := range environ {
|
||||
if !strings.HasPrefix(env, "DRONE_") {
|
||||
continue
|
||||
}
|
||||
parts := strings.SplitN(env, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
key := parts[0]
|
||||
val := parts[1]
|
||||
envs[key] = val
|
||||
}
|
||||
return envs
|
||||
}
|
||||
|
||||
// helper function combines one or more maps of environment
|
||||
// variables into a single map.
|
||||
func combineEnviron(env ...map[string]string) map[string]string {
|
||||
c := map[string]string{}
|
||||
for _, e := range env {
|
||||
for k, v := range e {
|
||||
c[k] = v
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
@ -2,29 +2,35 @@ package exec
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/cncd/pipeline/pipeline"
|
||||
"github.com/cncd/pipeline/pipeline/backend"
|
||||
"github.com/cncd/pipeline/pipeline/backend/docker"
|
||||
"github.com/cncd/pipeline/pipeline/frontend"
|
||||
"github.com/cncd/pipeline/pipeline/frontend/yaml"
|
||||
"github.com/cncd/pipeline/pipeline/frontend/yaml/compiler"
|
||||
"github.com/cncd/pipeline/pipeline/frontend/yaml/linter"
|
||||
"github.com/cncd/pipeline/pipeline/interrupt"
|
||||
"github.com/cncd/pipeline/pipeline/multipart"
|
||||
"github.com/drone/envsubst"
|
||||
|
||||
"github.com/drone/drone-runtime/engine"
|
||||
"github.com/drone/drone-runtime/engine/docker"
|
||||
"github.com/drone/drone-runtime/runtime"
|
||||
"github.com/drone/drone-runtime/runtime/term"
|
||||
"github.com/drone/drone-yaml/yaml"
|
||||
"github.com/drone/drone-yaml/yaml/compiler"
|
||||
"github.com/drone/drone-yaml/yaml/compiler/transform"
|
||||
"github.com/drone/drone-yaml/yaml/converter"
|
||||
"github.com/drone/drone-yaml/yaml/linter"
|
||||
"github.com/drone/signal"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var tty = isatty.IsTerminal(os.Stdout.Fd())
|
||||
|
||||
// Command exports the exec command.
|
||||
var Command = cli.Command{
|
||||
Name: "exec",
|
||||
@ -36,247 +42,107 @@ var Command = cli.Command{
|
||||
}
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolTFlag{
|
||||
Name: "local",
|
||||
Usage: "build from local directory",
|
||||
EnvVar: "DRONE_LOCAL",
|
||||
cli.StringFlag{
|
||||
Name: "pipeline",
|
||||
Usage: "Name of the pipeline to execute",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "include",
|
||||
Usage: "Name of steps to include",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "exclude",
|
||||
Usage: "Name of steps to exclude",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "resume-at",
|
||||
Usage: "Name of start to resume at",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "clone",
|
||||
Usage: "enable the clone step",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "trusted",
|
||||
Usage: "build is trusted",
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "timeout",
|
||||
Usage: "build timeout",
|
||||
Value: time.Hour,
|
||||
EnvVar: "DRONE_TIMEOUT",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "volumes",
|
||||
Name: "volume",
|
||||
Usage: "build volumes",
|
||||
EnvVar: "DRONE_VOLUMES",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "network",
|
||||
Usage: "external networks",
|
||||
EnvVar: "DRONE_NETWORKS",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "registry",
|
||||
Usage: "registry",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prefix",
|
||||
Value: "drone",
|
||||
Usage: "prefix containers created by drone",
|
||||
EnvVar: "DRONE_DOCKER_PREFIX",
|
||||
Hidden: true,
|
||||
Name: "secret-file",
|
||||
Usage: "secret file, define values that can be used with from_secret",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "env-file",
|
||||
Usage: "env file",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "privileged",
|
||||
Usage: "privileged plugins",
|
||||
Value: &cli.StringSlice{
|
||||
"plugins/docker",
|
||||
"plugins/gcr",
|
||||
"plugins/acr",
|
||||
"plugins/ecr",
|
||||
"plugins/gcr",
|
||||
"plugins/heroku",
|
||||
},
|
||||
},
|
||||
|
||||
//
|
||||
// Please note the below flags are mirrored in the pipec and
|
||||
// should be kept synchronized. Do not edit directly
|
||||
// https://github.com/cncd/pipeline/pipec
|
||||
//
|
||||
|
||||
//
|
||||
// workspace default
|
||||
//
|
||||
cli.StringFlag{
|
||||
Name: "workspace-base",
|
||||
Value: "/drone",
|
||||
EnvVar: "DRONE_WORKSPACE_BASE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "workspace-path",
|
||||
Value: "src",
|
||||
EnvVar: "DRONE_WORKSPACE_PATH",
|
||||
},
|
||||
//
|
||||
// netrc parameters
|
||||
//
|
||||
cli.StringFlag{
|
||||
Name: "netrc-username",
|
||||
EnvVar: "DRONE_NETRC_USERNAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "netrc-password",
|
||||
EnvVar: "DRONE_NETRC_PASSWORD",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "netrc-machine",
|
||||
EnvVar: "DRONE_NETRC_MACHINE",
|
||||
},
|
||||
|
||||
//
|
||||
// metadata parameters
|
||||
// trigger parameters
|
||||
//
|
||||
|
||||
cli.StringFlag{
|
||||
Name: "system-arch",
|
||||
Value: "linux/amd64",
|
||||
EnvVar: "DRONE_SYSTEM_ARCH",
|
||||
Name: "branch",
|
||||
Usage: "branch name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "system-name",
|
||||
Value: "pipec",
|
||||
EnvVar: "DRONE_SYSTEM_NAME",
|
||||
Name: "event",
|
||||
Usage: "build event name (push, pull_request, etc)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "system-link",
|
||||
Value: "https://github.com/cncd/pipec",
|
||||
EnvVar: "DRONE_SYSTEM_LINK",
|
||||
Name: "instance",
|
||||
Usage: "instance hostname (e.g. drone.company.com)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo-name",
|
||||
EnvVar: "DRONE_REPO_NAME",
|
||||
Name: "ref",
|
||||
Usage: "git reference",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo-link",
|
||||
EnvVar: "DRONE_REPO_LINK",
|
||||
Name: "repo",
|
||||
Usage: "git repository name (e.g. octocat/hello-world)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo-remote-url",
|
||||
EnvVar: "DRONE_REPO_REMOTE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo-private",
|
||||
EnvVar: "DRONE_REPO_PRIVATE",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "build-number",
|
||||
EnvVar: "DRONE_BUILD_NUMBER",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "parent-build-number",
|
||||
EnvVar: "DRONE_PARENT_BUILD_NUMBER",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "build-created",
|
||||
EnvVar: "DRONE_BUILD_CREATED",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "build-started",
|
||||
EnvVar: "DRONE_BUILD_STARTED",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "build-finished",
|
||||
EnvVar: "DRONE_BUILD_FINISHED",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build-status",
|
||||
EnvVar: "DRONE_BUILD_STATUS",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build-event",
|
||||
EnvVar: "DRONE_BUILD_EVENT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build-link",
|
||||
EnvVar: "DRONE_BUILD_LINK",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build-target",
|
||||
EnvVar: "DRONE_BUILD_TARGET",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-sha",
|
||||
EnvVar: "DRONE_COMMIT_SHA",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-ref",
|
||||
EnvVar: "DRONE_COMMIT_REF",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-refspec",
|
||||
EnvVar: "DRONE_COMMIT_REFSPEC",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-branch",
|
||||
EnvVar: "DRONE_COMMIT_BRANCH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-message",
|
||||
EnvVar: "DRONE_COMMIT_MESSAGE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-author-name",
|
||||
EnvVar: "DRONE_COMMIT_AUTHOR_NAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-author-avatar",
|
||||
EnvVar: "DRONE_COMMIT_AUTHOR_AVATAR",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "commit-author-email",
|
||||
EnvVar: "DRONE_COMMIT_AUTHOR_EMAIL",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "prev-build-number",
|
||||
EnvVar: "DRONE_PREV_BUILD_NUMBER",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "prev-build-created",
|
||||
EnvVar: "DRONE_PREV_BUILD_CREATED",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "prev-build-started",
|
||||
EnvVar: "DRONE_PREV_BUILD_STARTED",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "prev-build-finished",
|
||||
EnvVar: "DRONE_PREV_BUILD_FINISHED",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-build-status",
|
||||
EnvVar: "DRONE_PREV_BUILD_STATUS",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-build-event",
|
||||
EnvVar: "DRONE_PREV_BUILD_EVENT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-build-link",
|
||||
EnvVar: "DRONE_PREV_BUILD_LINK",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-sha",
|
||||
EnvVar: "DRONE_PREV_COMMIT_SHA",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-ref",
|
||||
EnvVar: "DRONE_PREV_COMMIT_REF",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-refspec",
|
||||
EnvVar: "DRONE_PREV_COMMIT_REFSPEC",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-branch",
|
||||
EnvVar: "DRONE_PREV_COMMIT_BRANCH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-message",
|
||||
EnvVar: "DRONE_PREV_COMMIT_MESSAGE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-author-name",
|
||||
EnvVar: "DRONE_PREV_COMMIT_AUTHOR_NAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-author-avatar",
|
||||
EnvVar: "DRONE_PREV_COMMIT_AUTHOR_AVATAR",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "prev-commit-author-email",
|
||||
EnvVar: "DRONE_PREV_COMMIT_AUTHOR_EMAIL",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "job-number",
|
||||
EnvVar: "DRONE_JOB_NUMBER",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "env, e",
|
||||
EnvVar: "DRONE_ENV",
|
||||
Name: "deploy-to",
|
||||
Usage: "deployment target (e.g. production)",
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -287,211 +153,204 @@ func exec(c *cli.Context) error {
|
||||
file = ".drone.yml"
|
||||
}
|
||||
|
||||
metadata := metadataFromContext(c)
|
||||
environ := metadata.Environ()
|
||||
secrets := []compiler.Secret{}
|
||||
for k, v := range metadata.EnvironDrone() {
|
||||
environ[k] = v
|
||||
}
|
||||
for key, val := range metadata.Job.Matrix {
|
||||
environ[key] = val
|
||||
secrets = append(secrets, compiler.Secret{
|
||||
Name: key,
|
||||
Value: val,
|
||||
})
|
||||
}
|
||||
|
||||
drone_env := make(map[string]string)
|
||||
for _, env := range c.StringSlice("env") {
|
||||
envs := strings.SplitN(env, "=", 2)
|
||||
drone_env[envs[0]] = envs[1]
|
||||
}
|
||||
|
||||
tmpl, err := envsubst.ParseFile(file)
|
||||
data, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
confstr, err := tmpl.Execute(func(name string) string {
|
||||
|
||||
environ := getEnv(c)
|
||||
dataS, err := envsubst.Eval(string(data), func(name string) string {
|
||||
return environ[name]
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conf, err := yaml.ParseString(confstr)
|
||||
// this code is temporarily in place to detect and convert
|
||||
// the legacy yaml configuration file to the new format.
|
||||
dataS, err = converter.ConvertString(dataS, converter.Metadata{
|
||||
Filename: file,
|
||||
Ref: c.String("ref"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// configure volumes for local execution
|
||||
volumes := c.StringSlice("volumes")
|
||||
if c.Bool("local") {
|
||||
var (
|
||||
workspaceBase = conf.Workspace.Base
|
||||
workspacePath = conf.Workspace.Path
|
||||
manifest, err := yaml.ParseString(dataS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var pipeline *yaml.Pipeline
|
||||
filter := c.String("pipeline")
|
||||
for _, resource := range manifest.Resources {
|
||||
v, ok := resource.(*yaml.Pipeline)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if filter == "" || filter == v.Name {
|
||||
pipeline = v
|
||||
break
|
||||
}
|
||||
}
|
||||
if pipeline == nil {
|
||||
return errors.New("cannot find pipeline")
|
||||
}
|
||||
|
||||
trusted := c.Bool("trusted")
|
||||
err = linter.Lint(pipeline, trusted)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// the user has the option to disable the git clone
|
||||
// if the pipeline is being executed on the local
|
||||
// codebase.
|
||||
if c.Bool("clone") == false {
|
||||
pipeline.Clone.Disable = true
|
||||
}
|
||||
|
||||
comp := new(compiler.Compiler)
|
||||
comp.PrivilegedFunc = compiler.DindFunc(
|
||||
c.StringSlice("privileged"),
|
||||
)
|
||||
if workspaceBase == "" {
|
||||
workspaceBase = c.String("workspace-base")
|
||||
}
|
||||
if workspacePath == "" {
|
||||
workspacePath = c.String("workspace-path")
|
||||
}
|
||||
dir, _ := filepath.Abs(filepath.Dir(file))
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
dir = convertPathForWindows(dir)
|
||||
}
|
||||
volumes = append(volumes, c.String("prefix")+"_default:"+workspaceBase)
|
||||
volumes = append(volumes, dir+":"+path.Join(workspaceBase, workspacePath))
|
||||
}
|
||||
|
||||
// lint the yaml file
|
||||
if lerr := linter.New(linter.WithTrusted(true)).Lint(conf); lerr != nil {
|
||||
return lerr
|
||||
}
|
||||
|
||||
// compiles the yaml file
|
||||
compiled := compiler.New(
|
||||
compiler.WithEscalated(
|
||||
c.StringSlice("privileged")...,
|
||||
comp.SkipFunc = compiler.SkipFunc(
|
||||
compiler.SkipData{
|
||||
Branch: environ["DRONE_BRANCH"],
|
||||
Event: environ["DRONE_EVENT"],
|
||||
Instance: environ["DRONE_SYSTEM_HOST"],
|
||||
Ref: environ["DRONE_COMMIT_REF"],
|
||||
Repo: environ["DRONE_REPO"],
|
||||
Target: environ["DRONE_DEPLOY_TO"],
|
||||
},
|
||||
)
|
||||
transforms := []func(*engine.Spec){
|
||||
transform.Include(
|
||||
c.StringSlice("include"),
|
||||
),
|
||||
compiler.WithVolumes(volumes...),
|
||||
compiler.WithWorkspace(
|
||||
c.String("workspace-base"),
|
||||
c.String("workspace-path"),
|
||||
transform.Exclude(
|
||||
c.StringSlice("exclude"),
|
||||
),
|
||||
compiler.WithNetworks(
|
||||
c.StringSlice("network")...,
|
||||
transform.ResumeAt(
|
||||
c.String("resume-at"),
|
||||
),
|
||||
compiler.WithPrefix(
|
||||
c.String("prefix"),
|
||||
transform.WithAuths(
|
||||
toRegistry(
|
||||
c.StringSlice("registry"),
|
||||
),
|
||||
compiler.WithProxy(),
|
||||
compiler.WithLocal(
|
||||
c.Bool("local"),
|
||||
),
|
||||
compiler.WithNetrc(
|
||||
transform.WithEnviron(
|
||||
readParams(
|
||||
c.String("env-file"),
|
||||
),
|
||||
),
|
||||
transform.WithEnviron(environ),
|
||||
transform.WithLables(nil),
|
||||
transform.WithLimits(0, 0),
|
||||
transform.WithNetrc(
|
||||
c.String("netrc-machine"),
|
||||
c.String("netrc-username"),
|
||||
c.String("netrc-password"),
|
||||
c.String("netrc-machine"),
|
||||
),
|
||||
compiler.WithMetadata(metadata),
|
||||
compiler.WithSecret(secrets...),
|
||||
compiler.WithEnviron(drone_env),
|
||||
).Compile(conf)
|
||||
transform.WithNetworks(
|
||||
c.StringSlice("network"),
|
||||
),
|
||||
transform.WithProxy(),
|
||||
transform.WithSecrets(
|
||||
readParams(
|
||||
c.String("secret-file"),
|
||||
),
|
||||
),
|
||||
transform.WithVolumeSlice(
|
||||
c.StringSlice("volume"),
|
||||
),
|
||||
}
|
||||
if c.Bool("clone") == false {
|
||||
pwd, _ := os.Getwd()
|
||||
comp.WorkspaceMountFunc = compiler.MountHostWorkspace
|
||||
comp.WorkspaceFunc = compiler.CreateHostWorkspace(pwd)
|
||||
}
|
||||
comp.TransformFunc = transform.Combine(transforms...)
|
||||
ir := comp.Compile(pipeline)
|
||||
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.Background(),
|
||||
c.Duration("timeout"),
|
||||
)
|
||||
ctx = signal.WithContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
// creates a docker-based engine. eventually we will
|
||||
// include the kubernetes and vmware fusion engines.
|
||||
engine, err := docker.NewEnv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), c.Duration("timeout"))
|
||||
defer cancel()
|
||||
ctx = interrupt.WithContext(ctx)
|
||||
// creates a hook to print the step output to stdout,
|
||||
// with per-step color coding if a tty.
|
||||
hooks := &runtime.Hook{}
|
||||
hooks.BeforeEach = func(s *runtime.State) error {
|
||||
s.Step.Envs["CI_BUILD_STATUS"] = "success"
|
||||
s.Step.Envs["CI_BUILD_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
|
||||
s.Step.Envs["CI_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
s.Step.Envs["DRONE_BUILD_STATUS"] = "success"
|
||||
s.Step.Envs["DRONE_BUILD_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
|
||||
s.Step.Envs["DRONE_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
return pipeline.New(compiled,
|
||||
pipeline.WithContext(ctx),
|
||||
pipeline.WithTracer(pipeline.DefaultTracer),
|
||||
pipeline.WithLogger(defaultLogger),
|
||||
pipeline.WithEngine(engine),
|
||||
).Run()
|
||||
}
|
||||
s.Step.Envs["CI_JOB_STATUS"] = "success"
|
||||
s.Step.Envs["CI_JOB_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
|
||||
s.Step.Envs["CI_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
s.Step.Envs["DRONE_JOB_STATUS"] = "success"
|
||||
s.Step.Envs["DRONE_JOB_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
|
||||
s.Step.Envs["DRONE_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
// return the metadata from the cli context.
|
||||
func metadataFromContext(c *cli.Context) frontend.Metadata {
|
||||
return frontend.Metadata{
|
||||
Repo: frontend.Repo{
|
||||
Name: c.String("repo-name"),
|
||||
Link: c.String("repo-link"),
|
||||
Remote: c.String("repo-remote-url"),
|
||||
Private: c.Bool("repo-private"),
|
||||
},
|
||||
Curr: frontend.Build{
|
||||
Number: c.Int("build-number"),
|
||||
Parent: c.Int("parent-build-number"),
|
||||
Created: c.Int64("build-created"),
|
||||
Started: c.Int64("build-started"),
|
||||
Finished: c.Int64("build-finished"),
|
||||
Status: c.String("build-status"),
|
||||
Event: c.String("build-event"),
|
||||
Link: c.String("build-link"),
|
||||
Target: c.String("build-target"),
|
||||
Commit: frontend.Commit{
|
||||
Sha: c.String("commit-sha"),
|
||||
Ref: c.String("commit-ref"),
|
||||
Refspec: c.String("commit-refspec"),
|
||||
Branch: c.String("commit-branch"),
|
||||
Message: c.String("commit-message"),
|
||||
Author: frontend.Author{
|
||||
Name: c.String("commit-author-name"),
|
||||
Email: c.String("commit-author-email"),
|
||||
Avatar: c.String("commit-author-avatar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Prev: frontend.Build{
|
||||
Number: c.Int("prev-build-number"),
|
||||
Created: c.Int64("prev-build-created"),
|
||||
Started: c.Int64("prev-build-started"),
|
||||
Finished: c.Int64("prev-build-finished"),
|
||||
Status: c.String("prev-build-status"),
|
||||
Event: c.String("prev-build-event"),
|
||||
Link: c.String("prev-build-link"),
|
||||
Commit: frontend.Commit{
|
||||
Sha: c.String("prev-commit-sha"),
|
||||
Ref: c.String("prev-commit-ref"),
|
||||
Refspec: c.String("prev-commit-refspec"),
|
||||
Branch: c.String("prev-commit-branch"),
|
||||
Message: c.String("prev-commit-message"),
|
||||
Author: frontend.Author{
|
||||
Name: c.String("prev-commit-author-name"),
|
||||
Email: c.String("prev-commit-author-email"),
|
||||
Avatar: c.String("prev-commit-author-avatar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Job: frontend.Job{
|
||||
Number: c.Int("job-number"),
|
||||
Matrix: availableEnvironment(),
|
||||
},
|
||||
Sys: frontend.System{
|
||||
Name: c.String("system-name"),
|
||||
Link: c.String("system-link"),
|
||||
Arch: c.String("system-arch"),
|
||||
},
|
||||
if s.Runtime.Error != nil {
|
||||
s.Step.Envs["CI_BUILD_STATUS"] = "failure"
|
||||
s.Step.Envs["CI_JOB_STATUS"] = "failure"
|
||||
s.Step.Envs["DRONE_BUILD_STATUS"] = "failure"
|
||||
s.Step.Envs["DRONE_JOB_STATUS"] = "failure"
|
||||
}
|
||||
}
|
||||
|
||||
func availableEnvironment() map[string]string {
|
||||
result := make(map[string]string, 0)
|
||||
|
||||
for _, env := range os.Environ() {
|
||||
pair := strings.SplitN(env, "=", 2)
|
||||
result[pair[0]] = pair[1]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func convertPathForWindows(path string) string {
|
||||
base := filepath.VolumeName(path)
|
||||
if len(base) == 2 {
|
||||
path = strings.TrimPrefix(path, base)
|
||||
base = strings.ToLower(strings.TrimSuffix(base, ":"))
|
||||
return "/" + base + filepath.ToSlash(path)
|
||||
}
|
||||
|
||||
return filepath.ToSlash(path)
|
||||
}
|
||||
|
||||
var defaultLogger = pipeline.LogFunc(func(proc *backend.Step, rc multipart.Reader) error {
|
||||
part, err := rc.NextPart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logstream := NewLineWriter(proc.Alias)
|
||||
io.Copy(logstream, part)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
hooks.GotLine = term.WriteLine(os.Stdout)
|
||||
if tty {
|
||||
hooks.GotLine = term.WriteLinePretty(
|
||||
colorable.NewColorableStdout(),
|
||||
)
|
||||
}
|
||||
|
||||
return runtime.New(
|
||||
runtime.WithEngine(engine),
|
||||
runtime.WithConfig(ir),
|
||||
runtime.WithHooks(hooks),
|
||||
).Run(ctx)
|
||||
}
|
||||
|
||||
// helper function converts a slice of urls to a slice
|
||||
// of docker registry credentials.
|
||||
func toRegistry(items []string) []*engine.DockerAuth {
|
||||
auths := []*engine.DockerAuth{}
|
||||
for _, item := range items {
|
||||
uri, err := url.Parse(item)
|
||||
if err != nil {
|
||||
continue // skip invalid
|
||||
}
|
||||
user := uri.User.Username()
|
||||
pass, _ := uri.User.Password()
|
||||
uri.User = nil
|
||||
auths = append(auths, &engine.DockerAuth{
|
||||
Address: uri.String(),
|
||||
Username: user,
|
||||
Password: pass,
|
||||
})
|
||||
}
|
||||
return auths
|
||||
}
|
||||
|
||||
// helper function reads secrets from a key-value file.
|
||||
func readParams(path string) map[string]string {
|
||||
data, _ := godotenv.Read(path)
|
||||
return data
|
||||
}
|
||||
|
47
drone/format/format.go
Normal file
47
drone/format/format.go
Normal file
@ -0,0 +1,47 @@
|
||||
package format
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-yaml/yaml"
|
||||
"github.com/drone/drone-yaml/yaml/pretty"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the fmt command.
|
||||
var Command = cli.Command{
|
||||
Name: "fmt",
|
||||
Usage: "format the yaml file",
|
||||
ArgsUsage: "<source>",
|
||||
Action: format,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "save",
|
||||
Usage: "save result to source",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func format(c *cli.Context) error {
|
||||
path := c.Args().First()
|
||||
if path == "" {
|
||||
path = ".drone.yml"
|
||||
}
|
||||
|
||||
manifest, err := yaml.ParseFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
pretty.Print(buf, manifest)
|
||||
|
||||
if c.Bool("save") {
|
||||
return ioutil.WriteFile(path, buf.Bytes(), 0644)
|
||||
}
|
||||
_, err = io.Copy(os.Stderr, buf)
|
||||
return err
|
||||
}
|
@ -4,9 +4,9 @@ import (
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the info command.
|
||||
@ -20,7 +20,6 @@ var Command = cli.Command{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplInfo,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -36,7 +35,7 @@ func info(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -49,6 +49,10 @@ func NewClient(c *cli.Context) (drone.Client, error) {
|
||||
},
|
||||
)
|
||||
|
||||
auther.CheckRedirect = func(*http.Request, []*http.Request) error {
|
||||
return fmt.Errorf("Attempting to redirect the requests. Did you configure the correct drone server address?")
|
||||
}
|
||||
|
||||
trans, _ := auther.Transport.(*oauth2.Transport)
|
||||
|
||||
if len(socks) != 0 && !socksoff {
|
||||
@ -79,7 +83,7 @@ func NewAutoscaleClient(c *cli.Context) (drone.Client, error) {
|
||||
}
|
||||
autoscaler := c.GlobalString("autoscaler")
|
||||
if autoscaler == "" {
|
||||
return nil, fmt.Errorf("Please provide the autoscaler address")
|
||||
return nil, fmt.Errorf("Please provide the autoscaler address.")
|
||||
}
|
||||
client.SetAddress(
|
||||
strings.TrimSuffix(autoscaler, "/"),
|
||||
@ -91,7 +95,7 @@ func NewAutoscaleClient(c *cli.Context) (drone.Client, error) {
|
||||
func ParseRepo(str string) (user, repo string, err error) {
|
||||
var parts = strings.Split(str, "/")
|
||||
if len(parts) != 2 {
|
||||
err = fmt.Errorf("Error: Invalid or missing repository. eg octocat/hello-world.")
|
||||
err = fmt.Errorf("Error: Invalid or missing repository (e.g. octocat/hello-world).")
|
||||
return
|
||||
}
|
||||
user = parts[0]
|
||||
|
@ -1,9 +1,16 @@
|
||||
package jsonnet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone-yaml/yaml"
|
||||
"github.com/drone/drone-yaml/yaml/pretty"
|
||||
"github.com/fatih/color"
|
||||
"github.com/google/go-jsonnet"
|
||||
"github.com/urfave/cli"
|
||||
@ -20,67 +27,120 @@ var Command = cli.Command{
|
||||
}
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "source",
|
||||
Usage: "Source file",
|
||||
Value: ".drone.jsonnet",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "target",
|
||||
Usage: "target file",
|
||||
Value: ".drone.yml",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "string",
|
||||
Hidden: true,
|
||||
Name: "stream",
|
||||
Usage: "Write output as a YAML stream.",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "max-stack",
|
||||
Usage: "number of allowed stack frames",
|
||||
Value: 500,
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "max-trace",
|
||||
Usage: "max length of stack trace before cropping",
|
||||
Value: 20,
|
||||
cli.BoolTFlag{
|
||||
Name: "format",
|
||||
Usage: "Write output as formatted YAML",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "stdout",
|
||||
Usage: "write the json document to stdout",
|
||||
Usage: "Write output to stdout",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "string",
|
||||
Usage: "Expect a string, manifest as plain text",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "extVar, V",
|
||||
Usage: "Pass extVars to Jsonnet (can be specified multiple times)",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func generate(c *cli.Context) error {
|
||||
input := c.Args().Get(0)
|
||||
if input == "" {
|
||||
input = ".drone.jsonnet"
|
||||
}
|
||||
output := c.Args().Get(1)
|
||||
if output == "" {
|
||||
output = ".drone.yml"
|
||||
}
|
||||
source := c.String("source")
|
||||
target := c.String("target")
|
||||
|
||||
snippet, err := ioutil.ReadFile(input)
|
||||
data, err := ioutil.ReadFile(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vm := jsonnet.MakeVM()
|
||||
vm.KeepOrder = true
|
||||
vm.MaxStack = 500
|
||||
vm.StringOutput = c.Bool("string")
|
||||
vm.MaxStack = c.Int("max-stack")
|
||||
// vm.ExtVar
|
||||
// vm.ExtCode
|
||||
// vm.TLAVar
|
||||
// vm.TLACode
|
||||
// vm.Importer(&jsonnet.FileImporter{})
|
||||
|
||||
vm.ErrorFormatter.SetMaxStackTraceSize(
|
||||
c.Int("max-trace"),
|
||||
)
|
||||
vm.ErrorFormatter.SetMaxStackTraceSize(20)
|
||||
vm.ErrorFormatter.SetColorFormatter(
|
||||
color.New(color.FgRed).Fprintf,
|
||||
)
|
||||
|
||||
raw, err := vm.EvaluateSnippet(input, string(snippet))
|
||||
// register native functions
|
||||
RegisterNativeFuncs(vm)
|
||||
|
||||
// extVars
|
||||
vars := c.StringSlice("extVar")
|
||||
for _, v := range vars {
|
||||
name, value, err := getVarVal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vm.ExtVar(name, value)
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if c.Bool("stream") {
|
||||
docs, err := vm.EvaluateSnippetStream(source, string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, doc := range docs {
|
||||
buf.WriteString("---")
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString(doc)
|
||||
}
|
||||
} else {
|
||||
result, err := vm.EvaluateSnippet(source, string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(result)
|
||||
}
|
||||
|
||||
// the yaml file is parsed and formatted by default. This
|
||||
// can be disabled for --format=false.
|
||||
if c.BoolT("format") {
|
||||
manifest, err := yaml.Parse(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.Reset()
|
||||
pretty.Print(buf, manifest)
|
||||
}
|
||||
|
||||
// the user can optionally write the yaml to stdout. This
|
||||
// is useful for debugging purposes without mutating an
|
||||
// existing file.
|
||||
if c.Bool("stdout") {
|
||||
println(raw)
|
||||
io.Copy(os.Stdout, buf)
|
||||
return nil
|
||||
}
|
||||
return ioutil.WriteFile(output, []byte(raw), 0644)
|
||||
|
||||
return ioutil.WriteFile(target, buf.Bytes(), 0644)
|
||||
}
|
||||
|
||||
// https://github.com/google/go-jsonnet/blob/master/cmd/jsonnet/cmd.go#L149
|
||||
func getVarVal(s string) (string, string, error) {
|
||||
parts := strings.SplitN(s, "=", 2)
|
||||
name := parts[0]
|
||||
if len(parts) == 1 {
|
||||
content, exists := os.LookupEnv(name)
|
||||
if exists {
|
||||
return name, content, nil
|
||||
}
|
||||
return "", "", fmt.Errorf("environment variable %v was undefined", name)
|
||||
}
|
||||
return name, parts[1], nil
|
||||
}
|
||||
|
45
drone/jsonnet/nativefuncs.go
Normal file
45
drone/jsonnet/nativefuncs.go
Normal file
@ -0,0 +1,45 @@
|
||||
package jsonnet
|
||||
|
||||
import (
|
||||
// "bytes"
|
||||
// "encoding/json"
|
||||
// "io"
|
||||
|
||||
jsonnet "github.com/google/go-jsonnet"
|
||||
// jsonnetAst "github.com/google/go-jsonnet/ast"
|
||||
// "k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
// RegisterNativeFuncs adds kubecfg's native jsonnet functions to provided VM
|
||||
func RegisterNativeFuncs(vm *jsonnet.VM) {
|
||||
// vm.NativeFunction(&jsonnet.NativeFunction{
|
||||
// Name: "parseJson",
|
||||
// Params: []jsonnetAst.Identifier{"json"},
|
||||
// Func: func(args []interface{}) (res interface{}, err error) {
|
||||
// data := []byte(args[0].(string))
|
||||
// err = json.Unmarshal(data, &res)
|
||||
// return
|
||||
// },
|
||||
// })
|
||||
|
||||
// vm.NativeFunction(&jsonnet.NativeFunction{
|
||||
// Name: "parseYaml",
|
||||
// Params: []jsonnetAst.Identifier{"yaml"},
|
||||
// Func: func(args []interface{}) (res interface{}, err error) {
|
||||
// ret := []interface{}{}
|
||||
// data := []byte(args[0].(string))
|
||||
// d := yaml.NewYAMLToJSONDecoder(bytes.NewReader(data))
|
||||
// for {
|
||||
// var doc interface{}
|
||||
// if err := d.Decode(&doc); err != nil {
|
||||
// if err == io.EOF {
|
||||
// break
|
||||
// }
|
||||
// return nil, err
|
||||
// }
|
||||
// ret = append(ret, doc)
|
||||
// }
|
||||
// return ret, nil
|
||||
// },
|
||||
// })
|
||||
}
|
41
drone/lint/lint.go
Normal file
41
drone/lint/lint.go
Normal file
@ -0,0 +1,41 @@
|
||||
package lint
|
||||
|
||||
import (
|
||||
"github.com/drone/drone-yaml/yaml"
|
||||
"github.com/drone/drone-yaml/yaml/linter"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the linter command.
|
||||
var Command = cli.Command{
|
||||
Name: "lint",
|
||||
Usage: "lint the yaml file",
|
||||
ArgsUsage: "<source>",
|
||||
Action: lint,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "trusted",
|
||||
Usage: "is the yaml trustable",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func lint(c *cli.Context) error {
|
||||
path := c.Args().First()
|
||||
if path == "" {
|
||||
path = ".drone.yml"
|
||||
}
|
||||
|
||||
manifest, err := yaml.ParseFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, resource := range manifest.Resources {
|
||||
if err := linter.Lint(resource, c.Bool("trusted")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -8,5 +8,6 @@ var Command = cli.Command{
|
||||
Usage: "manage logs",
|
||||
Subcommands: []cli.Command{
|
||||
logPurgeCmd,
|
||||
logViewCmd,
|
||||
},
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
var logPurgeCmd = cli.Command{
|
||||
Name: "purge",
|
||||
Usage: "purge a log",
|
||||
ArgsUsage: "<repo/name> <build>",
|
||||
ArgsUsage: "<repo/name> <build> <stage> <step>",
|
||||
Action: logPurge,
|
||||
}
|
||||
|
||||
@ -25,13 +25,21 @@ func logPurge(c *cli.Context) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stage, err := strconv.Atoi(c.Args().Get(2))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
step, err := strconv.Atoi(c.Args().Get(3))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = client.LogsPurge(owner, name, number)
|
||||
err = client.LogsPurge(owner, name, number, stage, step)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
50
drone/log/log_view.go
Normal file
50
drone/log/log_view.go
Normal file
@ -0,0 +1,50 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var logViewCmd = cli.Command{
|
||||
Name: "view",
|
||||
Usage: "display the step logs",
|
||||
ArgsUsage: "<repo/name> <build> <stage> <step>",
|
||||
Action: logView,
|
||||
}
|
||||
|
||||
func logView(c *cli.Context) (err error) {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
number, err := strconv.Atoi(c.Args().Get(1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stage, err := strconv.Atoi(c.Args().Get(2))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
step, err := strconv.Atoi(c.Args().Get(3))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lines, err := client.Logs(owner, name, number, stage, step)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
print(line.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
@ -6,15 +6,23 @@ import (
|
||||
|
||||
"github.com/drone/drone-cli/drone/autoscale"
|
||||
"github.com/drone/drone-cli/drone/build"
|
||||
"github.com/drone/drone-cli/drone/deploy"
|
||||
"github.com/drone/drone-cli/drone/convert"
|
||||
"github.com/drone/drone-cli/drone/cron"
|
||||
"github.com/drone/drone-cli/drone/encrypt"
|
||||
"github.com/drone/drone-cli/drone/exec"
|
||||
"github.com/drone/drone-cli/drone/format"
|
||||
"github.com/drone/drone-cli/drone/info"
|
||||
"github.com/drone/drone-cli/drone/jsonnet"
|
||||
"github.com/drone/drone-cli/drone/lint"
|
||||
"github.com/drone/drone-cli/drone/log"
|
||||
"github.com/drone/drone-cli/drone/registry"
|
||||
"github.com/drone/drone-cli/drone/orgsecret"
|
||||
"github.com/drone/drone-cli/drone/plugins"
|
||||
"github.com/drone/drone-cli/drone/queue"
|
||||
"github.com/drone/drone-cli/drone/repo"
|
||||
"github.com/drone/drone-cli/drone/secret"
|
||||
"github.com/drone/drone-cli/drone/server"
|
||||
"github.com/drone/drone-cli/drone/sign"
|
||||
"github.com/drone/drone-cli/drone/starlark"
|
||||
"github.com/drone/drone-cli/drone/user"
|
||||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
@ -68,17 +76,25 @@ func main() {
|
||||
}
|
||||
app.Commands = []cli.Command{
|
||||
build.Command,
|
||||
cron.Command,
|
||||
log.Command,
|
||||
deploy.Command,
|
||||
encrypt.Command,
|
||||
exec.Command,
|
||||
info.Command,
|
||||
registry.Command,
|
||||
secret.Command,
|
||||
repo.Command,
|
||||
user.Command,
|
||||
secret.Command,
|
||||
server.Command,
|
||||
queue.Command,
|
||||
orgsecret.Command,
|
||||
autoscale.Command,
|
||||
format.Command,
|
||||
convert.Command,
|
||||
lint.Command,
|
||||
sign.Command,
|
||||
jsonnet.Command,
|
||||
starlark.Command,
|
||||
plugins.Command,
|
||||
}
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
|
24
drone/node/node.go
Normal file
24
drone/node/node.go
Normal file
@ -0,0 +1,24 @@
|
||||
package node
|
||||
|
||||
import "github.com/urfave/cli"
|
||||
|
||||
// Command exports the registry command set.
|
||||
var Command = cli.Command{
|
||||
Name: "node",
|
||||
Usage: "manage nodes",
|
||||
Hidden: true,
|
||||
Subcommands: []cli.Command{
|
||||
nodeListCmd,
|
||||
nodeInfoCmd,
|
||||
nodeCreateCmd,
|
||||
// nodeUpdateCmd,
|
||||
// nodeDeleteCmd,
|
||||
// nodePauseCmd,
|
||||
// nodeUnpauseCmd,
|
||||
// nodeLockCmd,
|
||||
// nodeUnlockCmd,
|
||||
// nodeInitCmd,
|
||||
nodeImportCmd,
|
||||
// nodeKeygenCmd,
|
||||
},
|
||||
}
|
149
drone/node/node_create.go
Normal file
149
drone/node/node_create.go
Normal file
@ -0,0 +1,149 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var nodeCreateCmd = cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a node",
|
||||
Action: nodeCreate,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Usage: "node name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "hostname",
|
||||
Usage: "node hostname or ip address",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ca-key",
|
||||
Usage: "path to ca key",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ca-cert",
|
||||
Usage: "path to ca cert",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-key",
|
||||
Usage: "path to tls key",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-cert",
|
||||
Usage: "path to tls cert",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-server-name",
|
||||
Usage: "tls server name",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "capacity",
|
||||
Usage: "node capacity",
|
||||
Value: 2,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "os",
|
||||
Usage: "node os",
|
||||
Value: "linux",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "arch",
|
||||
Usage: "node arch",
|
||||
Value: "amd64",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "region",
|
||||
Usage: "node region",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "instance",
|
||||
Usage: "node instance type",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "image",
|
||||
Usage: "node image (i.e. ami)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "provider",
|
||||
Usage: "node hosting provider (e.g. amazon)",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "paused",
|
||||
Usage: "node is paused",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "protected",
|
||||
Usage: "node is protected from deletion",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplNodeInfo,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func nodeCreate(c *cli.Context) error {
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cakey, err := ioutil.ReadFile(c.String("ca-key"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacert, err := ioutil.ReadFile(c.String("ca-cert"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlskey, err := ioutil.ReadFile(c.String("tls-key"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlscert, err := ioutil.ReadFile(c.String("tls-cert"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
node := &drone.Node{
|
||||
UID: c.String("id"),
|
||||
Provider: c.String("provider"),
|
||||
State: c.String("state"),
|
||||
Name: c.String("name"),
|
||||
Image: c.String("image"),
|
||||
Region: c.String("region"),
|
||||
Size: c.String("instance"),
|
||||
OS: c.String("os"),
|
||||
Arch: c.String("arch"),
|
||||
Address: c.String("hostname"),
|
||||
Capacity: c.Int("capacity"),
|
||||
CAKey: cakey,
|
||||
CACert: cacert,
|
||||
TLSKey: tlskey,
|
||||
TLSCert: tlscert,
|
||||
TLSName: c.String("tls-server-name"),
|
||||
Paused: c.Bool("paused"),
|
||||
Protected: c.Bool("protected"),
|
||||
}
|
||||
|
||||
_, err = client.NodeCreate(node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
format := c.String("format")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, node)
|
||||
}
|
1
drone/node/node_delete.go
Normal file
1
drone/node/node_delete.go
Normal file
@ -0,0 +1 @@
|
||||
package node
|
192
drone/node/node_import.go
Normal file
192
drone/node/node_import.go
Normal file
@ -0,0 +1,192 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func getMachineHome() (path string) {
|
||||
user, err := user.Current()
|
||||
if err == nil {
|
||||
return filepath.Join(user.HomeDir, ".docker", "machine")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var nodeImportCmd = cli.Command{
|
||||
Name: "import",
|
||||
Usage: "import a node from docker-machine",
|
||||
Action: nodeImport,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Usage: "node name",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "capacity",
|
||||
Usage: "node capacity",
|
||||
Value: 2,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "os",
|
||||
Usage: "node os",
|
||||
Value: "linux",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "arch",
|
||||
Usage: "node arch",
|
||||
Value: "amd64",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "paused",
|
||||
Usage: "node is paused",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "protected",
|
||||
Usage: "node is protected from deletion",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "storage-path",
|
||||
Usage: "docker machine storage path",
|
||||
Value: getMachineHome(),
|
||||
EnvVar: "MACHINE_STORAGE_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplNodeInfo,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func nodeImport(c *cli.Context) error {
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := c.String("name")
|
||||
if name == "" {
|
||||
name = c.Args().First()
|
||||
}
|
||||
|
||||
home := c.String("storage-path")
|
||||
base := filepath.Join(home, "machines", name)
|
||||
|
||||
conf := new(machine)
|
||||
confpath := filepath.Join(base, "config.json")
|
||||
confdata, err := ioutil.ReadFile(confpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(confdata, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cakey, err := ioutil.ReadFile(conf.HostOptions.AuthOptions.CaPrivateKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacert, err := ioutil.ReadFile(conf.HostOptions.AuthOptions.CaCertPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlskey, err := ioutil.ReadFile(conf.HostOptions.AuthOptions.ClientKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlscert, err := ioutil.ReadFile(conf.HostOptions.AuthOptions.ClientCertPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
node := &drone.Node{
|
||||
UID: fmt.Sprint(conf.Driver.DropletID),
|
||||
Provider: c.String("provider"),
|
||||
State: c.String("state"),
|
||||
Name: conf.Driver.MachineName,
|
||||
Image: conf.Driver.Image,
|
||||
Region: conf.Driver.Region,
|
||||
Size: conf.Driver.Size,
|
||||
OS: c.String("os"),
|
||||
Arch: c.String("arch"),
|
||||
Address: conf.Driver.IPAddress,
|
||||
Capacity: 2,
|
||||
CAKey: cakey,
|
||||
CACert: cacert,
|
||||
TLSKey: tlskey,
|
||||
TLSCert: tlscert,
|
||||
Paused: c.Bool("paused"),
|
||||
Protected: c.Bool("protected"),
|
||||
}
|
||||
|
||||
_, err = client.NodeCreate(node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
format := c.String("format")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, node)
|
||||
}
|
||||
|
||||
type machine struct {
|
||||
DriverName string
|
||||
Driver struct {
|
||||
IPAddress string `json:"IPAddress"`
|
||||
MachineName string `json:"MachineName"`
|
||||
SSHUser string `json:"SSHUser"`
|
||||
SSHPort int `json:"SSHPort"`
|
||||
SSHKeyPath string `json:"SSHKeyPath"`
|
||||
StorePath string `json:"StorePath"`
|
||||
SwarmMaster bool `json:"SwarmMaster"`
|
||||
SwarmHost string `json:"SwarmHost"`
|
||||
SwarmDiscovery string `json:"SwarmDiscovery"`
|
||||
AccessToken string `json:"AccessToken"`
|
||||
DropletID int `json:"DropletID"`
|
||||
DropletName string `json:"DropletName"`
|
||||
Image string `json:"Image"`
|
||||
Region string `json:"Region"`
|
||||
SSHKeyID int `json:"SSHKeyID"`
|
||||
SSHKeyFingerprint string `json:"SSHKeyFingerprint"`
|
||||
SSHKey string `json:"SSHKey"`
|
||||
Size string `json:"Size"`
|
||||
IPv6 bool `json:"IPv6"`
|
||||
Backups bool `json:"Backups"`
|
||||
PrivateNetworking bool `json:"PrivateNetworking"`
|
||||
UserDataFile string `json:"UserDataFile"`
|
||||
Monitoring bool `json:"Monitoring"`
|
||||
Tags string `json:"Tags"`
|
||||
}
|
||||
HostOptions struct {
|
||||
AuthOptions struct {
|
||||
CertDir string `json:"CertDir"`
|
||||
CaCertPath string `json:"CaCertPath"`
|
||||
CaPrivateKeyPath string `json:"CaPrivateKeyPath"`
|
||||
CaCertRemotePath string `json:"CaCertRemotePath"`
|
||||
ServerCertPath string `json:"ServerCertPath"`
|
||||
ServerKeyPath string `json:"ServerKeyPath"`
|
||||
ClientKeyPath string `json:"ClientKeyPath"`
|
||||
ServerCertRemotePath string `json:"ServerCertRemotePath"`
|
||||
ServerKeyRemotePath string `json:"ServerKeyRemotePath"`
|
||||
ClientCertPath string `json:"ClientCertPath"`
|
||||
ServerCertSANs []interface{} `json:"ServerCertSANs"`
|
||||
StorePath string `json:"StorePath"`
|
||||
}
|
||||
}
|
||||
}
|
155
drone/node/node_import_all.go
Normal file
155
drone/node/node_import_all.go
Normal file
@ -0,0 +1,155 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var nodeImportAllCmd = cli.Command{
|
||||
Name: "import-all",
|
||||
Usage: "import all node from docker-machine",
|
||||
Action: nodeImportAll,
|
||||
Flags: []cli.Flag{
|
||||
cli.IntFlag{
|
||||
Name: "capacity",
|
||||
Usage: "node capacity",
|
||||
Value: 2,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "os",
|
||||
Usage: "node os",
|
||||
Value: "linux",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "arch",
|
||||
Usage: "node arch",
|
||||
Value: "amd64",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "paused",
|
||||
Usage: "node is paused",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "protected",
|
||||
Usage: "node is protected from deletion",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "storage-path",
|
||||
Usage: "docker machine storage path",
|
||||
Value: getMachineHome(),
|
||||
EnvVar: "MACHINE_STORAGE_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplNodeInfo,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func nodeImportAll(c *cli.Context) error {
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
home := c.String("storage-path")
|
||||
|
||||
matches, err := filepath.Glob(filepath.Join(home, "machines", "*"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nodes, err := client.NodeList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nodeIndex := map[string]*drone.Node{}
|
||||
for _, node := range nodes {
|
||||
nodeIndex[node.Name] = node
|
||||
}
|
||||
|
||||
format := c.String("format") + "\n"
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range matches {
|
||||
base := filepath.Join(home, "machines", name)
|
||||
|
||||
// if the node already exists it should be
|
||||
// ignored by the system.
|
||||
existing, ok := nodeIndex[name]
|
||||
if ok {
|
||||
tmpl.Execute(os.Stdout, existing)
|
||||
continue
|
||||
}
|
||||
|
||||
conf := new(machine)
|
||||
confpath := filepath.Join(base, "config.json")
|
||||
confdata, err := ioutil.ReadFile(confpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(confdata, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cakey, err := ioutil.ReadFile(conf.HostOptions.AuthOptions.CaPrivateKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacert, err := ioutil.ReadFile(conf.HostOptions.AuthOptions.CaCertPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlskey, err := ioutil.ReadFile(conf.HostOptions.AuthOptions.ClientKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlscert, err := ioutil.ReadFile(conf.HostOptions.AuthOptions.ClientCertPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
node := &drone.Node{
|
||||
UID: fmt.Sprint(conf.Driver.DropletID),
|
||||
Provider: c.String("provider"),
|
||||
State: c.String("state"),
|
||||
Name: conf.Driver.MachineName,
|
||||
Image: conf.Driver.Image,
|
||||
Region: conf.Driver.Region,
|
||||
Size: conf.Driver.Size,
|
||||
OS: c.String("os"),
|
||||
Arch: c.String("arch"),
|
||||
Address: conf.Driver.IPAddress,
|
||||
Capacity: 2,
|
||||
CAKey: cakey,
|
||||
CACert: cacert,
|
||||
TLSKey: tlskey,
|
||||
TLSCert: tlscert,
|
||||
Paused: c.Bool("paused"),
|
||||
Protected: c.Bool("protected"),
|
||||
}
|
||||
|
||||
_, err = client.NodeCreate(node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl.Execute(os.Stdout, node)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
51
drone/node/node_info.go
Normal file
51
drone/node/node_info.go
Normal file
@ -0,0 +1,51 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var nodeInfoCmd = cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display node info",
|
||||
Action: nodeInfo,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplNodeInfo,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func nodeInfo(c *cli.Context) error {
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := c.Args().First()
|
||||
node, err := client.Node(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
format := c.String("format")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, node)
|
||||
}
|
||||
|
||||
var tmplNodeInfo = "\x1b[33m{{ .Name }} \x1b[0m" + `
|
||||
Address: {{ .Address }}
|
||||
Region: {{ .Region }}
|
||||
Instance: {{ .Size }}
|
||||
OS: {{ .OS }}
|
||||
Arch: {{ .Arch }}
|
||||
Locked: {{ .Protected }}
|
||||
Paused: {{ .Paused }}
|
||||
`
|
1
drone/node/node_init.go
Normal file
1
drone/node/node_init.go
Normal file
@ -0,0 +1 @@
|
||||
package node
|
1
drone/node/node_keygen.go
Normal file
1
drone/node/node_keygen.go
Normal file
@ -0,0 +1 @@
|
||||
package node
|
49
drone/node/node_list.go
Normal file
49
drone/node/node_list.go
Normal file
@ -0,0 +1,49 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var nodeListCmd = cli.Command{
|
||||
Name: "ls",
|
||||
Usage: "list nodes",
|
||||
Action: nodeList,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplNodeList,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func nodeList(c *cli.Context) error {
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
list, err := client.NodeList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
format := c.String("format") + "\n"
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, cron := range list {
|
||||
tmpl.Execute(os.Stdout, cron)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// template for node list information
|
||||
var tmplNodeList = "\x1b[33m{{ .Name }} \x1b[0m" + `
|
||||
Address: {{ .Address }}
|
||||
Platform: {{ .OS }}/{{ .Arch }}
|
||||
`
|
1
drone/node/node_update.go
Normal file
1
drone/node/node_update.go
Normal file
@ -0,0 +1 @@
|
||||
package node
|
16
drone/orgsecret/secret.go
Normal file
16
drone/orgsecret/secret.go
Normal file
@ -0,0 +1,16 @@
|
||||
package orgsecret
|
||||
|
||||
import "github.com/urfave/cli"
|
||||
|
||||
// Command exports the secret command.
|
||||
var Command = cli.Command{
|
||||
Name: "orgsecret",
|
||||
Usage: "manage organization secrets",
|
||||
Subcommands: []cli.Command{
|
||||
secretCreateCmd,
|
||||
secretDeleteCmd,
|
||||
secretUpdateCmd,
|
||||
secretInfoCmd,
|
||||
secretListCmd,
|
||||
},
|
||||
}
|
57
drone/orgsecret/secret_add.go
Normal file
57
drone/orgsecret/secret_add.go
Normal file
@ -0,0 +1,57 @@
|
||||
package orgsecret
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var secretCreateCmd = cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a secret",
|
||||
ArgsUsage: "[organization] [name] [data]",
|
||||
Action: secretCreate,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "allow-pull-request",
|
||||
Usage: "permit read access to pull requests",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "allow-push-on-pull-request",
|
||||
Usage: "permit write access to pull requests (e.g. allow docker push)",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func secretCreate(c *cli.Context) error {
|
||||
var (
|
||||
namespace = c.Args().First()
|
||||
name = c.Args().Get(1)
|
||||
data = c.Args().Get(2)
|
||||
)
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
secret := &drone.Secret{
|
||||
Name: name,
|
||||
Data: data,
|
||||
PullRequest: c.Bool("allow-pull-request"),
|
||||
PullRequestPush: c.Bool("allow-push-on-pull-request"),
|
||||
}
|
||||
|
||||
if strings.HasPrefix(secret.Data, "@") {
|
||||
path := strings.TrimPrefix(secret.Data, "@")
|
||||
out, ferr := ioutil.ReadFile(path)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
secret.Data = string(out)
|
||||
}
|
||||
_, err = client.OrgSecretCreate(namespace, secret)
|
||||
return err
|
||||
}
|
45
drone/orgsecret/secret_info.go
Normal file
45
drone/orgsecret/secret_info.go
Normal file
@ -0,0 +1,45 @@
|
||||
package orgsecret
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var secretInfoCmd = cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display secret info",
|
||||
ArgsUsage: "[organization] [name]",
|
||||
Action: secretInfo,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplSecretList,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func secretInfo(c *cli.Context) error {
|
||||
var (
|
||||
namespace = c.Args().First()
|
||||
name = c.Args().Get(1)
|
||||
format = c.String("format") + "\n"
|
||||
)
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
secret, err := client.OrgSecret(namespace, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, secret)
|
||||
}
|
62
drone/orgsecret/secret_list.go
Normal file
62
drone/orgsecret/secret_list.go
Normal file
@ -0,0 +1,62 @@
|
||||
package orgsecret
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var secretListCmd = cli.Command{
|
||||
Name: "ls",
|
||||
Usage: "list secrets",
|
||||
ArgsUsage: "",
|
||||
Action: secretList,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "filter",
|
||||
Usage: "filter output by organization",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplSecretList,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func secretList(c *cli.Context) error {
|
||||
filter := c.String("filter")
|
||||
format := c.String("format") + "\n"
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var list []*drone.Secret
|
||||
if filter == "" {
|
||||
list, err = client.OrgSecretListAll()
|
||||
} else {
|
||||
list, err = client.OrgSecretList(filter)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, secret := range list {
|
||||
tmpl.Execute(os.Stdout, secret)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// template for secret list items
|
||||
var tmplSecretList = "\x1b[33m{{ .Name }} \x1b[0m" + `
|
||||
Organization: {{ .Namespace }}
|
||||
Pull Request Read: {{ .PullRequest }}
|
||||
Pull Request Write: {{ .PullRequestPush }}
|
||||
`
|
27
drone/orgsecret/secret_rm.go
Normal file
27
drone/orgsecret/secret_rm.go
Normal file
@ -0,0 +1,27 @@
|
||||
package orgsecret
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
)
|
||||
|
||||
var secretDeleteCmd = cli.Command{
|
||||
Name: "rm",
|
||||
Usage: "remove a secret",
|
||||
ArgsUsage: "[organization] [name]",
|
||||
Action: secretDelete,
|
||||
Flags: []cli.Flag{},
|
||||
}
|
||||
|
||||
func secretDelete(c *cli.Context) error {
|
||||
var (
|
||||
namespace = c.Args().First()
|
||||
name = c.Args().Get(1)
|
||||
)
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.OrgSecretDelete(namespace, name)
|
||||
}
|
56
drone/orgsecret/secret_set.go
Normal file
56
drone/orgsecret/secret_set.go
Normal file
@ -0,0 +1,56 @@
|
||||
package orgsecret
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var secretUpdateCmd = cli.Command{
|
||||
Name: "update",
|
||||
Usage: "update a secret",
|
||||
ArgsUsage: "[organization] [name] [data]",
|
||||
Action: secretUpdate,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "allow-pull-request",
|
||||
Usage: "permit read access to pull requests",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "allow-push-on-pull-request",
|
||||
Usage: "permit write access to pull requests (e.g. allow docker push)",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func secretUpdate(c *cli.Context) error {
|
||||
var (
|
||||
namespace = c.Args().First()
|
||||
name = c.Args().Get(1)
|
||||
data = c.Args().Get(2)
|
||||
)
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
secret := &drone.Secret{
|
||||
Name: name,
|
||||
Data: data,
|
||||
PullRequest: c.Bool("allow-pull-request"),
|
||||
PullRequestPush: c.Bool("allow-push-on-pull-request"),
|
||||
}
|
||||
if strings.HasPrefix(secret.Data, "@") {
|
||||
path := strings.TrimPrefix(secret.Data, "@")
|
||||
out, ferr := ioutil.ReadFile(path)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
secret.Data = string(out)
|
||||
}
|
||||
_, err = client.OrgSecretUpdate(namespace, secret)
|
||||
return err
|
||||
}
|
64
drone/plugins/admit/admit.go
Normal file
64
drone/plugins/admit/admit.go
Normal file
@ -0,0 +1,64 @@
|
||||
package admit
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/drone-go/plugin/admission"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the admission command set.
|
||||
var Command = cli.Command{
|
||||
Name: "admit",
|
||||
Usage: "test user admission",
|
||||
ArgsUsage: "user",
|
||||
Action: admit,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "user",
|
||||
Usage: "username",
|
||||
},
|
||||
|
||||
cli.StringFlag{
|
||||
Name: "endpoint",
|
||||
Usage: "plugin endpoint",
|
||||
EnvVar: "DRONE_ADMISSION_ENDPOINT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "secret",
|
||||
Usage: "plugin secret",
|
||||
EnvVar: "DRONE_ADMISSION_SECRET",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ssl-skip-verify",
|
||||
Usage: "plugin ssl verification disabled",
|
||||
EnvVar: "DRONE_ADMISSION_SKIP_VERIFY",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func admit(c *cli.Context) error {
|
||||
login := c.String("user")
|
||||
if login == "" {
|
||||
login = c.Args().First()
|
||||
}
|
||||
|
||||
req := &admission.Request{
|
||||
User: drone.User{
|
||||
Login: login,
|
||||
},
|
||||
}
|
||||
|
||||
client := admission.Client(
|
||||
c.String("endpoint"),
|
||||
c.String("secret"),
|
||||
c.Bool("ssl-skip-verify"),
|
||||
)
|
||||
_, err := client.Admit(context.Background(), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
12
drone/plugins/config/config.go
Normal file
12
drone/plugins/config/config.go
Normal file
@ -0,0 +1,12 @@
|
||||
package config
|
||||
|
||||
import "github.com/urfave/cli"
|
||||
|
||||
// Command exports the registry command set.
|
||||
var Command = cli.Command{
|
||||
Name: "config",
|
||||
Usage: "config plugin helpers",
|
||||
Subcommands: []cli.Command{
|
||||
configFindCmd,
|
||||
},
|
||||
}
|
106
drone/plugins/config/get.go
Normal file
106
drone/plugins/config/get.go
Normal file
@ -0,0 +1,106 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/drone-go/plugin/config"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var configFindCmd = cli.Command{
|
||||
Name: "get",
|
||||
Usage: "get the pipeline configuration",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: configFind,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "ref",
|
||||
Usage: "git reference",
|
||||
Value: "refs/heads/master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "source",
|
||||
Usage: "source branch",
|
||||
Value: "master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "target",
|
||||
Usage: "target branch",
|
||||
Value: "master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "before",
|
||||
Usage: "commit sha before the change",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "after",
|
||||
Usage: "commit sha after the change",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "path",
|
||||
Usage: "configuration file path",
|
||||
Value: ".drone.jsonnet",
|
||||
},
|
||||
|
||||
// TODO(bradrydzewski) these parameters should
|
||||
// be defined globally for all plugin commands.
|
||||
|
||||
cli.StringFlag{
|
||||
Name: "endpoint",
|
||||
Usage: "plugin endpoint",
|
||||
EnvVar: "DRONE_YAML_ENDPOINT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "secret",
|
||||
Usage: "plugin secret",
|
||||
EnvVar: "DRONE_YAML_SECRET",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ssl-skip-verify",
|
||||
Usage: "plugin ssl verification disabled",
|
||||
EnvVar: "DRONE_YAML_SKIP_VERIFY",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func configFind(c *cli.Context) error {
|
||||
slug := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(slug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo := drone.Repo{
|
||||
Namespace: owner,
|
||||
Name: name,
|
||||
Slug: slug,
|
||||
Config: c.String("path"),
|
||||
}
|
||||
|
||||
build := drone.Build{
|
||||
Ref: c.String("ref"),
|
||||
Before: c.String("before"),
|
||||
After: c.String("after"),
|
||||
Source: c.String("source"),
|
||||
Target: c.String("target"),
|
||||
}
|
||||
|
||||
req := &config.Request{
|
||||
Repo: repo,
|
||||
Build: build,
|
||||
}
|
||||
|
||||
client := config.Client(
|
||||
c.String("endpoint"),
|
||||
c.String("secret"),
|
||||
c.Bool("ssl-skip-verify"),
|
||||
)
|
||||
res, err := client.Find(context.Background(), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
println(res.Data)
|
||||
return nil
|
||||
}
|
122
drone/plugins/convert/convert.go
Normal file
122
drone/plugins/convert/convert.go
Normal file
@ -0,0 +1,122 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/drone-go/plugin/converter"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the registry command set.
|
||||
var Command = cli.Command{
|
||||
Name: "convert",
|
||||
Usage: "convert the pipeline configuration",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: convert,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "path",
|
||||
Usage: "path to the configuration file",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ref",
|
||||
Usage: "git reference",
|
||||
Value: "refs/heads/master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "source",
|
||||
Usage: "source branch",
|
||||
Value: "master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "target",
|
||||
Usage: "target branch",
|
||||
Value: "master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "before",
|
||||
Usage: "commit sha before the change",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "after",
|
||||
Usage: "commit sha after the change",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repository",
|
||||
Usage: "repository name",
|
||||
},
|
||||
|
||||
// TODO(bradrydzewski) these parameters should
|
||||
// be defined globally for all plugin commands.
|
||||
|
||||
cli.StringFlag{
|
||||
Name: "endpoint",
|
||||
Usage: "plugin endpoint",
|
||||
EnvVar: "DRONE_CONVERT_ENDPOINT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "secret",
|
||||
Usage: "plugin secret",
|
||||
EnvVar: "DRONE_CONVERT_SECRET",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ssl-skip-verify",
|
||||
Usage: "plugin ssl verification disabled",
|
||||
EnvVar: "DRONE_CONVERT_SKIP_VERIFY",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func convert(c *cli.Context) error {
|
||||
slug := c.String("repository")
|
||||
owner, name, _ := internal.ParseRepo(slug)
|
||||
|
||||
path := c.String("path")
|
||||
if path == "" {
|
||||
path = c.Args().First()
|
||||
}
|
||||
|
||||
raw, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req := &converter.Request{
|
||||
Repo: drone.Repo{
|
||||
Namespace: owner,
|
||||
Name: name,
|
||||
Slug: slug,
|
||||
Config: path,
|
||||
},
|
||||
Build: drone.Build{
|
||||
Ref: c.String("ref"),
|
||||
Before: c.String("before"),
|
||||
After: c.String("after"),
|
||||
Source: c.String("source"),
|
||||
Target: c.String("target"),
|
||||
},
|
||||
Config: drone.Config{
|
||||
Data: string(raw),
|
||||
},
|
||||
}
|
||||
|
||||
client := converter.Client(
|
||||
c.String("endpoint"),
|
||||
c.String("secret"),
|
||||
c.Bool("ssl-skip-verify"),
|
||||
)
|
||||
res, err := client.Convert(context.Background(), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch {
|
||||
case res == nil:
|
||||
println(string(raw))
|
||||
case res != nil:
|
||||
println(res.Data)
|
||||
}
|
||||
return nil
|
||||
}
|
24
drone/plugins/plugins.go
Normal file
24
drone/plugins/plugins.go
Normal file
@ -0,0 +1,24 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"github.com/drone/drone-cli/drone/plugins/admit"
|
||||
"github.com/drone/drone-cli/drone/plugins/config"
|
||||
"github.com/drone/drone-cli/drone/plugins/convert"
|
||||
"github.com/drone/drone-cli/drone/plugins/registry"
|
||||
"github.com/drone/drone-cli/drone/plugins/secret"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the registry command set.
|
||||
var Command = cli.Command{
|
||||
Name: "plugins",
|
||||
Usage: "plugin helper functions",
|
||||
Subcommands: []cli.Command{
|
||||
admit.Command,
|
||||
config.Command,
|
||||
convert.Command,
|
||||
secret.Command,
|
||||
registry.Command,
|
||||
},
|
||||
}
|
123
drone/plugins/registry/list.go
Normal file
123
drone/plugins/registry/list.go
Normal file
@ -0,0 +1,123 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/drone-go/plugin/registry"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var registryListCmd = cli.Command{
|
||||
Name: "list",
|
||||
Usage: "list the registry credentials",
|
||||
Action: registryList,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "ref",
|
||||
Usage: "git reference",
|
||||
Value: "refs/heads/master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "source",
|
||||
Usage: "source branch",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "target",
|
||||
Usage: "target branch",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "before",
|
||||
Usage: "commit sha before the change",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "after",
|
||||
Usage: "commit sha after the change",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "event",
|
||||
Usage: "build event",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo",
|
||||
Usage: "repository name",
|
||||
},
|
||||
|
||||
// TODO(bradrydzewski) these parameters should
|
||||
// be defined globally for all plugin commands.
|
||||
|
||||
cli.StringFlag{
|
||||
Name: "endpoint",
|
||||
Usage: "plugin endpoint",
|
||||
EnvVar: "DRONE_REGISTRY_ENDPOINT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "secret",
|
||||
Usage: "plugin secret",
|
||||
EnvVar: "DRONE_REGISTRY_SECRET",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ssl-skip-verify",
|
||||
Usage: "plugin ssl verification disabled",
|
||||
EnvVar: "DRONE_REGISTRY_VERIFY",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Value: tmplList,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func registryList(c *cli.Context) error {
|
||||
slug := c.String("repo")
|
||||
owner, name, _ := internal.ParseRepo(slug)
|
||||
|
||||
repo := drone.Repo{
|
||||
Namespace: owner,
|
||||
Name: name,
|
||||
Slug: slug,
|
||||
}
|
||||
|
||||
build := drone.Build{
|
||||
Ref: c.String("ref"),
|
||||
Before: c.String("before"),
|
||||
After: c.String("after"),
|
||||
Source: c.String("source"),
|
||||
Target: c.String("target"),
|
||||
Event: c.String("event"),
|
||||
}
|
||||
|
||||
req := ®istry.Request{
|
||||
Repo: repo,
|
||||
Build: build,
|
||||
}
|
||||
|
||||
client := registry.Client(
|
||||
c.String("endpoint"),
|
||||
c.String("secret"),
|
||||
c.Bool("ssl-skip-verify"),
|
||||
)
|
||||
list, err := client.List(context.Background(), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
format := c.String("format") + "\n"
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range list {
|
||||
tmpl.Execute(os.Stdout, item)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var tmplList = "\x1b[33m{{ .Address }} \x1b[0m" + `
|
||||
Username: {{ .Username }}
|
||||
Password: {{ .Password }}
|
||||
`
|
@ -5,12 +5,8 @@ import "github.com/urfave/cli"
|
||||
// Command exports the registry command set.
|
||||
var Command = cli.Command{
|
||||
Name: "registry",
|
||||
Usage: "manage registries",
|
||||
Usage: "registry plugin helpers",
|
||||
Subcommands: []cli.Command{
|
||||
registryCreateCmd,
|
||||
registryDeleteCmd,
|
||||
registryUpdateCmd,
|
||||
registryInfoCmd,
|
||||
registryListCmd,
|
||||
},
|
||||
}
|
112
drone/plugins/secret/get.go
Normal file
112
drone/plugins/secret/get.go
Normal file
@ -0,0 +1,112 @@
|
||||
package secret
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/drone-go/plugin/secret"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var secretFindCmd = cli.Command{
|
||||
Name: "get",
|
||||
Usage: "get the named secret",
|
||||
ArgsUsage: "secret",
|
||||
Action: secretFind,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "ref",
|
||||
Usage: "git reference",
|
||||
Value: "refs/heads/master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "source",
|
||||
Usage: "source branch",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "target",
|
||||
Usage: "target branch",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "before",
|
||||
Usage: "commit sha before the change",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "after",
|
||||
Usage: "commit sha after the change",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "event",
|
||||
Usage: "build event",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo",
|
||||
Usage: "repository name",
|
||||
},
|
||||
|
||||
// TODO(bradrydzewski) these parameters should
|
||||
// be defined globally for all plugin commands.
|
||||
|
||||
cli.StringFlag{
|
||||
Name: "endpoint",
|
||||
Usage: "plugin endpoint",
|
||||
EnvVar: "DRONE_SECRET_ENDPOINT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "secret",
|
||||
Usage: "plugin secret",
|
||||
EnvVar: "DRONE_SECRET_SECRET",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ssl-skip-verify",
|
||||
Usage: "plugin ssl verification disabled",
|
||||
EnvVar: "DRONE_SECRET_VERIFY",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func secretFind(c *cli.Context) error {
|
||||
path := c.Args().First()
|
||||
key := c.Args().Get(1)
|
||||
|
||||
slug := c.String("repo")
|
||||
owner, name, err := internal.ParseRepo(slug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo := drone.Repo{
|
||||
Namespace: owner,
|
||||
Name: name,
|
||||
Slug: slug,
|
||||
}
|
||||
|
||||
build := drone.Build{
|
||||
Ref: c.String("ref"),
|
||||
Before: c.String("before"),
|
||||
After: c.String("after"),
|
||||
Source: c.String("source"),
|
||||
Target: c.String("target"),
|
||||
Event: c.String("event"),
|
||||
}
|
||||
|
||||
req := &secret.Request{
|
||||
Path: path,
|
||||
Name: key,
|
||||
Repo: repo,
|
||||
Build: build,
|
||||
}
|
||||
|
||||
client := secret.Client(
|
||||
c.String("endpoint"),
|
||||
c.String("secret"),
|
||||
c.Bool("ssl-skip-verify"),
|
||||
)
|
||||
res, err := client.Find(context.Background(), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
println(res.Data)
|
||||
return nil
|
||||
}
|
12
drone/plugins/secret/secret.go
Normal file
12
drone/plugins/secret/secret.go
Normal file
@ -0,0 +1,12 @@
|
||||
package secret
|
||||
|
||||
import "github.com/urfave/cli"
|
||||
|
||||
// Command exports the registry command set.
|
||||
var Command = cli.Command{
|
||||
Name: "secret",
|
||||
Usage: "secret plugin helpers",
|
||||
Subcommands: []cli.Command{
|
||||
secretFindCmd,
|
||||
},
|
||||
}
|
14
drone/queue/queue.go
Normal file
14
drone/queue/queue.go
Normal file
@ -0,0 +1,14 @@
|
||||
package queue
|
||||
|
||||
import "github.com/urfave/cli"
|
||||
|
||||
// Command exports the queue command set.
|
||||
var Command = cli.Command{
|
||||
Name: "queue",
|
||||
Usage: "queue operations",
|
||||
Subcommands: []cli.Command{
|
||||
queueListCmd,
|
||||
queuePauseCmd,
|
||||
queueResumeCmd,
|
||||
},
|
||||
}
|
59
drone/queue/queue_list.go
Normal file
59
drone/queue/queue_list.go
Normal file
@ -0,0 +1,59 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var queueListCmd = cli.Command{
|
||||
Name: "ls",
|
||||
Usage: "list queue items",
|
||||
Action: queueList,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplStage,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func queueList(c *cli.Context) (err error) {
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
builds, err := client.Queue()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(builds) == 0 {
|
||||
fmt.Println("there are no pending or running builds")
|
||||
return nil
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, build := range builds {
|
||||
tmpl.Execute(os.Stdout, build)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var tmplStage = "\x1b[33mitem #{{ .ID }} \x1b[0m" + `
|
||||
Status: {{ .Status }}
|
||||
Machine: {{ .Machine }}
|
||||
OS: {{ .OS }}
|
||||
Arch: {{ .Arch }}
|
||||
Variant: {{ .Variant }}
|
||||
Version: {{ .Kernel }}
|
||||
`
|
20
drone/queue/queue_pause.go
Normal file
20
drone/queue/queue_pause.go
Normal file
@ -0,0 +1,20 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var queuePauseCmd = cli.Command{
|
||||
Name: "pause",
|
||||
Usage: "pause queue operations",
|
||||
Action: queuePause,
|
||||
}
|
||||
|
||||
func queuePause(c *cli.Context) (err error) {
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.QueuePause()
|
||||
}
|
20
drone/queue/queue_resume.go
Normal file
20
drone/queue/queue_resume.go
Normal file
@ -0,0 +1,20 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var queueResumeCmd = cli.Command{
|
||||
Name: "resume",
|
||||
Usage: "resume queue operations",
|
||||
Action: queueResume,
|
||||
}
|
||||
|
||||
func queueResume(c *cli.Context) (err error) {
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.QueueResume()
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var registryCreateCmd = cli.Command{
|
||||
Name: "add",
|
||||
Usage: "adds a registry",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: registryCreate,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "repository",
|
||||
Usage: "repository name (e.g. octocat/hello-world)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "hostname",
|
||||
Usage: "registry hostname",
|
||||
Value: "docker.io",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "username",
|
||||
Usage: "registry username",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "password",
|
||||
Usage: "registry password",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func registryCreate(c *cli.Context) error {
|
||||
var (
|
||||
hostname = c.String("hostname")
|
||||
username = c.String("username")
|
||||
password = c.String("password")
|
||||
reponame = c.String("repository")
|
||||
)
|
||||
if reponame == "" {
|
||||
reponame = c.Args().First()
|
||||
}
|
||||
owner, name, err := internal.ParseRepo(reponame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
registry := &drone.Registry{
|
||||
Address: hostname,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
if strings.HasPrefix(registry.Password, "@") {
|
||||
path := strings.TrimPrefix(registry.Password, "@")
|
||||
out, ferr := ioutil.ReadFile(path)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
registry.Password = string(out)
|
||||
}
|
||||
_, err = client.RegistryCreate(owner, name, registry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var registryInfoCmd = cli.Command{
|
||||
Name: "info",
|
||||
Usage: "display registry info",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: registryInfo,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "repository",
|
||||
Usage: "repository name (e.g. octocat/hello-world)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "hostname",
|
||||
Usage: "registry hostname",
|
||||
Value: "docker.io",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplRegistryList,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func registryInfo(c *cli.Context) error {
|
||||
var (
|
||||
hostname = c.String("hostname")
|
||||
reponame = c.String("repository")
|
||||
format = c.String("format") + "\n"
|
||||
)
|
||||
if reponame == "" {
|
||||
reponame = c.Args().First()
|
||||
}
|
||||
owner, name, err := internal.ParseRepo(reponame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
registry, err := client.Registry(owner, name, hostname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpl, err := template.New("_").Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, registry)
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
)
|
||||
|
||||
var registryListCmd = cli.Command{
|
||||
Name: "ls",
|
||||
Usage: "list registries",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: registryList,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "repository",
|
||||
Usage: "repository name (e.g. octocat/hello-world)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplRegistryList,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func registryList(c *cli.Context) error {
|
||||
var (
|
||||
format = c.String("format") + "\n"
|
||||
reponame = c.String("repository")
|
||||
)
|
||||
if reponame == "" {
|
||||
reponame = c.Args().First()
|
||||
}
|
||||
owner, name, err := internal.ParseRepo(reponame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
list, err := client.RegistryList(owner, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpl, err := template.New("_").Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, registry := range list {
|
||||
tmpl.Execute(os.Stdout, registry)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// template for build list information
|
||||
var tmplRegistryList = "\x1b[33m{{ .Address }} \x1b[0m" + `
|
||||
Username: {{ .Username }}
|
||||
Email: {{ .Email }}
|
||||
`
|
@ -1,44 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var registryDeleteCmd = cli.Command{
|
||||
Name: "rm",
|
||||
Usage: "remove a registry",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: registryDelete,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "repository",
|
||||
Usage: "repository name (e.g. octocat/hello-world)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "hostname",
|
||||
Usage: "registry hostname",
|
||||
Value: "docker.io",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func registryDelete(c *cli.Context) error {
|
||||
var (
|
||||
hostname = c.String("hostname")
|
||||
reponame = c.String("repository")
|
||||
)
|
||||
if reponame == "" {
|
||||
reponame = c.Args().First()
|
||||
}
|
||||
owner, name, err := internal.ParseRepo(reponame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.RegistryDelete(owner, name, hostname)
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var registryUpdateCmd = cli.Command{
|
||||
Name: "update",
|
||||
Usage: "update a registry",
|
||||
ArgsUsage: "[repo/name]",
|
||||
Action: registryUpdate,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "repository",
|
||||
Usage: "repository name (e.g. octocat/hello-world)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "hostname",
|
||||
Usage: "registry hostname",
|
||||
Value: "docker.io",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "username",
|
||||
Usage: "registry username",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "password",
|
||||
Usage: "registry password",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func registryUpdate(c *cli.Context) error {
|
||||
var (
|
||||
hostname = c.String("hostname")
|
||||
username = c.String("username")
|
||||
password = c.String("password")
|
||||
reponame = c.String("repository")
|
||||
)
|
||||
if reponame == "" {
|
||||
reponame = c.Args().First()
|
||||
}
|
||||
owner, name, err := internal.ParseRepo(reponame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
registry := &drone.Registry{
|
||||
Address: hostname,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
if strings.HasPrefix(registry.Password, "@") {
|
||||
path := strings.TrimPrefix(registry.Password, "@")
|
||||
out, ferr := ioutil.ReadFile(path)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
registry.Password = string(out)
|
||||
}
|
||||
_, err = client.RegistryUpdate(owner, name, registry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -8,8 +8,8 @@ import (
|
||||
)
|
||||
|
||||
var repoAddCmd = cli.Command{
|
||||
Name: "add",
|
||||
Usage: "add a repository",
|
||||
Name: "enable",
|
||||
Usage: "enable a repository",
|
||||
ArgsUsage: "<repo/name>",
|
||||
Action: repoAdd,
|
||||
}
|
||||
@ -26,7 +26,7 @@ func repoAdd(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := client.RepoPost(owner, name); err != nil {
|
||||
if _, err := client.RepoEnable(owner, name); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Successfully activated repository %s/%s\n", owner, name)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@ -39,7 +40,7 @@ func repoInfo(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format"))
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -47,13 +48,12 @@ func repoInfo(c *cli.Context) error {
|
||||
}
|
||||
|
||||
// template for repo information
|
||||
var tmplRepoInfo = `Owner: {{ .Owner }}
|
||||
var tmplRepoInfo = `Owner: {{ .Namespace }}
|
||||
Repo: {{ .Name }}
|
||||
Type: {{ .Kind }}
|
||||
Config: {{ .Config }}
|
||||
Visibility: {{ .Visibility }}
|
||||
Private: {{ .IsPrivate }}
|
||||
Trusted: {{ .IsTrusted }}
|
||||
Gated: {{ .IsGated }}
|
||||
Remote: {{ .Clone }}
|
||||
Private: {{ .Private }}
|
||||
Trusted: {{ .Trusted }}
|
||||
Protected: {{ .Protected }}
|
||||
Remote: {{ .HTTPURL }}
|
||||
`
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@ -23,6 +24,10 @@ var repoListCmd = cli.Command{
|
||||
Name: "org",
|
||||
Usage: "filter by organization",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "active",
|
||||
Usage: "filter active repositories only",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -37,14 +42,17 @@ func repoList(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
org := c.String("org")
|
||||
org, active := c.String("org"), c.Bool("active")
|
||||
for _, repo := range repos {
|
||||
if org != "" && org != repo.Owner {
|
||||
if org != "" && org != repo.Namespace {
|
||||
continue
|
||||
}
|
||||
if !repo.Active && active {
|
||||
continue
|
||||
}
|
||||
tmpl.Execute(os.Stdout, repo)
|
||||
@ -53,4 +61,4 @@ func repoList(c *cli.Context) error {
|
||||
}
|
||||
|
||||
// template for repository list items
|
||||
var tmplRepoList = `{{ .FullName }}`
|
||||
var tmplRepoList = `{{ .Slug }}`
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
)
|
||||
|
||||
var repoRemoveCmd = cli.Command{
|
||||
Name: "rm",
|
||||
Usage: "remove a repository",
|
||||
Name: "disable",
|
||||
Usage: "disable a repository",
|
||||
ArgsUsage: "<repo/name>",
|
||||
Action: repoRemove,
|
||||
}
|
||||
@ -27,7 +27,7 @@ func repoRemove(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := client.RepoDel(owner, name); err != nil {
|
||||
if err := client.RepoDisable(owner, name); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Successfully removed repository %s/%s\n", owner, name)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@ -28,21 +29,17 @@ func repoSync(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
repos, err := client.RepoListOpts(true, true)
|
||||
repos, err := client.RepoListSync()
|
||||
if err != nil || len(repos) == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).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
|
||||
|
@ -21,8 +21,8 @@ var repoUpdateCmd = cli.Command{
|
||||
Usage: "repository is trusted",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "gated",
|
||||
Usage: "repository is gated",
|
||||
Name: "protected",
|
||||
Usage: "repository is protected",
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "timeout",
|
||||
@ -32,6 +32,22 @@ var repoUpdateCmd = cli.Command{
|
||||
Name: "visibility",
|
||||
Usage: "repository visibility",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "ignore-forks",
|
||||
Usage: "ignore forks",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "ignore-pull-requests",
|
||||
Usage: "ignore pull requests",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "auto-cancel-pull-requests",
|
||||
Usage: "automatically cancel pending pull request builds",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "auto-cancel-pushes",
|
||||
Usage: "automatically cancel pending push builds",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "config",
|
||||
Usage: "repository configuration path (e.g. .drone.yml)",
|
||||
@ -64,17 +80,21 @@ func repoUpdate(c *cli.Context) error {
|
||||
config = c.String("config")
|
||||
timeout = c.Duration("timeout")
|
||||
trusted = c.Bool("trusted")
|
||||
gated = c.Bool("gated")
|
||||
protected = c.Bool("protected")
|
||||
ignoreForks = c.Bool("ignore-forks")
|
||||
ignorePulls = c.Bool("ignore-pull-requests")
|
||||
cancelPulls = c.Bool("auto-cancel-pull-requests")
|
||||
cancelPush = c.Bool("auto-cancel-pushes")
|
||||
buildCounter = c.Int("build-counter")
|
||||
unsafe = c.Bool("unsafe")
|
||||
)
|
||||
|
||||
patch := new(drone.RepoPatch)
|
||||
if c.IsSet("trusted") {
|
||||
patch.IsTrusted = &trusted
|
||||
patch.Trusted = &trusted
|
||||
}
|
||||
if c.IsSet("gated") {
|
||||
patch.IsGated = &gated
|
||||
if c.IsSet("protected") {
|
||||
patch.Protected = &protected
|
||||
}
|
||||
if c.IsSet("timeout") {
|
||||
v := int64(timeout / time.Minute)
|
||||
@ -83,6 +103,18 @@ func repoUpdate(c *cli.Context) error {
|
||||
if c.IsSet("config") {
|
||||
patch.Config = &config
|
||||
}
|
||||
if c.IsSet("ignore-forks") {
|
||||
patch.IgnoreForks = &ignoreForks
|
||||
}
|
||||
if c.IsSet("ignore-pull-requests") {
|
||||
patch.IgnorePulls = &ignorePulls
|
||||
}
|
||||
if c.IsSet("auto-cancel-pull-requests") {
|
||||
patch.CancelPulls = &cancelPulls
|
||||
}
|
||||
if c.IsSet("auto-cancel-pushes") {
|
||||
patch.CancelPush = &cancelPush
|
||||
}
|
||||
if c.IsSet("visibility") {
|
||||
switch visibility {
|
||||
case "public", "private", "internal":
|
||||
@ -93,10 +125,10 @@ func repoUpdate(c *cli.Context) error {
|
||||
fmt.Printf("Setting the build counter is an unsafe operation that could put your repository in an inconsistent state. Please use --unsafe to proceed")
|
||||
}
|
||||
if c.IsSet("build-counter") && unsafe {
|
||||
patch.BuildCounter = &buildCounter
|
||||
patch.Counter = &buildCounter
|
||||
}
|
||||
|
||||
if _, err := client.RepoPatch(owner, name, patch); err != nil {
|
||||
if _, err := client.RepoUpdate(owner, name, patch); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Successfully updated repository %s/%s\n", owner, name)
|
||||
|
@ -25,16 +25,16 @@ var secretCreateCmd = cli.Command{
|
||||
Usage: "secret name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "value",
|
||||
Name: "data",
|
||||
Usage: "secret value",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "event",
|
||||
Usage: "secret limited to these events",
|
||||
cli.BoolFlag{
|
||||
Name: "allow-pull-request",
|
||||
Usage: "permit read access to pull requests",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "image",
|
||||
Usage: "secret limited to these images",
|
||||
cli.BoolFlag{
|
||||
Name: "allow-push-on-pull-request",
|
||||
Usage: "permit write access to pull requests (e.g. allow docker push)",
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -54,27 +54,19 @@ func secretCreate(c *cli.Context) error {
|
||||
}
|
||||
secret := &drone.Secret{
|
||||
Name: c.String("name"),
|
||||
Value: c.String("value"),
|
||||
Images: c.StringSlice("image"),
|
||||
Events: c.StringSlice("event"),
|
||||
Data: c.String("data"),
|
||||
PullRequest: c.Bool("allow-pull-request"),
|
||||
PullRequestPush: c.Bool("allow-push-on-pull-request"),
|
||||
}
|
||||
if len(secret.Events) == 0 {
|
||||
secret.Events = defaultSecretEvents
|
||||
}
|
||||
if strings.HasPrefix(secret.Value, "@") {
|
||||
path := strings.TrimPrefix(secret.Value, "@")
|
||||
|
||||
if strings.HasPrefix(secret.Data, "@") {
|
||||
path := strings.TrimPrefix(secret.Data, "@")
|
||||
out, ferr := ioutil.ReadFile(path)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
secret.Value = string(out)
|
||||
secret.Data = string(out)
|
||||
}
|
||||
_, err = client.SecretCreate(owner, name, secret)
|
||||
return err
|
||||
}
|
||||
|
||||
var defaultSecretEvents = []string{
|
||||
drone.EventPush,
|
||||
drone.EventTag,
|
||||
drone.EventDeploy,
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var secretInfoCmd = cli.Command{
|
||||
@ -28,7 +28,6 @@ var secretInfoCmd = cli.Command{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplSecretList,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -57,7 +56,7 @@ func secretInfo(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpl, err := template.New("_").Funcs(secretFuncMap).Parse(format)
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -3,11 +3,10 @@ package secret
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var secretListCmd = cli.Command{
|
||||
@ -24,7 +23,6 @@ var secretListCmd = cli.Command{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplSecretList,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -49,28 +47,18 @@ func secretList(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpl, err := template.New("_").Funcs(secretFuncMap).Parse(format)
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, registry := range list {
|
||||
tmpl.Execute(os.Stdout, registry)
|
||||
for _, secret := range list {
|
||||
tmpl.Execute(os.Stdout, secret)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// template for secret list items
|
||||
var tmplSecretList = "\x1b[33m{{ .Name }} \x1b[0m" + `
|
||||
Events: {{ list .Events }}
|
||||
{{- if .Images }}
|
||||
Images: {{ list .Images }}
|
||||
{{- else }}
|
||||
Images: <any>
|
||||
{{- end }}
|
||||
Pull Request Read: {{ .PullRequest }}
|
||||
Pull Request Write: {{ .PullRequestPush }}
|
||||
`
|
||||
|
||||
var secretFuncMap = template.FuncMap{
|
||||
"list": func(s []string) string {
|
||||
return strings.Join(s, ", ")
|
||||
},
|
||||
}
|
||||
|
@ -25,16 +25,16 @@ var secretUpdateCmd = cli.Command{
|
||||
Usage: "secret name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "value",
|
||||
Name: "data",
|
||||
Usage: "secret value",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "event",
|
||||
Usage: "secret limited to these events",
|
||||
cli.BoolFlag{
|
||||
Name: "allow-pull-request",
|
||||
Usage: "permit read access to pull requests",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "image",
|
||||
Usage: "secret limited to these images",
|
||||
cli.BoolFlag{
|
||||
Name: "allow-push-on-pull-request",
|
||||
Usage: "permit write access to pull requests (e.g. allow docker push)",
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -54,17 +54,17 @@ func secretUpdate(c *cli.Context) error {
|
||||
}
|
||||
secret := &drone.Secret{
|
||||
Name: c.String("name"),
|
||||
Value: c.String("value"),
|
||||
Images: c.StringSlice("image"),
|
||||
Events: c.StringSlice("event"),
|
||||
Data: c.String("data"),
|
||||
PullRequest: c.Bool("allow-pull-request"),
|
||||
PullRequestPush: c.Bool("allow-push-on-pull-request"),
|
||||
}
|
||||
if strings.HasPrefix(secret.Value, "@") {
|
||||
path := strings.TrimPrefix(secret.Value, "@")
|
||||
if strings.HasPrefix(secret.Data, "@") {
|
||||
path := strings.TrimPrefix(secret.Data, "@")
|
||||
out, ferr := ioutil.ReadFile(path)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
secret.Value = string(out)
|
||||
secret.Data = string(out)
|
||||
}
|
||||
_, err = client.SecretUpdate(owner, name, secret)
|
||||
return err
|
||||
|
@ -4,21 +4,20 @@ import (
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var serverCreateCmd = cli.Command{
|
||||
Name: "create",
|
||||
Usage: "crate a new server",
|
||||
Usage: "create a new server",
|
||||
Action: serverCreate,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplServerCreate,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -34,7 +33,7 @@ func serverCreate(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var serverDestroyCmd = cli.Command{
|
||||
@ -20,7 +20,10 @@ var serverDestroyCmd = cli.Command{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplServerDestroy,
|
||||
Hidden: true,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "force",
|
||||
Usage: "force destroy",
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -36,7 +39,7 @@ func serverDestroy(c *cli.Context) error {
|
||||
return fmt.Errorf("Missing or invalid server name")
|
||||
}
|
||||
|
||||
err = client.ServerDelete(name)
|
||||
err = client.ServerDelete(name, c.Bool("force"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -46,7 +49,7 @@ func serverDestroy(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ import (
|
||||
"path"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var serverEnvCmd = cli.Command{
|
||||
@ -108,7 +108,7 @@ func serverEnv(c *cli.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
var shellT = template.Must(template.New("_").Parse(`
|
||||
var shellT = template.Must(template.New("_").Funcs(funcmap.Funcs).Parse(`
|
||||
{{- if eq .Shell "fish" -}}
|
||||
sex -x DOCKER_TLS "1";
|
||||
set -x DOCKER_TLS_VERIFY "";
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var serverInfoCmd = cli.Command{
|
||||
@ -20,7 +20,6 @@ var serverInfoCmd = cli.Command{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplServerInfo,
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -41,7 +40,7 @@ func serverInfo(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"github.com/drone/funcmap"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var serverListCmd = cli.Command{
|
||||
@ -20,23 +20,26 @@ var serverListCmd = cli.Command{
|
||||
ArgsUsage: " ",
|
||||
Action: serverList,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "s, state",
|
||||
Usage: "filter by state",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "a",
|
||||
Name: "a, all",
|
||||
Usage: "include stopped servers",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "l",
|
||||
Name: "l, long",
|
||||
Usage: "list in long format",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "H",
|
||||
Usage: "include columne headers",
|
||||
Name: "H, headers",
|
||||
Usage: "include column headers",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Value: tmplServerList,
|
||||
Hidden: true,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "la",
|
||||
@ -50,6 +53,7 @@ func serverList(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := c.String("s")
|
||||
a := c.Bool("a")
|
||||
l := c.Bool("l")
|
||||
h := c.BoolT("H")
|
||||
@ -65,11 +69,11 @@ func serverList(c *cli.Context) error {
|
||||
}
|
||||
|
||||
if l && h {
|
||||
printLong(servers, a, h)
|
||||
printLong(servers, s, a, h)
|
||||
return nil
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
tmpl, err := template.New("_").Funcs(funcmap.Funcs).Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -78,12 +82,17 @@ func serverList(c *cli.Context) error {
|
||||
if !a && server.State == "stopped" {
|
||||
continue
|
||||
}
|
||||
|
||||
if s != "" && s != server.State {
|
||||
continue
|
||||
}
|
||||
|
||||
tmpl.Execute(os.Stdout, server)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printLong(servers []*drone.Server, a, h bool) {
|
||||
func printLong(servers []*drone.Server, s string, a, h bool) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
|
||||
if h {
|
||||
fmt.Fprintln(w, "Name\tAddress\tState\tCreated")
|
||||
@ -92,6 +101,9 @@ func printLong(servers []*drone.Server, a, h bool) {
|
||||
if !a && server.State == "stopped" {
|
||||
continue
|
||||
}
|
||||
if s != "" && s != server.State {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\n",
|
||||
server.Name,
|
||||
server.Address,
|
||||
|
63
drone/sign/sign.go
Normal file
63
drone/sign/sign.go
Normal file
@ -0,0 +1,63 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/drone/drone-cli/drone/internal"
|
||||
"github.com/drone/drone-yaml/yaml/signer"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Command exports the sign command.
|
||||
var Command = cli.Command{
|
||||
Name: "sign",
|
||||
Usage: "sign the yaml file",
|
||||
ArgsUsage: "<source>",
|
||||
Action: format,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "save",
|
||||
Usage: "save result to source",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func format(c *cli.Context) error {
|
||||
repo := c.Args().First()
|
||||
owner, name, err := internal.ParseRepo(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path := c.Args().Get(1)
|
||||
if path == "" {
|
||||
path = ".drone.yml"
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hmac, err := client.Sign(owner, name, string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.Bool("save") == false {
|
||||
fmt.Println(hmac)
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err = signer.WriteTo(data, hmac)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(path, data, 0644)
|
||||
}
|
8
drone/starlark/samples/docker.py
Normal file
8
drone/starlark/samples/docker.py
Normal file
@ -0,0 +1,8 @@
|
||||
def docker(repo):
|
||||
return {
|
||||
'name': 'docker',
|
||||
'image': 'plugins/docker',
|
||||
'settings': {
|
||||
'repo': repo,
|
||||
},
|
||||
}
|
33
drone/starlark/samples/pipeline.py
Normal file
33
drone/starlark/samples/pipeline.py
Normal file
@ -0,0 +1,33 @@
|
||||
# cd drone/starlark/samples
|
||||
# drone script --source pipeline.py --stdout
|
||||
|
||||
load('docker.py', 'docker')
|
||||
|
||||
def build(version):
|
||||
return {
|
||||
'name': 'build',
|
||||
'image': 'golang:%s' % version,
|
||||
'commands': [
|
||||
'go build',
|
||||
'go test',
|
||||
]
|
||||
}
|
||||
|
||||
def main(ctx):
|
||||
if ctx['build']['message'].find('[skip build]'):
|
||||
return {
|
||||
'kind': 'pipeline',
|
||||
'name': 'publish_only',
|
||||
'steps': [
|
||||
docker('octocat/hello-world'),
|
||||
],
|
||||
}
|
||||
return {
|
||||
'kind': 'pipeline',
|
||||
'name': 'build_and_publish',
|
||||
'steps': [
|
||||
build('1.11'),
|
||||
build('1.12'),
|
||||
docker('octocat/hello-world'),
|
||||
],
|
||||
}
|
317
drone/starlark/starlark.go
Normal file
317
drone/starlark/starlark.go
Normal file
@ -0,0 +1,317 @@
|
||||
package starlark
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-yaml/yaml"
|
||||
"github.com/drone/drone-yaml/yaml/pretty"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
"go.starlark.net/starlark"
|
||||
"go.starlark.net/starlarkstruct"
|
||||
)
|
||||
|
||||
// Command exports the jsonnet command.
|
||||
var Command = cli.Command{
|
||||
Name: "starlark",
|
||||
Usage: "generate .drone.yml from starlark",
|
||||
ArgsUsage: "[path/to/.drone.star]",
|
||||
Action: func(c *cli.Context) {
|
||||
if err := generate(c); err != nil {
|
||||
if err, ok := err.(*starlark.EvalError); ok {
|
||||
log.Fatalf("starlark evaluation error:\n%s", err.Backtrace())
|
||||
}
|
||||
log.Fatalln(err)
|
||||
}
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "source",
|
||||
Usage: "Source file",
|
||||
Value: ".drone.star",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "target",
|
||||
Usage: "target file",
|
||||
Value: ".drone.yml",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "format",
|
||||
Usage: "Write output as formatted YAML",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "stdout",
|
||||
Usage: "Write output to stdout",
|
||||
},
|
||||
//
|
||||
// Drone Parameters
|
||||
//
|
||||
cli.StringFlag{
|
||||
Name: "repo.name",
|
||||
Usage: "repository name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo.namespace",
|
||||
Usage: "repository namespace",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "repo.slug",
|
||||
Usage: "repository slug",
|
||||
},
|
||||
|
||||
cli.StringFlag{
|
||||
Name: "build.event",
|
||||
Usage: "build event",
|
||||
Value: "push",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.branch",
|
||||
Usage: "build branch",
|
||||
Value: "master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.source",
|
||||
Usage: "build source branch",
|
||||
Value: "master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.target",
|
||||
Usage: "build target branch",
|
||||
Value: "master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.ref",
|
||||
Usage: "build ref",
|
||||
Value: "refs/heads/master",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.commit",
|
||||
Usage: "build commit sha",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "build.message",
|
||||
Usage: "build commit message",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func generate(c *cli.Context) error {
|
||||
source := c.String("source")
|
||||
target := c.String("target")
|
||||
|
||||
data, err := ioutil.ReadFile(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
thread := &starlark.Thread{
|
||||
Name: "drone",
|
||||
Print: func(_ *starlark.Thread, msg string) { fmt.Println(msg) },
|
||||
Load: makeLoad(),
|
||||
}
|
||||
globals, err := starlark.ExecFile(thread, source, data, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mainVal, ok := globals["main"]
|
||||
if !ok {
|
||||
return fmt.Errorf("no main function found")
|
||||
}
|
||||
main, ok := mainVal.(starlark.Callable)
|
||||
if !ok {
|
||||
return fmt.Errorf("main must be a function")
|
||||
}
|
||||
|
||||
// TODO this needs to be flushed out.
|
||||
repo := starlark.StringDict{
|
||||
"name": starlark.String(c.String("repo.name")),
|
||||
"namespace": starlark.String(c.String("repo.namespace")),
|
||||
"slug": starlark.String(c.String("repo.slug")),
|
||||
}
|
||||
|
||||
build := starlark.StringDict{
|
||||
"event": starlark.String(c.String("build.event")),
|
||||
"branch": starlark.String(c.String("build.branch")),
|
||||
"source": starlark.String(c.String("build.source_branch")),
|
||||
"target": starlark.String(c.String("build.target_branch")),
|
||||
"ref": starlark.String(c.String("build.ref")),
|
||||
"commit": starlark.String(c.String("build.commit")),
|
||||
"message": starlark.String(c.String("build.message")),
|
||||
}
|
||||
|
||||
args := starlark.Tuple([]starlark.Value{
|
||||
starlarkstruct.FromStringDict(
|
||||
starlark.String("context"),
|
||||
starlark.StringDict{
|
||||
"repo": starlarkstruct.FromStringDict(starlark.String("repo"), repo),
|
||||
"build": starlarkstruct.FromStringDict(starlark.String("build"), build),
|
||||
},
|
||||
),
|
||||
})
|
||||
mainVal, err = starlark.Call(thread, main, args, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
switch v := mainVal.(type) {
|
||||
case *starlark.List:
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
item := v.Index(i)
|
||||
buf.WriteString("---\n")
|
||||
err = writeJSON(buf, item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
case *starlark.Dict:
|
||||
buf.WriteString("---\n")
|
||||
err = writeJSON(buf, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid return type (got a %s)", mainVal.Type())
|
||||
}
|
||||
|
||||
// if the user disables pretty printing, the yaml is printed
|
||||
// to the console or written to the file in json format.
|
||||
if c.BoolT("format") == false {
|
||||
if c.Bool("stdout") {
|
||||
io.Copy(os.Stdout, buf)
|
||||
return nil
|
||||
}
|
||||
return ioutil.WriteFile(target, buf.Bytes(), 0644)
|
||||
}
|
||||
|
||||
manifest, err := yaml.Parse(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.Reset()
|
||||
pretty.Print(buf, manifest)
|
||||
|
||||
// the user can optionally write the yaml to stdout. This
|
||||
// is useful for debugging purposes without mutating an
|
||||
// existing file.
|
||||
if c.Bool("stdout") {
|
||||
io.Copy(os.Stdout, buf)
|
||||
return nil
|
||||
}
|
||||
return ioutil.WriteFile(target, buf.Bytes(), 0644)
|
||||
}
|
||||
|
||||
// Adapted from skycfg:
|
||||
// https://github.com/stripe/skycfg/blob/eaa524101c2a0807c13ed5d2e52576fefc146ec3/internal/go/skycfg/json_write.go#L45
|
||||
func writeJSON(out *bytes.Buffer, v starlark.Value) error {
|
||||
if marshaler, ok := v.(json.Marshaler); ok {
|
||||
jsonData, err := marshaler.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out.Write(jsonData)
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := v.(type) {
|
||||
case starlark.NoneType:
|
||||
out.WriteString("null")
|
||||
case starlark.Bool:
|
||||
fmt.Fprintf(out, "%t", v)
|
||||
case starlark.Int:
|
||||
out.WriteString(v.String())
|
||||
case starlark.Float:
|
||||
fmt.Fprintf(out, "%g", v)
|
||||
case starlark.String:
|
||||
s := string(v)
|
||||
if goQuoteIsSafe(s) {
|
||||
fmt.Fprintf(out, "%q", s)
|
||||
} else {
|
||||
// vanishingly rare for text strings
|
||||
data, _ := json.Marshal(s)
|
||||
out.Write(data)
|
||||
}
|
||||
case starlark.Indexable: // Tuple, List
|
||||
out.WriteByte('[')
|
||||
for i, n := 0, starlark.Len(v); i < n; i++ {
|
||||
if i > 0 {
|
||||
out.WriteString(", ")
|
||||
}
|
||||
if err := writeJSON(out, v.Index(i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
out.WriteByte(']')
|
||||
case *starlark.Dict:
|
||||
out.WriteByte('{')
|
||||
for i, itemPair := range v.Items() {
|
||||
key := itemPair[0]
|
||||
value := itemPair[1]
|
||||
if i > 0 {
|
||||
out.WriteString(", ")
|
||||
}
|
||||
if err := writeJSON(out, key); err != nil {
|
||||
return err
|
||||
}
|
||||
out.WriteString(": ")
|
||||
if err := writeJSON(out, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
out.WriteByte('}')
|
||||
default:
|
||||
return fmt.Errorf("TypeError: value %s (type `%s') can't be converted to JSON.", v.String(), v.Type())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func goQuoteIsSafe(s string) bool {
|
||||
for _, r := range s {
|
||||
// JSON doesn't like Go's \xHH escapes for ASCII control codes,
|
||||
// nor its \UHHHHHHHH escapes for runes >16 bits.
|
||||
if r < 0x20 || r >= 0x10000 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// https://github.com/google/starlark-go/blob/4eb76950c5f02ec5bcfd3ca898231a6543942fd9/repl/repl.go#L175
|
||||
func makeLoad() func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
|
||||
type entry struct {
|
||||
globals starlark.StringDict
|
||||
err error
|
||||
}
|
||||
|
||||
var cache = make(map[string]*entry)
|
||||
|
||||
return func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
|
||||
e, ok := cache[module]
|
||||
if e == nil {
|
||||
if ok {
|
||||
// request for package whose loading is in progress
|
||||
return nil, fmt.Errorf("cycle in load graph")
|
||||
}
|
||||
|
||||
// Add a placeholder to indicate "load in progress".
|
||||
cache[module] = nil
|
||||
|
||||
// Load it.
|
||||
thread := &starlark.Thread{Name: "exec " + module, Load: thread.Load}
|
||||
globals, err := starlark.ExecFile(thread, module, nil, nil)
|
||||
e = &entry{globals, err}
|
||||
|
||||
// Update the cache.
|
||||
cache[module] = e
|
||||
}
|
||||
return e.globals, e.err
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user