diff --git a/action/build/approve.go b/action/build/approve.go new file mode 100644 index 00000000..b48b36bb --- /dev/null +++ b/action/build/approve.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "fmt" + + "github.com/go-vela/cli/internal/output" + + "github.com/go-vela/sdk-go/vela" + + "github.com/sirupsen/logrus" +) + +// Approve approves a build based off the provided configuration. +func (c *Config) Approve(client *vela.Client) error { + logrus.Debug("executing approve for build configuration") + + logrus.Tracef("approving build %s/%s/%d", c.Org, c.Repo, c.Number) + + // send API call to approve a build + // + // https://pkg.go.dev/github.com/go-vela/sdk-go/vela?tab=doc#BuildService.Approve + _, err := client.Build.Approve(c.Org, c.Repo, c.Number) + if err != nil { + return err + } + + // output the build in stdout format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#Stdout + return output.Stdout(fmt.Sprintf("successfully approved build %s/%s/%d", c.Org, c.Repo, c.Number)) +} diff --git a/action/build/approve_test.go b/action/build/approve_test.go new file mode 100644 index 00000000..2b944277 --- /dev/null +++ b/action/build/approve_test.go @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "net/http/httptest" + "testing" + + "github.com/go-vela/server/mock/server" + + "github.com/go-vela/sdk-go/vela" +) + +func TestBuild_Config_Approve(t *testing.T) { + // setup test server + s := httptest.NewServer(server.FakeHandler()) + + // create a vela client + client, err := vela.NewClient(s.URL, "vela", nil) + if err != nil { + t.Errorf("unable to create client: %v", err) + } + + // setup tests + tests := []struct { + failure bool + config *Config + }{ + { + failure: false, + config: &Config{ + Action: "approve", + Org: "github", + Repo: "octocat", + Number: 1, + }, + }, + { + failure: true, + config: &Config{ + Action: "approve", + Org: "github", + Repo: "octocat", + Number: 0, + }, + }, + } + + // run tests + for _, test := range tests { + err := test.config.Approve(client) + + if test.failure { + if err == nil { + t.Errorf("Approve should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Approve returned err: %v", err) + } + } +} diff --git a/cmd/vela-cli/approve.go b/cmd/vela-cli/approve.go new file mode 100644 index 00000000..b545e374 --- /dev/null +++ b/cmd/vela-cli/approve.go @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "github.com/go-vela/cli/command/build" + + "github.com/urfave/cli/v2" +) + +// approveCmds defines the commands for approving resources. +var approveCmds = &cli.Command{ + Name: "approve", + Category: "Resource Management", + Description: "Use this command to approve a resource for Vela.", + Usage: "Approve a resource for Vela via subcommands", + UseShortOptionHandling: true, + Subcommands: []*cli.Command{ + // add the sub command for approving a build + // + // https://pkg.go.dev/github.com/go-vela/cli/command/build?tab=doc#CommandApprove + build.CommandApprove, + }, +} diff --git a/cmd/vela-cli/main.go b/cmd/vela-cli/main.go index 3174ba2a..7d5b09b5 100644 --- a/cmd/vela-cli/main.go +++ b/cmd/vela-cli/main.go @@ -47,6 +47,7 @@ func main() { login.CommandLogin, _version.CommandVersion, addCmds, + approveCmds, cancelCmds, chownCmds, compileCmds, diff --git a/command/build/approve.go b/command/build/approve.go new file mode 100644 index 00000000..298bd2e0 --- /dev/null +++ b/command/build/approve.go @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "fmt" + + "github.com/go-vela/cli/action" + "github.com/go-vela/cli/action/build" + "github.com/go-vela/cli/internal" + "github.com/go-vela/cli/internal/client" + + "github.com/urfave/cli/v2" +) + +// CommandApprove defines the command for Approveing a build. +var CommandApprove = &cli.Command{ + Name: internal.FlagBuild, + Description: "Use this command to Approve a build.", + Usage: "Approve the provided build", + Action: approve, + Flags: []cli.Flag{ + + // Repo Flags + + &cli.StringFlag{ + EnvVars: []string{"VELA_ORG", "BUILD_ORG"}, + Name: internal.FlagOrg, + Aliases: []string{"o"}, + Usage: "provide the organization for the build", + }, + &cli.StringFlag{ + EnvVars: []string{"VELA_REPO", "BUILD_REPO"}, + Name: internal.FlagRepo, + Aliases: []string{"r"}, + Usage: "provide the repository for the build", + }, + + // Build Flags + + &cli.IntFlag{ + EnvVars: []string{"VELA_BUILD", "BUILD_NUMBER"}, + Name: internal.FlagBuild, + Aliases: []string{"b", "number", "bn"}, + Usage: "provide the number for the build", + }, + }, + CustomHelpTemplate: fmt.Sprintf(`%s +EXAMPLES: + 1. Approve existing build for a repository. + $ {{.HelpName}} --org MyOrg --repo MyRepo --build 1 + 2. Approve existing build for a repository when config or environment variables are set. + $ {{.HelpName}} --build 1 + +DOCUMENTATION: + + https://go-vela.github.io/docs/reference/cli/build/Approve/ +`, cli.CommandHelpTemplate), +} + +// helper function to capture the provided +// input and create the object used to +// approve a build. +func approve(c *cli.Context) error { + // load variables from the config file + err := action.Load(c) + if err != nil { + return err + } + + // grab first command line argument, if it exists, and set it as resource + err = internal.ProcessArgs(c, internal.FlagBuild, "int") + if err != nil { + return err + } + + // parse the Vela client from the context + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/client?tab=doc#Parse + client, err := client.Parse(c) + if err != nil { + return err + } + + // create the build configuration + // + // https://pkg.go.dev/github.com/go-vela/cli/action/build?tab=doc#Config + b := &build.Config{ + Action: internal.ActionApprove, + Org: c.String(internal.FlagOrg), + Repo: c.String(internal.FlagRepo), + Number: c.Int(internal.FlagBuild), + } + + // validate build configuration + // + // https://pkg.go.dev/github.com/go-vela/cli/action/build?tab=doc#Config.Validate + err = b.Validate() + if err != nil { + return err + } + + // execute the Approve call for the build configuration + // + // https://pkg.go.dev/github.com/go-vela/cli/action/build?tab=doc#Config.Approve + return b.Approve(client) +} diff --git a/command/build/approve_test.go b/command/build/approve_test.go new file mode 100644 index 00000000..78448856 --- /dev/null +++ b/command/build/approve_test.go @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "flag" + "net/http/httptest" + "testing" + + "github.com/go-vela/cli/test" + "github.com/go-vela/server/mock/server" + + "github.com/urfave/cli/v2" +) + +func TestBuild_Approve(t *testing.T) { + // setup test server + s := httptest.NewServer(server.FakeHandler()) + + // setup flags + authSet := flag.NewFlagSet("test", 0) + authSet.String("api.addr", s.URL, "doc") + authSet.String("api.token.access", test.TestTokenGood, "doc") + authSet.String("api.token.refresh", "superSecretRefreshToken", "doc") + + fullSet := flag.NewFlagSet("test", 0) + fullSet.String("api.addr", s.URL, "doc") + fullSet.String("api.token.access", test.TestTokenGood, "doc") + fullSet.String("api.token.refresh", "superSecretRefreshToken", "doc") + fullSet.String("org", "github", "doc") + fullSet.String("repo", "octocat", "doc") + fullSet.Int("build", 1, "doc") + + // setup tests + tests := []struct { + failure bool + set *flag.FlagSet + }{ + { + failure: false, + set: fullSet, + }, + { + failure: true, + set: authSet, + }, + { + failure: true, + set: flag.NewFlagSet("test", 0), + }, + } + + // run tests + for _, test := range tests { + err := approve(cli.NewContext(&cli.App{Name: "vela", Version: "v0.0.0"}, test.set, nil)) + + if test.failure { + if err == nil { + t.Errorf("approve should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("approve returned err: %v", err) + } + } +} diff --git a/go.mod b/go.mod index 48283792..b53a4bbd 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,9 @@ require ( github.com/dustin/go-humanize v1.0.1 github.com/gin-gonic/gin v1.9.1 github.com/go-git/go-git/v5 v5.10.1 - github.com/go-vela/sdk-go v0.22.0 - github.com/go-vela/server v0.22.2 - github.com/go-vela/types v0.22.0 + github.com/go-vela/sdk-go v0.22.1-0.20231211213353-23e6a2ee9817 + github.com/go-vela/server v0.22.3-0.20231211205434-140d2b1492b7 + github.com/go-vela/types v0.22.1-0.20231211143329-1eae2f5e371b github.com/go-vela/worker v0.22.0 github.com/golang-jwt/jwt/v5 v5.1.0 github.com/gosuri/uitable v0.0.4 diff --git a/go.sum b/go.sum index 0ea96ae9..38df0b5c 100644 --- a/go.sum +++ b/go.sum @@ -114,12 +114,12 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-vela/sdk-go v0.22.0 h1:zuFa9BVACP5d5hwbm1o4DVny4amcweGYJgSBDV6En8o= -github.com/go-vela/sdk-go v0.22.0/go.mod h1:7N0SW+5L4iboP+B6VQ2PlKvW5Tcj/8zRXJVob9nrSko= -github.com/go-vela/server v0.22.2 h1:jDlkQBqi4vxmnJkUVIUTdZeUAEoEVejdd6Mkm25QMrs= -github.com/go-vela/server v0.22.2/go.mod h1:DidWsP+FCWot5ePim0jjvQqhaheOKjSMoVtAfXeNTyU= -github.com/go-vela/types v0.22.0 h1:JmAQ9Hy4HnOgbgNsNz5x1wu3Myv47KoC0rxR9x36OQ4= -github.com/go-vela/types v0.22.0/go.mod h1:ljNY36D6YkpObBbNF7Xslv3oxN4mGuQAwWhnnK/V06I= +github.com/go-vela/sdk-go v0.22.1-0.20231211213353-23e6a2ee9817 h1:YTvVN2nfMiU5EpSwN/Zwrxn/bixBB+y1EcwsEBB7bMU= +github.com/go-vela/sdk-go v0.22.1-0.20231211213353-23e6a2ee9817/go.mod h1:EVAthIAXxYtP6I/AxbzTJngTtgvLwrNtRLZ39TBqZtg= +github.com/go-vela/server v0.22.3-0.20231211205434-140d2b1492b7 h1:Ou1URiqOj+L56/3dzQgP5ov8dWRyOmW/N8aihZRxlX4= +github.com/go-vela/server v0.22.3-0.20231211205434-140d2b1492b7/go.mod h1:f8bWM2UGX+lKbCyaj11BQWQUSrc5pW7So0G+5BU7vkc= +github.com/go-vela/types v0.22.1-0.20231211143329-1eae2f5e371b h1:8rC4vEVWUFisc11LvGFOsVx76K1HmxxE+jub4s4sb0A= +github.com/go-vela/types v0.22.1-0.20231211143329-1eae2f5e371b/go.mod h1:ljNY36D6YkpObBbNF7Xslv3oxN4mGuQAwWhnnK/V06I= github.com/go-vela/worker v0.22.0 h1:zmGiuykclbd0cfH6XKpCnoeIagYhYt7CJQ/y5HfqjZk= github.com/go-vela/worker v0.22.0/go.mod h1:ErPzlBEBWgYcinlbscn5q+9iArIuajy1DO+Oe9Ya2NA= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= diff --git a/internal/internal.go b/internal/internal.go index 00c4002a..68bc29ce 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -165,6 +165,9 @@ const ( // ActionAdd defines the action for creating a resource. ActionAdd = "add" + // ActionApprove defines the action for approving a resource. + ActionApprove = "approve" + // ActionCancel defines the action for canceling of a resource. ActionCancel = "cancel"