mirror of https://gitlab.com/gitlab-org/cli.git
feat(schedule): Add commands to create and delete schedules
This commit is contained in:
parent
a81a2ae527
commit
afdcc8b053
|
@ -33,3 +33,28 @@ var RunSchedule = func(client *gitlab.Client, repo string, schedule int, opts ..
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
var CreateSchedule = func(client *gitlab.Client, repo string, scheduleOpts *gitlab.CreatePipelineScheduleOptions, opts ...gitlab.RequestOptionFunc) error {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
}
|
||||
|
||||
_, _, err := client.PipelineSchedules.CreatePipelineSchedule(repo, scheduleOpts, opts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating scheduled pipeline status: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var DeleteSchedule = func(client *gitlab.Client, scheduleId int, repo string, opts ...gitlab.RequestOptionFunc) (err error) {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
}
|
||||
|
||||
_, err = client.PipelineSchedules.DeletePipelineSchedule(repo, scheduleId, opts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("deleting scheduled pipeline status: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package create
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
func NewCmdCreate(f *cmdutils.Factory) *cobra.Command {
|
||||
scheduleCreateCmd := &cobra.Command{
|
||||
Use: "create [flags]",
|
||||
Short: `Schedule a new pipeline.`,
|
||||
Example: heredoc.Doc(`
|
||||
glab schedule create --cron "0 * * * *" --description "Describe your pipeline here" --ref "main"
|
||||
`),
|
||||
Long: ``,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
apiClient, err := f.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo, err := f.BaseRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l := &gitlab.CreatePipelineScheduleOptions{}
|
||||
|
||||
description, _ := cmd.Flags().GetString("description")
|
||||
ref, _ := cmd.Flags().GetString("ref")
|
||||
cron, _ := cmd.Flags().GetString("cron")
|
||||
cronTimeZone, _ := cmd.Flags().GetString("cronTimeZone")
|
||||
active, _ := cmd.Flags().GetBool("active")
|
||||
|
||||
l.Description = &description
|
||||
l.Ref = &ref
|
||||
l.Cron = &cron
|
||||
l.CronTimezone = &cronTimeZone
|
||||
l.Active = &active
|
||||
|
||||
err = api.CreateSchedule(apiClient, repo.FullName(), l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(f.IO.StdOut, "Created schedule")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
scheduleCreateCmd.Flags().String("description", "", "Description of the schedule")
|
||||
scheduleCreateCmd.Flags().String("ref", "", "Target branch or tag")
|
||||
scheduleCreateCmd.Flags().String("cron", "", "Cron interval pattern")
|
||||
scheduleCreateCmd.Flags().String("cronTimeZone", "UTC", "Cron timezone")
|
||||
scheduleCreateCmd.Flags().Bool("active", true, "Whether or not the schedule is active")
|
||||
|
||||
_ = scheduleCreateCmd.MarkFlagRequired("ref")
|
||||
_ = scheduleCreateCmd.MarkFlagRequired("cron")
|
||||
_ = scheduleCreateCmd.MarkFlagRequired("description")
|
||||
|
||||
return scheduleCreateCmd
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package create
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func Test_ScheduleCreate(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
ExpectedMsg []string
|
||||
wantErr bool
|
||||
cli string
|
||||
wantStderr string
|
||||
httpMocks []httpMock
|
||||
}{
|
||||
{
|
||||
Name: "Schedule created",
|
||||
ExpectedMsg: []string{"Created schedule"},
|
||||
cli: "--cron '*0 * * * *' --description 'example pipeline' --ref 'main'",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodPost,
|
||||
"/api/v4/projects/OWNER/REPO/pipeline_schedules",
|
||||
http.StatusCreated,
|
||||
`{}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Schedule not created because of missing ref",
|
||||
wantStderr: "required flag(s) \"ref\" not set",
|
||||
wantErr: true,
|
||||
ExpectedMsg: []string{""},
|
||||
cli: "--cron '*0 * * * *' --description 'example pipeline'",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
fakeHTTP := &httpmock.Mocker{
|
||||
MatchURL: httpmock.PathAndQuerystring,
|
||||
}
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
}
|
||||
|
||||
out, err := runCommand(fakeHTTP, false, tc.cli)
|
||||
|
||||
for _, msg := range tc.ExpectedMsg {
|
||||
require.Contains(t, out.String(), msg)
|
||||
}
|
||||
if err != nil {
|
||||
if tc.wantErr == true {
|
||||
if assert.Error(t, err) {
|
||||
require.Equal(t, tc.wantStderr, err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
_, _ = factory.HttpClient()
|
||||
cmd := NewCmdCreate(factory)
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package delete
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type RunOpts struct {
|
||||
ScheduleId int
|
||||
IO *iostreams.IOStreams
|
||||
}
|
||||
|
||||
func NewCmdDelete(f *cmdutils.Factory) *cobra.Command {
|
||||
opts := &RunOpts{
|
||||
IO: f.IO,
|
||||
}
|
||||
scheduleDeleteCmd := &cobra.Command{
|
||||
Use: "delete [flags]",
|
||||
Short: `Delete schedule with the specified ID.`,
|
||||
Example: heredoc.Doc(`
|
||||
glab schedule delete 10
|
||||
`),
|
||||
Long: ``,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
apiClient, err := f.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo, err := f.BaseRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id, err := strconv.ParseUint(args[0], 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scheduleId := int(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = api.DeleteSchedule(apiClient, scheduleId, repo.FullName())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(opts.IO.StdOut, "Deleted schedule with ID", scheduleId)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return scheduleDeleteCmd
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package delete
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func Test_ScheduleDelete(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
ExpectedMsg []string
|
||||
wantErr bool
|
||||
cli string
|
||||
wantStderr string
|
||||
httpMocks []httpMock
|
||||
}{
|
||||
{
|
||||
Name: "Schedule deleted",
|
||||
ExpectedMsg: []string{"Deleted schedule with ID 1"},
|
||||
cli: "1",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodDelete,
|
||||
"/api/v4/projects/OWNER/REPO/pipeline_schedules/1",
|
||||
http.StatusNoContent,
|
||||
"",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
fakeHTTP := &httpmock.Mocker{
|
||||
MatchURL: httpmock.PathAndQuerystring,
|
||||
}
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
}
|
||||
|
||||
out, err := runCommand(fakeHTTP, false, tc.cli)
|
||||
fmt.Print(err)
|
||||
if err != nil {
|
||||
if tc.wantErr == true {
|
||||
if assert.Error(t, err) {
|
||||
require.Equal(t, tc.wantStderr, err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, msg := range tc.ExpectedMsg {
|
||||
fmt.Print(msg)
|
||||
require.Contains(t, out.String(), msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
_, _ = factory.HttpClient()
|
||||
cmd := NewCmdDelete(factory)
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package schedule
|
||||
|
||||
import (
|
||||
scheduleCreateCmd "gitlab.com/gitlab-org/cli/commands/schedule/create"
|
||||
scheduleDeleteCmd "gitlab.com/gitlab-org/cli/commands/schedule/delete"
|
||||
scheduleListCmd "gitlab.com/gitlab-org/cli/commands/schedule/list"
|
||||
scheduleRunCmd "gitlab.com/gitlab-org/cli/commands/schedule/run"
|
||||
|
||||
|
@ -21,6 +23,8 @@ func NewCmdSchedule(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
scheduleCmd.AddCommand(scheduleListCmd.NewCmdList(f))
|
||||
scheduleCmd.AddCommand(scheduleRunCmd.NewCmdRun(f))
|
||||
scheduleCmd.AddCommand(scheduleCreateCmd.NewCmdCreate(f))
|
||||
scheduleCmd.AddCommand(scheduleDeleteCmd.NewCmdDelete(f))
|
||||
|
||||
return scheduleCmd
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Code Review
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
<!--
|
||||
This documentation is auto generated by a script.
|
||||
Please do not edit this file directly. Run `make gen-docs` instead.
|
||||
-->
|
||||
|
||||
# `glab schedule create`
|
||||
|
||||
Schedule a new pipeline.
|
||||
|
||||
```plaintext
|
||||
glab schedule create [flags]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```plaintext
|
||||
glab schedule create --cron "0 * * * *" --description "Describe your pipeline here" --ref "main"
|
||||
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
```plaintext
|
||||
--active Whether or not the schedule is active (default true)
|
||||
--cron string Cron interval pattern
|
||||
--cronTimeZone string Cron timezone (default "UTC")
|
||||
--description string Description of the schedule
|
||||
--ref string Target branch or tag
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
||||
```plaintext
|
||||
--help Show help for command
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
```
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Code Review
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
<!--
|
||||
This documentation is auto generated by a script.
|
||||
Please do not edit this file directly. Run `make gen-docs` instead.
|
||||
-->
|
||||
|
||||
# `glab schedule delete`
|
||||
|
||||
Delete schedule with the specified ID.
|
||||
|
||||
```plaintext
|
||||
glab schedule delete [flags]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```plaintext
|
||||
glab schedule delete 10
|
||||
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
||||
```plaintext
|
||||
--help Show help for command
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
```
|
|
@ -34,5 +34,7 @@ skd
|
|||
|
||||
## Subcommands
|
||||
|
||||
- [create](create.md)
|
||||
- [delete](delete.md)
|
||||
- [list](list.md)
|
||||
- [run](run.md)
|
||||
|
|
Loading…
Reference in New Issue