mirror of https://gitlab.com/gitlab-org/cli.git
Merge branch 'main' into 'jmc-remove-stats'
# Conflicts: # api/project.go
This commit is contained in:
commit
124b7a3621
|
@ -1,2 +1,2 @@
|
|||
golang 1.21.5
|
||||
golang 1.21.9
|
||||
vale 3.0.7
|
||||
|
|
|
@ -8,7 +8,7 @@ var GetCommitStatuses = func(client *gitlab.Client, pid interface{}, sha string)
|
|||
}
|
||||
|
||||
opt := &gitlab.GetCommitStatusesOptions{
|
||||
All: gitlab.Bool(true),
|
||||
All: gitlab.Ptr(true),
|
||||
}
|
||||
|
||||
statuses, _, err := client.Commits.GetCommitStatuses(pid, sha, opt, nil)
|
||||
|
|
|
@ -225,7 +225,7 @@ var ListMRNotes = func(client *gitlab.Client, projectID interface{}, mrID int, o
|
|||
return notes, nil
|
||||
}
|
||||
|
||||
var RebaseMR = func(client *gitlab.Client, projectID interface{}, mrID int, opts gitlab.RequestOptionFunc) error {
|
||||
var RebaseMR = func(client *gitlab.Client, projectID interface{}, mrID int, opts *gitlab.RebaseMergeRequestOptions) error {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ var ListProjectMilestones = func(client *gitlab.Client, projectID interface{}, o
|
|||
}
|
||||
|
||||
var ProjectMilestoneByTitle = func(client *gitlab.Client, projectID interface{}, name string) (*gitlab.Milestone, error) {
|
||||
opts := &gitlab.ListMilestonesOptions{Title: gitlab.String(name)}
|
||||
opts := &gitlab.ListMilestonesOptions{Title: gitlab.Ptr(name)}
|
||||
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
|
|
|
@ -127,8 +127,8 @@ var GetLastPipeline = func(client *gitlab.Client, repo string, ref string) (*git
|
|||
}
|
||||
|
||||
l := &gitlab.ListProjectPipelinesOptions{
|
||||
Ref: gitlab.String(ref),
|
||||
Sort: gitlab.String("desc"),
|
||||
Ref: gitlab.Ptr(ref),
|
||||
Sort: gitlab.Ptr("desc"),
|
||||
}
|
||||
|
||||
l.Page = 1
|
||||
|
@ -257,8 +257,8 @@ var GetPipelineFromBranch = func(client *gitlab.Client, ref, repo string) ([]*gi
|
|||
}
|
||||
}
|
||||
l := &gitlab.ListProjectPipelinesOptions{
|
||||
Ref: gitlab.String(ref),
|
||||
Sort: gitlab.String("desc"),
|
||||
Ref: gitlab.Ptr(ref),
|
||||
Sort: gitlab.Ptr("desc"),
|
||||
}
|
||||
l.Page = 1
|
||||
l.PerPage = 1
|
||||
|
@ -381,7 +381,7 @@ var PipelineJobsWithSha = func(client *gitlab.Client, pid interface{}, sha strin
|
|||
client = apiClient.Lab()
|
||||
}
|
||||
pipelines, err := GetPipelines(client, &gitlab.ListProjectPipelinesOptions{
|
||||
SHA: gitlab.String(sha),
|
||||
SHA: gitlab.Ptr(sha),
|
||||
}, pid)
|
||||
if len(pipelines) == 0 || err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -438,6 +438,14 @@ var CreatePipeline = func(client *gitlab.Client, projectID interface{}, opts *gi
|
|||
return pipe, err
|
||||
}
|
||||
|
||||
var RunPipelineTrigger = func(client *gitlab.Client, projectID interface{}, opts *gitlab.RunPipelineTriggerOptions) (*gitlab.Pipeline, error) {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
}
|
||||
pipe, _, err := client.PipelineTriggers.RunPipelineTrigger(projectID, opts)
|
||||
return pipe, err
|
||||
}
|
||||
|
||||
var DownloadArtifactJob = func(client *gitlab.Client, repo string, ref string, opts *gitlab.DownloadArtifactsFileOptions) (*bytes.Reader, error) {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
|
|
|
@ -7,9 +7,9 @@ var GetProject = func(client *gitlab.Client, projectID interface{}) (*gitlab.Pro
|
|||
client = apiClient.Lab()
|
||||
}
|
||||
opts := &gitlab.GetProjectOptions{
|
||||
Statistics: gitlab.Bool(false),
|
||||
License: gitlab.Bool(true),
|
||||
WithCustomAttributes: gitlab.Bool(true),
|
||||
Statistics: gitlab.Ptr(false),
|
||||
License: gitlab.Ptr(true),
|
||||
WithCustomAttributes: gitlab.Ptr(true),
|
||||
}
|
||||
project, _, err := client.Projects.GetProject(projectID, opts)
|
||||
if err != nil {
|
||||
|
|
|
@ -19,7 +19,7 @@ var CurrentUser = func(client *gitlab.Client) (*gitlab.User, error) {
|
|||
}
|
||||
|
||||
var UserByName = func(client *gitlab.Client, name string) (*gitlab.User, error) {
|
||||
opts := &gitlab.ListUsersOptions{Username: gitlab.String(name)}
|
||||
opts := &gitlab.ListUsersOptions{Username: gitlab.Ptr(name)}
|
||||
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
|
@ -65,7 +65,7 @@ var CreatePersonalAccessTokenForCurrentUser = func(client *gitlab.Client, name s
|
|||
}
|
||||
expiresAtISO := gitlab.ISOTime(expiresAt)
|
||||
options := &gitlab.CreatePersonalAccessTokenForCurrentUserOptions{
|
||||
Name: gitlab.String(name),
|
||||
Name: gitlab.Ptr(name),
|
||||
Scopes: &scopes,
|
||||
ExpiresAt: &expiresAtISO,
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ func NewCmdGenerate(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
// Set the version
|
||||
if s, _ := cmd.Flags().GetString("version"); s != "" {
|
||||
opts.Version = gitlab.String(s)
|
||||
opts.Version = gitlab.Ptr(s)
|
||||
} else {
|
||||
tags, err := git.ListTags()
|
||||
if err != nil {
|
||||
|
@ -53,12 +53,12 @@ func NewCmdGenerate(f *cmdutils.Factory) *cobra.Command {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to determine version from git describe: %w..", err)
|
||||
}
|
||||
opts.Version = gitlab.String(version)
|
||||
opts.Version = gitlab.Ptr(version)
|
||||
}
|
||||
|
||||
// Set the config file
|
||||
if s, _ := cmd.Flags().GetString("config-file"); s != "" {
|
||||
opts.ConfigFile = gitlab.String(s)
|
||||
opts.ConfigFile = gitlab.Ptr(s)
|
||||
}
|
||||
|
||||
// Set the date
|
||||
|
@ -74,17 +74,17 @@ func NewCmdGenerate(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
// Set the "from" attribute
|
||||
if s, _ := cmd.Flags().GetString("from"); s != "" {
|
||||
opts.From = gitlab.String(s)
|
||||
opts.From = gitlab.Ptr(s)
|
||||
}
|
||||
|
||||
// Set the "to" attribute
|
||||
if s, _ := cmd.Flags().GetString("to"); s != "" {
|
||||
opts.To = gitlab.String(s)
|
||||
opts.To = gitlab.Ptr(s)
|
||||
}
|
||||
|
||||
// Set the trailer
|
||||
if s, _ := cmd.Flags().GetString("trailer"); s != "" {
|
||||
opts.Trailer = gitlab.String(s)
|
||||
opts.Trailer = gitlab.Ptr(s)
|
||||
}
|
||||
|
||||
project, err := repo.Project(apiClient)
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/internal/config"
|
||||
"gitlab.com/gitlab-org/cli/pkg/utils"
|
||||
)
|
||||
|
||||
func ensurePathIsCreated(filename string) error {
|
||||
|
@ -28,15 +29,6 @@ func ensurePathIsCreated(filename string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func sanitizeAssetName(asset string) string {
|
||||
if !strings.HasPrefix(asset, "/") {
|
||||
// Prefix the asset with "/" ensures that filepath.Clean removes all `/..`
|
||||
// See rule 4 of filepath.Clean for more information: https://pkg.go.dev/path/filepath#Clean
|
||||
asset = "/" + asset
|
||||
}
|
||||
return filepath.Clean(asset)
|
||||
}
|
||||
|
||||
func NewCmdRun(f *cmdutils.Factory) *cobra.Command {
|
||||
jobArtifactCmd := &cobra.Command{
|
||||
Use: "artifact <refName> <jobName> [flags]",
|
||||
|
@ -83,7 +75,7 @@ func NewCmdRun(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
for _, v := range zipReader.File {
|
||||
sanitizedAssetName := sanitizeAssetName(v.Name)
|
||||
sanitizedAssetName := utils.SanitizePathName(v.Name)
|
||||
|
||||
destDir, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
|
|
|
@ -10,9 +10,10 @@ import (
|
|||
pipeListCmd "gitlab.com/gitlab-org/cli/commands/ci/list"
|
||||
pipeRetryCmd "gitlab.com/gitlab-org/cli/commands/ci/retry"
|
||||
pipeRunCmd "gitlab.com/gitlab-org/cli/commands/ci/run"
|
||||
pipeRunTrigCmd "gitlab.com/gitlab-org/cli/commands/ci/run_trig"
|
||||
pipeStatusCmd "gitlab.com/gitlab-org/cli/commands/ci/status"
|
||||
ciTraceCmd "gitlab.com/gitlab-org/cli/commands/ci/trace"
|
||||
pipeTriggerCmd "gitlab.com/gitlab-org/cli/commands/ci/trigger"
|
||||
jobPlayCmd "gitlab.com/gitlab-org/cli/commands/ci/trigger"
|
||||
ciViewCmd "gitlab.com/gitlab-org/cli/commands/ci/view"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
|
||||
|
@ -38,7 +39,8 @@ func NewCmdCI(f *cmdutils.Factory) *cobra.Command {
|
|||
ciCmd.AddCommand(pipeStatusCmd.NewCmdStatus(f))
|
||||
ciCmd.AddCommand(pipeRetryCmd.NewCmdRetry(f))
|
||||
ciCmd.AddCommand(pipeRunCmd.NewCmdRun(f))
|
||||
ciCmd.AddCommand(pipeTriggerCmd.NewCmdTrigger(f))
|
||||
ciCmd.AddCommand(jobPlayCmd.NewCmdTrigger(f))
|
||||
ciCmd.AddCommand(pipeRunTrigCmd.NewCmdRunTrig(f))
|
||||
ciCmd.AddCommand(jobArtifactCmd.NewCmdRun(f))
|
||||
ciCmd.AddCommand(pipeGetCmd.NewCmdGet(f))
|
||||
ciCmd.AddCommand(ciConfigCmd.NewCmdConfig(f))
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/internal/glrepo"
|
||||
"gitlab.com/gitlab-org/cli/pkg/git"
|
||||
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
||||
|
@ -179,6 +180,27 @@ func getPipelineId(inputs *JobInputs, opts *JobOptions) (int, error) {
|
|||
return pipeline.ID, err
|
||||
}
|
||||
|
||||
func GetDefaultBranch(f *cmdutils.Factory) string {
|
||||
repo, err := f.BaseRepo()
|
||||
if err != nil {
|
||||
return "master"
|
||||
}
|
||||
|
||||
remotes, err := f.Remotes()
|
||||
if err != nil {
|
||||
return "master"
|
||||
}
|
||||
|
||||
repoRemote, err := remotes.FindByRepo(repo.RepoOwner(), repo.RepoName())
|
||||
if err != nil {
|
||||
return "master"
|
||||
}
|
||||
|
||||
branch, _ := git.GetDefaultBranch(repoRemote.Name)
|
||||
|
||||
return branch
|
||||
}
|
||||
|
||||
func getBranch(branch string, opts *JobOptions) (string, error) {
|
||||
if branch != "" {
|
||||
return branch, nil
|
||||
|
|
|
@ -135,15 +135,15 @@ func optsFromFlags(flags *pflag.FlagSet) *gitlab.ListProjectPipelinesOptions {
|
|||
olderThanDuration, _ := flags.GetDuration(FlagOlderThan)
|
||||
|
||||
if source != "" {
|
||||
opts.Source = gitlab.String(source)
|
||||
opts.Source = gitlab.Ptr(source)
|
||||
}
|
||||
|
||||
if status != "" {
|
||||
opts.Status = gitlab.BuildState(gitlab.BuildStateValue(status))
|
||||
opts.Status = gitlab.Ptr(gitlab.BuildStateValue(status))
|
||||
}
|
||||
|
||||
if olderThanDuration != 0 {
|
||||
opts.UpdatedBefore = gitlab.Time(time.Now().Add(-olderThanDuration))
|
||||
opts.UpdatedBefore = gitlab.Ptr(time.Now().Add(-olderThanDuration))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
@ -338,7 +338,7 @@ func TestOptsFromFlags(t *testing.T) {
|
|||
opts := optsFromFlags(flags)
|
||||
|
||||
assert.Nil(t, opts.Source)
|
||||
assert.Equal(t, opts.Status, gitlab.BuildState("success"))
|
||||
assert.Equal(t, opts.Status, gitlab.Ptr(gitlab.BuildStateValue("success")))
|
||||
|
||||
lowerTimeBoundary := time.Now().Add(-1 * 24 * time.Hour).Add(-5 * time.Second)
|
||||
upperTimeBoundary := time.Now().Add(-1 * 24 * time.Hour).Add(5 * time.Second)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/mr/mrutils"
|
||||
"gitlab.com/gitlab-org/cli/pkg/git"
|
||||
"gitlab.com/gitlab-org/cli/pkg/tableprinter"
|
||||
|
||||
|
@ -63,7 +64,24 @@ func NewCmdGet(f *cmdutils.Factory) *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pipelineId = commit.LastPipeline.ID
|
||||
|
||||
// The latest commit on the branch won't work with a merged
|
||||
// result pipeline
|
||||
if commit.LastPipeline == nil {
|
||||
mr, _, err := mrutils.MRFromArgs(f, args, "any")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mr.HeadPipeline == nil {
|
||||
return fmt.Errorf("no pipeline found. It might not exist yet. If this problem continues, check your pipeline configuration.")
|
||||
} else {
|
||||
pipelineId = mr.HeadPipeline.ID
|
||||
}
|
||||
|
||||
} else {
|
||||
pipelineId = commit.LastPipeline.ID
|
||||
}
|
||||
}
|
||||
|
||||
pipeline, err := api.GetPipeline(apiClient, pipelineId, nil, repo.FullName())
|
||||
|
|
|
@ -392,6 +392,88 @@ updated: 2023-10-10 00:00:00 +0000 UTC
|
|||
|
||||
# Variables:
|
||||
No variables found in pipeline.
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "when there is a merged result pipeline and no commit pipeline",
|
||||
args: "-b=main",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 5,
|
||||
"status": "pending",
|
||||
"source": "push",
|
||||
"ref": "main",
|
||||
"sha": "0ff3ae198f8601a285adcf5c0fff204ee6fba5fd",
|
||||
"user": {
|
||||
"username": "test"
|
||||
},
|
||||
"yaml_errors": "-",
|
||||
"created_at": "2023-10-10T00:00:00Z",
|
||||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/123/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
`[]`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/merge_requests/1",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"head_pipeline": {
|
||||
"id": 123
|
||||
}
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/merge_requests?per_page=30&source_branch=main",
|
||||
http.StatusOK,
|
||||
`[
|
||||
{
|
||||
"iid": 1
|
||||
}
|
||||
]`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/repository/commits/main",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"last_pipeline": null
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
},
|
||||
expectedOut: `# Pipeline:
|
||||
id: 123
|
||||
status: pending
|
||||
source: push
|
||||
ref: main
|
||||
sha: 0ff3ae198f8601a285adcf5c0fff204ee6fba5fd
|
||||
tag: false
|
||||
yaml Errors: -
|
||||
user: test
|
||||
created: 2023-10-10 00:00:00 +0000 UTC
|
||||
started: 2023-10-10 00:00:00 +0000 UTC
|
||||
updated: 2023-10-10 00:00:00 +0000 UTC
|
||||
|
||||
# Jobs:
|
||||
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -47,14 +47,14 @@ func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
|||
l.PerPage = 30
|
||||
|
||||
if m, _ := cmd.Flags().GetString("status"); m != "" {
|
||||
l.Status = gitlab.BuildState(gitlab.BuildStateValue(m))
|
||||
l.Status = gitlab.Ptr(gitlab.BuildStateValue(m))
|
||||
titleQualifier = m
|
||||
}
|
||||
if m, _ := cmd.Flags().GetString("orderBy"); m != "" {
|
||||
l.OrderBy = gitlab.String(m)
|
||||
l.OrderBy = gitlab.Ptr(m)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetString("sort"); m != "" {
|
||||
l.Sort = gitlab.String(m)
|
||||
l.Sort = gitlab.Ptr(m)
|
||||
}
|
||||
if p, _ := cmd.Flags().GetInt("page"); p != 0 {
|
||||
l.Page = p
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/ci/ciutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/pkg/git"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -22,27 +22,6 @@ var (
|
|||
|
||||
var envVariables = []string{}
|
||||
|
||||
func getDefaultBranch(f *cmdutils.Factory) string {
|
||||
repo, err := f.BaseRepo()
|
||||
if err != nil {
|
||||
return "master"
|
||||
}
|
||||
|
||||
remotes, err := f.Remotes()
|
||||
if err != nil {
|
||||
return "master"
|
||||
}
|
||||
|
||||
repoRemote, err := remotes.FindByRepo(repo.RepoOwner(), repo.RepoName())
|
||||
if err != nil {
|
||||
return "master"
|
||||
}
|
||||
|
||||
branch, _ := git.GetDefaultBranch(repoRemote.Name)
|
||||
|
||||
return branch
|
||||
}
|
||||
|
||||
func parseVarArg(s string) (*gitlab.PipelineVariableOptions, error) {
|
||||
// From https://pkg.go.dev/strings#Split:
|
||||
//
|
||||
|
@ -161,13 +140,13 @@ func NewCmdRun(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
if branch != "" {
|
||||
c.Ref = gitlab.String(branch)
|
||||
c.Ref = gitlab.Ptr(branch)
|
||||
} else if currentBranch, err := f.Branch(); err == nil {
|
||||
c.Ref = gitlab.String(currentBranch)
|
||||
c.Ref = gitlab.Ptr(currentBranch)
|
||||
} else {
|
||||
// `ci run` is running out of a git repo
|
||||
fmt.Fprintln(f.IO.StdOut, "not in a git repository, using repository argument")
|
||||
c.Ref = gitlab.String(getDefaultBranch(f))
|
||||
c.Ref = gitlab.Ptr(ciutils.GetDefaultBranch(f))
|
||||
}
|
||||
|
||||
pipe, err := api.CreatePipeline(apiClient, repo.FullName(), c)
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
package run_trig
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/ci/ciutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
var envVariables = []string{}
|
||||
|
||||
func parseVarArg(s string) (key string, val string, err error) {
|
||||
// From https://pkg.go.dev/strings#Split:
|
||||
//
|
||||
// > If s does not contain sep and sep is not empty,
|
||||
// > Split returns a slice of length 1 whose only element is s.
|
||||
//
|
||||
// Therefore, the function will always return a slice of min length 1.
|
||||
v := strings.SplitN(s, ":", 2)
|
||||
if len(v) == 1 {
|
||||
return "", "", fmt.Errorf("invalid argument structure")
|
||||
}
|
||||
return v[0], v[1], nil
|
||||
}
|
||||
|
||||
func NewCmdRunTrig(f *cmdutils.Factory) *cobra.Command {
|
||||
pipelineRunCmd := &cobra.Command{
|
||||
Use: "run-trig [flags]",
|
||||
Short: `Run a CI/CD pipeline trigger`,
|
||||
Aliases: []string{"run-trig"},
|
||||
Example: heredoc.Doc(`
|
||||
glab ci run-trig -t xxxx
|
||||
glab ci run-trig -t xxxx -b main
|
||||
glab ci run-trig -t xxxx -b main --variables key1:val1
|
||||
glab ci run-trig -t xxxx -b main --variables key1:val1,key2:val2
|
||||
glab ci run-trig -t xxxx -b main --variables key1:val1 --variables key2:val2
|
||||
`),
|
||||
Long: ``,
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var err error
|
||||
|
||||
apiClient, err := f.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo, err := f.BaseRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c := &gitlab.RunPipelineTriggerOptions{
|
||||
Variables: make(map[string]string),
|
||||
}
|
||||
|
||||
if customPipelineVars, _ := cmd.Flags().GetStringSlice("variables"); len(customPipelineVars) > 0 {
|
||||
for _, v := range customPipelineVars {
|
||||
key, val, err := parseVarArg(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing pipeline variable expected format KEY:VALUE: %w", err)
|
||||
}
|
||||
c.Variables[key] = val
|
||||
}
|
||||
}
|
||||
|
||||
branch, err := cmd.Flags().GetString("branch")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if branch != "" {
|
||||
c.Ref = gitlab.Ptr(branch)
|
||||
} else if currentBranch, err := f.Branch(); err == nil {
|
||||
c.Ref = gitlab.Ptr(currentBranch)
|
||||
} else {
|
||||
// `ci run-trig` is running out of a git repo
|
||||
fmt.Fprintln(f.IO.StdOut, "not in a git repository, using repository argument")
|
||||
c.Ref = gitlab.Ptr(ciutils.GetDefaultBranch(f))
|
||||
}
|
||||
|
||||
token, err := cmd.Flags().GetString("token")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if token == "" {
|
||||
token = os.Getenv("CI_JOB_TOKEN")
|
||||
}
|
||||
if token == "" {
|
||||
return errors.New("--token parameter can be omitted only if CI_JOB_TOKEN environment variable is set")
|
||||
}
|
||||
c.Token = &token
|
||||
|
||||
pipe, err := api.RunPipelineTrigger(apiClient, repo.FullName(), c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintln(f.IO.StdOut, "Created pipeline (id:", pipe.ID, "), status:", pipe.Status, ", ref:", pipe.Ref, ", weburl: ", pipe.WebURL, ")")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
pipelineRunCmd.Flags().StringP("token", "t", "", "Pipeline trigger token (can be omitted only if CI_JOB_TOKEN environment variable is set)")
|
||||
pipelineRunCmd.Flags().StringP("branch", "b", "", "Create pipeline on branch/ref <string>")
|
||||
pipelineRunCmd.Flags().StringSliceVarP(&envVariables, "variables", "", []string{}, "Pass variables to pipeline in format <key>:<value>")
|
||||
|
||||
return pipelineRunCmd
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package run_trig
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
type ResponseJSON struct {
|
||||
Token string `json:"token"`
|
||||
Ref string `json:"ref"`
|
||||
}
|
||||
|
||||
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
factory.Branch = func() (string, error) {
|
||||
return "custom-branch-123", nil
|
||||
}
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
cmd := NewCmdRunTrig(factory)
|
||||
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestCIRun(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cli string
|
||||
ciJobToken string
|
||||
expectedPOSTBody string
|
||||
expectedOut string
|
||||
}{
|
||||
{
|
||||
name: "when running `ci run-trig` without branch parameter, defaults to current branch",
|
||||
cli: "-t foobar",
|
||||
ciJobToken: "",
|
||||
expectedPOSTBody: fmt.Sprintf(`"ref":"%s"`, "custom-branch-123"),
|
||||
expectedOut: fmt.Sprintf("Created pipeline (id: 123 ), status: created , ref: %s , weburl: https://gitlab.com/OWNER/REPO/-/pipelines/123 )\n", "custom-branch-123"),
|
||||
},
|
||||
{
|
||||
name: "when running `ci run-trig` with branch parameter, run CI at branch",
|
||||
cli: "-t foobar -b ci-cd-improvement-399",
|
||||
ciJobToken: "",
|
||||
expectedPOSTBody: `"ref":"ci-cd-improvement-399"`,
|
||||
expectedOut: "Created pipeline (id: 123 ), status: created , ref: ci-cd-improvement-399 , weburl: https://gitlab.com/OWNER/REPO/-/pipelines/123 )\n",
|
||||
},
|
||||
{
|
||||
name: "when running `ci run-trig` without any parameter, takes trigger token from env variable",
|
||||
cli: "",
|
||||
ciJobToken: "foobar",
|
||||
expectedPOSTBody: fmt.Sprintf(`"ref":"%s"`, "custom-branch-123"),
|
||||
expectedOut: fmt.Sprintf("Created pipeline (id: 123 ), status: created , ref: %s , weburl: https://gitlab.com/OWNER/REPO/-/pipelines/123 )\n", "custom-branch-123"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeHTTP := &httpmock.Mocker{
|
||||
MatchURL: httpmock.PathAndQuerystring,
|
||||
}
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
initialEnvValue := os.Getenv("CI_JOB_TOKEN")
|
||||
os.Setenv("CI_JOB_TOKEN", tc.ciJobToken)
|
||||
defer os.Setenv("CI_JOB_TOKEN", initialEnvValue)
|
||||
|
||||
fakeHTTP.RegisterResponder(http.MethodPost, "/api/v4/projects/OWNER/REPO/trigger/pipeline",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
rb, _ := io.ReadAll(req.Body)
|
||||
|
||||
var response ResponseJSON
|
||||
err := json.Unmarshal(rb, &response)
|
||||
if err != nil {
|
||||
fmt.Printf("Error when parsing response body %s\n", rb)
|
||||
}
|
||||
|
||||
if response.Token != "foobar" {
|
||||
fmt.Printf("Invalid token %s\n", rb)
|
||||
}
|
||||
|
||||
// ensure CLI runs CI on correct branch
|
||||
assert.Contains(t, string(rb), tc.expectedPOSTBody)
|
||||
resp, _ := httpmock.NewStringResponse(http.StatusOK, fmt.Sprintf(`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"status": "created",
|
||||
"ref": "%s",
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/pipelines/123"}`, response.Ref))(req)
|
||||
return resp, nil
|
||||
},
|
||||
)
|
||||
|
||||
output, _ := runCommand(fakeHTTP, false, tc.cli)
|
||||
|
||||
out := output.String()
|
||||
|
||||
assert.Equal(t, tc.expectedOut, out)
|
||||
assert.Empty(t, output.Stderr())
|
||||
})
|
||||
}
|
||||
}
|
|
@ -162,6 +162,9 @@ func InitFactory(ios *iostreams.IOStreams, rt http.RoundTripper) *cmdutils.Facto
|
|||
BaseRepo: func() (glrepo.Interface, error) {
|
||||
return glrepo.New("OWNER", "REPO"), nil
|
||||
},
|
||||
Branch: func() (string, error) {
|
||||
return "main", nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -183,8 +183,8 @@ func MilestonesPrompt(response *int, apiClient *gitlab.Client, repoRemote *glrep
|
|||
milestoneMap := map[string]int{}
|
||||
|
||||
lOpts := &api.ListMilestonesOptions{
|
||||
IncludeParentMilestones: gitlab.Bool(true),
|
||||
State: gitlab.String("active"),
|
||||
IncludeParentMilestones: gitlab.Ptr(true),
|
||||
State: gitlab.Ptr("active"),
|
||||
PerPage: 100,
|
||||
}
|
||||
milestones, err := api.ListAllMilestones(apiClient, repoRemote.FullName(), lOpts)
|
||||
|
|
|
@ -19,13 +19,13 @@ func NewCmdConfig(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
Current respected settings:
|
||||
|
||||
- token: Your GitLab access token, defaults to environment variables
|
||||
- token: your GitLab access token, defaults to environment variables
|
||||
- host: if unset, defaults to %[1]shttps://gitlab.com%[1]s
|
||||
- browser: if unset, defaults to environment variables
|
||||
- editor: if unset, defaults to environment variables
|
||||
- visual: alternative for editor. If unset, defaults to environment variables
|
||||
- glamour_style: Your desired Markdown renderer style. Options are dark, light, notty. Custom styles are allowed using [glamour](https://github.com/charmbracelet/glamour#styles)
|
||||
- glab_pager: Your desired pager command to use (e.g. less -R)
|
||||
- browser: if unset, default browser is used. Override with environment variable $BROWSER
|
||||
- editor: if unset, default editor is used. Override with environment variable $EDITOR
|
||||
- visual: takes precedence over editor. If unset, default editor is used. Override with environment variable $VISUAL
|
||||
- glamour_style: your desired Markdown renderer style. Options are dark, light, notty. Custom styles are allowed using [glamour](https://github.com/charmbracelet/glamour#styles)
|
||||
- glab_pager: your desired pager command to use (e.g. less -R)
|
||||
- check_update: if true, notifies of any available updates to glab. Defaults to true
|
||||
- display_hyperlinks: if true, and using a TTY, outputs hyperlinks for issues and MR lists. Defaults to false
|
||||
`, "`"),
|
||||
|
|
|
@ -54,7 +54,7 @@ func NewCmdClose(f *cmdutils.Factory, issueType issuable.IssueType) *cobra.Comma
|
|||
}
|
||||
|
||||
l := &gitlab.UpdateIssueOptions{}
|
||||
l.StateEvent = gitlab.String("close")
|
||||
l.StateEvent = gitlab.Ptr("close")
|
||||
|
||||
c := f.IO.Color()
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ type ListOptions struct {
|
|||
ListType string
|
||||
TitleQualifier string
|
||||
OutputFormat string
|
||||
Output string
|
||||
|
||||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (glrepo.Interface, error)
|
||||
|
@ -138,10 +139,12 @@ func NewCmdList(f *cmdutils.Factory, runE func(opts *ListOptions) error, issueTy
|
|||
issueListCmd.Flags().BoolVarP(&opts.All, "all", "A", false, fmt.Sprintf("Get all %ss", issueType))
|
||||
issueListCmd.Flags().BoolVarP(&opts.Closed, "closed", "c", false, fmt.Sprintf("Get only closed %ss", issueType))
|
||||
issueListCmd.Flags().BoolVarP(&opts.Confidential, "confidential", "C", false, fmt.Sprintf("Filter by confidential %ss", issueType))
|
||||
issueListCmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "details", "One of 'details', 'ids', 'urls' or 'json'")
|
||||
issueListCmd.Flags().StringVarP(&opts.OutputFormat, "output-format", "F", "details", "One of 'details', 'ids', 'urls'")
|
||||
issueListCmd.Flags().StringVarP(&opts.Output, "output", "O", "text", "One of 'text' or 'json'")
|
||||
issueListCmd.Flags().IntVarP(&opts.Page, "page", "p", 1, "Page number")
|
||||
issueListCmd.Flags().IntVarP(&opts.PerPage, "per-page", "P", 30, "Number of items to list per page.")
|
||||
issueListCmd.PersistentFlags().StringP("group", "g", "", "Select a group/subgroup. This option is ignored if a repo argument is set.")
|
||||
issueListCmd.MarkFlagsMutuallyExclusive("output", "output-format")
|
||||
|
||||
if issueType == issuable.TypeIssue {
|
||||
issueListCmd.Flags().StringVarP(&opts.IssueType, "issue-type", "t", "", "Filter issue by its type {issue|incident|test_case}")
|
||||
|
@ -170,8 +173,8 @@ func listRun(opts *ListOptions) error {
|
|||
}
|
||||
|
||||
listOpts := &gitlab.ListProjectIssuesOptions{
|
||||
State: gitlab.String(opts.State),
|
||||
In: gitlab.String(opts.In),
|
||||
State: gitlab.Ptr(opts.State),
|
||||
In: gitlab.Ptr(opts.In),
|
||||
}
|
||||
listOpts.Page = 1
|
||||
listOpts.PerPage = 30
|
||||
|
@ -184,7 +187,7 @@ func listRun(opts *ListOptions) error {
|
|||
}
|
||||
opts.Assignee = u.Username
|
||||
}
|
||||
listOpts.AssigneeUsername = gitlab.String(opts.Assignee)
|
||||
listOpts.AssigneeUsername = gitlab.Ptr(opts.Assignee)
|
||||
}
|
||||
if len(opts.NotAssignee) != 0 {
|
||||
u, err := api.UsersByNames(apiClient, opts.NotAssignee)
|
||||
|
@ -198,7 +201,7 @@ func listRun(opts *ListOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listOpts.AuthorID = gitlab.Int(u.ID)
|
||||
listOpts.AuthorID = gitlab.Ptr(u.ID)
|
||||
}
|
||||
if len(opts.NotAuthor) != 0 {
|
||||
u, err := api.UsersByNames(apiClient, opts.NotAuthor)
|
||||
|
@ -208,23 +211,23 @@ func listRun(opts *ListOptions) error {
|
|||
listOpts.NotAuthorID = cmdutils.IDsFromUsers(u)
|
||||
}
|
||||
if opts.Search != "" {
|
||||
listOpts.Search = gitlab.String(opts.Search)
|
||||
listOpts.Search = gitlab.Ptr(opts.Search)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if len(opts.Labels) != 0 {
|
||||
listOpts.Labels = (*gitlab.Labels)(&opts.Labels)
|
||||
listOpts.Labels = (*gitlab.LabelOptions)(&opts.Labels)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if len(opts.NotLabels) != 0 {
|
||||
listOpts.NotLabels = (*gitlab.Labels)(&opts.NotLabels)
|
||||
listOpts.NotLabels = (*gitlab.LabelOptions)(&opts.NotLabels)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if opts.Milestone != "" {
|
||||
listOpts.Milestone = gitlab.String(opts.Milestone)
|
||||
listOpts.Milestone = gitlab.Ptr(opts.Milestone)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if opts.Confidential {
|
||||
listOpts.Confidential = gitlab.Bool(opts.Confidential)
|
||||
listOpts.Confidential = gitlab.Ptr(opts.Confidential)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if opts.Page != 0 {
|
||||
|
@ -238,7 +241,7 @@ func listRun(opts *ListOptions) error {
|
|||
|
||||
issueType := "issue"
|
||||
if opts.IssueType != "" {
|
||||
listOpts.IssueType = gitlab.String(opts.IssueType)
|
||||
listOpts.IssueType = gitlab.Ptr(opts.IssueType)
|
||||
opts.ListType = "search"
|
||||
issueType = opts.IssueType
|
||||
}
|
||||
|
@ -263,7 +266,7 @@ func listRun(opts *ListOptions) error {
|
|||
title.ListActionType = opts.ListType
|
||||
title.CurrentPageTotal = len(issues)
|
||||
|
||||
if opts.OutputFormat == "json" {
|
||||
if opts.Output == "json" {
|
||||
issueListJSON, _ := json.Marshal(issues)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(issueListJSON))
|
||||
return nil
|
||||
|
|
|
@ -359,7 +359,7 @@ func TestIssueListJSON(t *testing.T) {
|
|||
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/issues",
|
||||
httpmock.NewFileResponse(http.StatusOK, "./testdata/issueListFull.json"))
|
||||
|
||||
output, err := runCommand("issue", fakeHTTP, true, "-F json", nil, "")
|
||||
output, err := runCommand("issue", fakeHTTP, true, "--output json", nil, "")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `issue list -F json`: %v", err)
|
||||
}
|
||||
|
@ -378,3 +378,10 @@ func TestIssueListJSON(t *testing.T) {
|
|||
assert.JSONEq(t, expectedOut, output.String())
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
||||
func TestIssueListMutualOutputFlags(t *testing.T) {
|
||||
_, err := runCommand("issue", nil, true, "--output json --output-format ids", nil, "")
|
||||
|
||||
assert.NotNil(t, err)
|
||||
assert.EqualError(t, err, "if any flags in the group [output output-format] are set none of the others can be; [output output-format] were all set")
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"label_details": null,
|
||||
"subscribed": false,
|
||||
"closed_by": null,
|
||||
"labels":"",
|
||||
"labels":[],
|
||||
"milestone": null,
|
||||
"assignees":
|
||||
[],
|
||||
|
|
|
@ -64,7 +64,7 @@ func NewCmdReopen(f *cmdutils.Factory, issueType issuable.IssueType) *cobra.Comm
|
|||
}
|
||||
|
||||
l := &gitlab.UpdateIssueOptions{}
|
||||
l.StateEvent = gitlab.String("reopen")
|
||||
l.StateEvent = gitlab.Ptr("reopen")
|
||||
|
||||
for _, issue := range issues {
|
||||
valid, msg := issuable.ValidateIncidentCmd(issueType, "reopen", issue)
|
||||
|
|
|
@ -95,7 +95,7 @@ func NewCmdView(f *cmdutils.Factory, issueType issuable.IssueType) *cobra.Comman
|
|||
|
||||
if opts.ShowComments {
|
||||
l := &gitlab.ListIssueNotesOptions{
|
||||
Sort: gitlab.String("asc"),
|
||||
Sort: gitlab.Ptr("asc"),
|
||||
}
|
||||
if opts.CommentPageNumber != 0 {
|
||||
l.Page = opts.CommentPageNumber
|
||||
|
|
|
@ -46,7 +46,7 @@ func NewCmdCreate(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
opts := &gitlab.CreateIssueBoardOptions{
|
||||
Name: gitlab.String(boardName),
|
||||
Name: gitlab.Ptr(boardName),
|
||||
}
|
||||
|
||||
fmt.Fprintln(out, "- Creating board")
|
||||
|
|
|
@ -205,7 +205,7 @@ func (opts *issueBoardViewOptions) getListProjectIssueOptions() *gitlab.ListProj
|
|||
}
|
||||
|
||||
if len(opts.labels) != 0 {
|
||||
labels := gitlab.Labels(opts.labels)
|
||||
labels := gitlab.LabelOptions(opts.labels)
|
||||
reqOpts.Labels = &labels
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ func (opts *issueBoardViewOptions) getListGroupIssueOptions() *gitlab.ListGroupI
|
|||
}
|
||||
|
||||
if len(opts.labels) != 0 {
|
||||
labels := gitlab.Labels(opts.labels)
|
||||
labels := gitlab.LabelOptions(opts.labels)
|
||||
reqOpts.Labels = &labels
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ func Test_issueBoardViewOptions_getListProjectIssueOptions(t *testing.T) {
|
|||
WithLabelDetails: &withLabelDetails,
|
||||
AssigneeUsername: &user,
|
||||
Milestone: &milestone,
|
||||
Labels: &gitlab.Labels{"a", "b", "c"},
|
||||
Labels: &gitlab.LabelOptions{"a", "b", "c"},
|
||||
State: &state,
|
||||
},
|
||||
},
|
||||
|
@ -98,7 +98,7 @@ func Test_issueBoardViewOptions_getListGroupIssueOptions(t *testing.T) {
|
|||
WithLabelDetails: &withLabelDetails,
|
||||
AssigneeUsername: &user,
|
||||
Milestone: &milestone,
|
||||
Labels: &gitlab.Labels{"a", "b", "c"},
|
||||
Labels: &gitlab.LabelOptions{"a", "b", "c"},
|
||||
State: &state,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -342,20 +342,20 @@ func createRun(opts *CreateOpts) error {
|
|||
}
|
||||
|
||||
if action == cmdutils.SubmitAction {
|
||||
issueCreateOpts.Title = gitlab.String(opts.Title)
|
||||
issueCreateOpts.Labels = (*gitlab.Labels)(&opts.Labels)
|
||||
issueCreateOpts.Title = gitlab.Ptr(opts.Title)
|
||||
issueCreateOpts.Labels = (*gitlab.LabelOptions)(&opts.Labels)
|
||||
issueCreateOpts.Description = &opts.Description
|
||||
if opts.IsConfidential {
|
||||
issueCreateOpts.Confidential = gitlab.Bool(opts.IsConfidential)
|
||||
issueCreateOpts.Confidential = gitlab.Ptr(opts.IsConfidential)
|
||||
}
|
||||
if opts.Weight != 0 {
|
||||
issueCreateOpts.Weight = gitlab.Int(opts.Weight)
|
||||
issueCreateOpts.Weight = gitlab.Ptr(opts.Weight)
|
||||
}
|
||||
if opts.LinkedMR != 0 {
|
||||
issueCreateOpts.MergeRequestToResolveDiscussionsOf = gitlab.Int(opts.LinkedMR)
|
||||
issueCreateOpts.MergeRequestToResolveDiscussionsOf = gitlab.Ptr(opts.LinkedMR)
|
||||
}
|
||||
if opts.Milestone != 0 {
|
||||
issueCreateOpts.MilestoneID = gitlab.Int(opts.Milestone)
|
||||
issueCreateOpts.MilestoneID = gitlab.Ptr(opts.Milestone)
|
||||
}
|
||||
if len(opts.Assignees) > 0 {
|
||||
users, err := api.UsersByNames(apiClient, opts.Assignees)
|
||||
|
@ -386,8 +386,8 @@ func postCreateActions(apiClient *gitlab.Client, issue *gitlab.Issue, opts *Crea
|
|||
for _, targetIssueIID := range opts.LinkedIssues {
|
||||
fmt.Fprintln(opts.IO.StdErr, "- Linking to issue ", targetIssueIID)
|
||||
issue, _, err = api.LinkIssues(apiClient, repo.FullName(), issue.IID, &gitlab.CreateIssueLinkOptions{
|
||||
TargetIssueIID: gitlab.String(strconv.Itoa(targetIssueIID)),
|
||||
LinkType: gitlab.String(opts.IssueLinkType),
|
||||
TargetIssueIID: gitlab.Ptr(strconv.Itoa(targetIssueIID)),
|
||||
LinkType: gitlab.Ptr(opts.IssueLinkType),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -397,7 +397,7 @@ func postCreateActions(apiClient *gitlab.Client, issue *gitlab.Issue, opts *Crea
|
|||
if opts.TimeEstimate != "" {
|
||||
fmt.Fprintln(opts.IO.StdErr, "- Adding time estimate ", opts.TimeEstimate)
|
||||
_, err := api.SetIssueTimeEstimate(apiClient, repo.FullName(), issue.IID, &gitlab.SetTimeEstimateOptions{
|
||||
Duration: gitlab.String(opts.TimeEstimate),
|
||||
Duration: gitlab.Ptr(opts.TimeEstimate),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -406,7 +406,7 @@ func postCreateActions(apiClient *gitlab.Client, issue *gitlab.Issue, opts *Crea
|
|||
if opts.TimeSpent != "" {
|
||||
fmt.Fprintln(opts.IO.StdErr, "- Adding time spent ", opts.TimeSpent)
|
||||
_, err := api.AddIssueTimeSpent(apiClient, repo.FullName(), issue.IID, &gitlab.AddSpentTimeOptions{
|
||||
Duration: gitlab.String(opts.TimeSpent),
|
||||
Duration: gitlab.Ptr(opts.TimeSpent),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -45,7 +45,7 @@ func Test_IssueCreate_Integration(t *testing.T) {
|
|||
ID: 1,
|
||||
IID: 1,
|
||||
Title: *opts.Title,
|
||||
Labels: *opts.Labels,
|
||||
Labels: gitlab.Labels(*opts.Labels),
|
||||
State: "opened",
|
||||
Description: *opts.Description,
|
||||
Weight: *opts.Weight,
|
||||
|
|
|
@ -70,15 +70,15 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
if m, _ := cmd.Flags().GetString("title"); m != "" {
|
||||
actions = append(actions, fmt.Sprintf("updated title to %q", m))
|
||||
l.Title = gitlab.String(m)
|
||||
l.Title = gitlab.Ptr(m)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetBool("lock-discussion"); m {
|
||||
actions = append(actions, "locked discussion")
|
||||
l.DiscussionLocked = gitlab.Bool(m)
|
||||
l.DiscussionLocked = gitlab.Ptr(m)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetBool("unlock-discussion"); m {
|
||||
actions = append(actions, "unlocked dicussion")
|
||||
l.DiscussionLocked = gitlab.Bool(false)
|
||||
l.DiscussionLocked = gitlab.Ptr(false)
|
||||
}
|
||||
|
||||
if m, _ := cmd.Flags().GetString("description"); m != "" {
|
||||
|
@ -102,30 +102,30 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
l.Description = gitlab.String("")
|
||||
l.Description = gitlab.Ptr("")
|
||||
err = cmdutils.EditorPrompt(l.Description, "Description", issue.Description, editor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
l.Description = gitlab.String(m)
|
||||
l.Description = gitlab.Ptr(m)
|
||||
}
|
||||
}
|
||||
if m, _ := cmd.Flags().GetStringSlice("label"); len(m) != 0 {
|
||||
actions = append(actions, fmt.Sprintf("added labels %s", strings.Join(m, " ")))
|
||||
l.AddLabels = (*gitlab.Labels)(&m)
|
||||
l.AddLabels = (*gitlab.LabelOptions)(&m)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetStringSlice("unlabel"); len(m) != 0 {
|
||||
actions = append(actions, fmt.Sprintf("removed labels %s", strings.Join(m, " ")))
|
||||
l.RemoveLabels = (*gitlab.Labels)(&m)
|
||||
l.RemoveLabels = (*gitlab.LabelOptions)(&m)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetBool("public"); m {
|
||||
actions = append(actions, "made public")
|
||||
l.Confidential = gitlab.Bool(false)
|
||||
l.Confidential = gitlab.Ptr(false)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetBool("confidential"); m {
|
||||
actions = append(actions, "made confidential")
|
||||
l.Confidential = gitlab.Bool(true)
|
||||
l.Confidential = gitlab.Ptr(true)
|
||||
}
|
||||
if ok := cmd.Flags().Changed("milestone"); ok {
|
||||
if m, _ := cmd.Flags().GetString("milestone"); m != "" || m == "0" {
|
||||
|
@ -134,11 +134,11 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
actions = append(actions, fmt.Sprintf("added milestone %q", m))
|
||||
l.MilestoneID = gitlab.Int(mID)
|
||||
l.MilestoneID = gitlab.Ptr(mID)
|
||||
} else {
|
||||
// Unassign the Milestone
|
||||
actions = append(actions, "unassigned milestone")
|
||||
l.MilestoneID = gitlab.Int(0)
|
||||
l.MilestoneID = gitlab.Ptr(0)
|
||||
}
|
||||
}
|
||||
if cmd.Flags().Changed("unassign") {
|
||||
|
|
|
@ -52,7 +52,7 @@ func TestNewCmdUpdate_Integration(t *testing.T) {
|
|||
testIssue.Description = *opts.Description
|
||||
}
|
||||
if opts.AddLabels != nil {
|
||||
testIssue.Labels = *opts.AddLabels
|
||||
testIssue.Labels = gitlab.Labels(*opts.AddLabels)
|
||||
}
|
||||
return testIssue, nil
|
||||
}
|
||||
|
|
|
@ -39,14 +39,14 @@ func NewCmdCreate(f *cmdutils.Factory) *cobra.Command {
|
|||
l := &gitlab.CreateLabelOptions{}
|
||||
|
||||
if s, _ := cmd.Flags().GetString("name"); s != "" {
|
||||
l.Name = gitlab.String(s)
|
||||
l.Name = gitlab.Ptr(s)
|
||||
}
|
||||
|
||||
if s, _ := cmd.Flags().GetString("color"); s != "" {
|
||||
l.Color = gitlab.String(s)
|
||||
l.Color = gitlab.Ptr(s)
|
||||
}
|
||||
if s, _ := cmd.Flags().GetString("description"); s != "" {
|
||||
l.Description = gitlab.String(s)
|
||||
l.Description = gitlab.Ptr(s)
|
||||
}
|
||||
label, err := api.CreateLabel(apiClient, repo.FullName(), l)
|
||||
if err != nil {
|
||||
|
|
|
@ -43,7 +43,7 @@ func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
l := &gitlab.ListLabelsOptions{}
|
||||
|
||||
l.WithCounts = gitlab.Bool(true)
|
||||
l.WithCounts = gitlab.Ptr(true)
|
||||
|
||||
if p, _ := cmd.Flags().GetInt("page"); p != 0 {
|
||||
l.Page = p
|
||||
|
|
|
@ -48,7 +48,7 @@ func NewCmdApprove(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
opts := &gitlab.ApproveMergeRequestOptions{}
|
||||
if s, _ := cmd.Flags().GetString("sha"); s != "" {
|
||||
opts.SHA = gitlab.String(s)
|
||||
opts.SHA = gitlab.Ptr(s)
|
||||
}
|
||||
|
||||
fmt.Fprintf(f.IO.StdOut, "- Approving Merge Request !%d\n", mr.IID)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/mr/mrutils"
|
||||
|
@ -67,12 +68,24 @@ func NewCmdCheckout(f *cmdutils.Factory) *cobra.Command {
|
|||
mrCheckoutCfg.branch = mr.SourceBranch
|
||||
}
|
||||
|
||||
mrProject, err := api.GetProject(apiClient, mr.SourceProjectID)
|
||||
var mrRef string
|
||||
var mrProject *gitlab.Project
|
||||
|
||||
mrProject, err = api.GetProject(apiClient, mr.SourceProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
// If we don't have access to the source project, let's try the target project
|
||||
mrProject, err = api.GetProject(apiClient, mr.TargetProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
// We found the target project, let's find the ref another way
|
||||
mrRef = fmt.Sprintf("refs/merge-requests/%d/head", mr.IID)
|
||||
}
|
||||
|
||||
} else {
|
||||
mrRef = fmt.Sprintf("refs/heads/%s", mr.SourceBranch)
|
||||
}
|
||||
|
||||
mrRef := fmt.Sprintf("refs/heads/%s", mr.SourceBranch)
|
||||
fetchRefSpec := fmt.Sprintf("%s:%s", mrRef, mrCheckoutCfg.branch)
|
||||
if err := git.RunCmd([]string{"fetch", mrProject.SSHURLToRepo, fetchRefSpec}); err != nil {
|
||||
return err
|
||||
|
|
|
@ -122,6 +122,64 @@ func TestMrCheckout(t *testing.T) {
|
|||
"git checkout feat-new-mr",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "when a valid MR comes from a forked private project",
|
||||
commandArgs: "123",
|
||||
branch: "main",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"source_project_id": 3,
|
||||
"target_project_id": 4,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"allow_collaboration": false,
|
||||
"state": "opened",
|
||||
"source_branch":"feat-new-mr"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/4",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 4,
|
||||
"ssh_url_to_repo": "git@gitlab.com:OWNER/REPO.git"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/3",
|
||||
http.StatusNotFound,
|
||||
`{
|
||||
"message":"404 Project Not Found"
|
||||
}`,
|
||||
},
|
||||
},
|
||||
shelloutStubs: []string{
|
||||
"HEAD branch: master\n",
|
||||
"\n",
|
||||
"\n",
|
||||
heredoc.Doc(`
|
||||
deadbeef HEAD
|
||||
deadb00f refs/remotes/upstream/feat-new-mr
|
||||
deadbeef refs/remotes/origin/feat-new-mr
|
||||
`),
|
||||
},
|
||||
|
||||
expectedShellouts: []string{
|
||||
"git fetch git@gitlab.com:OWNER/REPO.git refs/merge-requests/123/head:feat-new-mr",
|
||||
"git config branch.feat-new-mr.remote git@gitlab.com:OWNER/REPO.git",
|
||||
"git config branch.feat-new-mr.merge refs/merge-requests/123/head",
|
||||
"git checkout feat-new-mr",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "when a valid MR is checked out using MR id and specifying branch",
|
||||
commandArgs: "123 --branch foo",
|
||||
|
|
|
@ -39,7 +39,7 @@ func NewCmdClose(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
l := &gitlab.UpdateMergeRequestOptions{}
|
||||
l.StateEvent = gitlab.String("close")
|
||||
l.StateEvent = gitlab.Ptr("close")
|
||||
for _, mr := range mrs {
|
||||
if err = mrutils.MRCheckErrors(mr, mrutils.MRCheckErrOptions{
|
||||
Closed: true,
|
||||
|
|
|
@ -324,7 +324,7 @@ func createRun(opts *CreateOpts) error {
|
|||
}
|
||||
|
||||
if opts.CopyIssueLabels {
|
||||
mrCreateOpts.Labels = &issue.Labels
|
||||
mrCreateOpts.Labels = (*gitlab.LabelOptions)(&issue.Labels)
|
||||
}
|
||||
|
||||
opts.Description += fmt.Sprintf("\n\nCloses #%d", issue.IID)
|
||||
|
@ -475,15 +475,15 @@ func createRun(opts *CreateOpts) error {
|
|||
mrCreateOpts.TargetBranch = &opts.TargetBranch
|
||||
|
||||
if opts.AllowCollaboration {
|
||||
mrCreateOpts.AllowCollaboration = gitlab.Bool(true)
|
||||
mrCreateOpts.AllowCollaboration = gitlab.Ptr(true)
|
||||
}
|
||||
|
||||
if opts.RemoveSourceBranch {
|
||||
mrCreateOpts.RemoveSourceBranch = gitlab.Bool(true)
|
||||
mrCreateOpts.RemoveSourceBranch = gitlab.Ptr(true)
|
||||
}
|
||||
|
||||
if opts.SquashBeforeMerge {
|
||||
mrCreateOpts.Squash = gitlab.Bool(true)
|
||||
mrCreateOpts.Squash = gitlab.Ptr(true)
|
||||
}
|
||||
|
||||
if opts.TargetProject != nil {
|
||||
|
@ -576,7 +576,7 @@ func createRun(opts *CreateOpts) error {
|
|||
|
||||
// This check protects against possibly dereferencing a nil pointer.
|
||||
if mrCreateOpts.Labels == nil {
|
||||
mrCreateOpts.Labels = &gitlab.Labels{}
|
||||
mrCreateOpts.Labels = &gitlab.LabelOptions{}
|
||||
}
|
||||
// These actions need to be done here, after the `Add metadata` prompt because
|
||||
// they are metadata that can be modified by the prompt
|
||||
|
@ -599,7 +599,7 @@ func createRun(opts *CreateOpts) error {
|
|||
}
|
||||
|
||||
if opts.Milestone != 0 {
|
||||
mrCreateOpts.MilestoneID = gitlab.Int(opts.Milestone)
|
||||
mrCreateOpts.MilestoneID = gitlab.Ptr(opts.Milestone)
|
||||
}
|
||||
|
||||
if action == cmdutils.CancelAction {
|
||||
|
|
|
@ -92,7 +92,7 @@ func diffRun(opts *DiffOptions) error {
|
|||
diffOut := &bytes.Buffer{}
|
||||
for _, diff := range diffs {
|
||||
// the diffs are not included in the GetMergeRequestDiffVersions so we query for each diff version
|
||||
diffVersion, _, err := apiClient.MergeRequests.GetSingleMergeRequestDiffVersion(baseRepo.FullName(), mr.IID, diff.ID)
|
||||
diffVersion, _, err := apiClient.MergeRequests.GetSingleMergeRequestDiffVersion(baseRepo.FullName(), mr.IID, diff.ID, &gitlab.GetSingleMergeRequestDiffVersionOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find merge request diff: %w", err)
|
||||
}
|
||||
|
|
|
@ -67,8 +67,8 @@ func NewCmdFor(f *cmdutils.Factory) *cobra.Command {
|
|||
sourceBranch := fmt.Sprintf("%d-%s", issue.IID, utils.ReplaceNonAlphaNumericChars(strings.ToLower(issue.Title), "-"))
|
||||
|
||||
lb := &gitlab.CreateBranchOptions{
|
||||
Branch: gitlab.String(sourceBranch),
|
||||
Ref: gitlab.String(targetBranch),
|
||||
Branch: gitlab.Ptr(sourceBranch),
|
||||
Ref: gitlab.Ptr(targetBranch),
|
||||
}
|
||||
|
||||
_, err = api.CreateBranch(apiClient, repo.FullName(), lb)
|
||||
|
@ -77,8 +77,8 @@ func NewCmdFor(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
numberedBranch := fmt.Sprintf("%d-%s-%d", issue.IID, strings.ReplaceAll(strings.ToLower(issue.Title), " ", "-"), branchCount)
|
||||
lb = &gitlab.CreateBranchOptions{
|
||||
Branch: gitlab.String(numberedBranch),
|
||||
Ref: gitlab.String(targetBranch),
|
||||
Branch: gitlab.Ptr(numberedBranch),
|
||||
Ref: gitlab.Ptr(targetBranch),
|
||||
}
|
||||
sourceBranch = numberedBranch
|
||||
_, branchErr = api.CreateBranch(apiClient, repo.FullName(), lb)
|
||||
|
@ -102,22 +102,22 @@ func NewCmdFor(f *cmdutils.Factory) *cobra.Command {
|
|||
mergeLabel, _ := cmd.Flags().GetString("label")
|
||||
|
||||
l := &gitlab.CreateMergeRequestOptions{}
|
||||
l.Title = gitlab.String(mergeTitle)
|
||||
l.Description = gitlab.String(fmt.Sprintf("Closes #%d", issue.IID))
|
||||
l.Labels = &gitlab.Labels{mergeLabel}
|
||||
l.SourceBranch = gitlab.String(sourceBranch)
|
||||
l.TargetBranch = gitlab.String(targetBranch)
|
||||
l.Title = gitlab.Ptr(mergeTitle)
|
||||
l.Description = gitlab.Ptr(fmt.Sprintf("Closes #%d", issue.IID))
|
||||
l.Labels = &gitlab.LabelOptions{mergeLabel}
|
||||
l.SourceBranch = gitlab.Ptr(sourceBranch)
|
||||
l.TargetBranch = gitlab.Ptr(targetBranch)
|
||||
if milestone, _ := cmd.Flags().GetInt("milestone"); milestone != -1 {
|
||||
l.MilestoneID = gitlab.Int(milestone)
|
||||
l.MilestoneID = gitlab.Ptr(milestone)
|
||||
}
|
||||
if allowCol, _ := cmd.Flags().GetBool("allow-collaboration"); allowCol {
|
||||
l.AllowCollaboration = gitlab.Bool(true)
|
||||
l.AllowCollaboration = gitlab.Ptr(true)
|
||||
}
|
||||
if removeSource, _ := cmd.Flags().GetBool("remove-source-branch"); removeSource {
|
||||
l.RemoveSourceBranch = gitlab.Bool(true)
|
||||
l.RemoveSourceBranch = gitlab.Ptr(true)
|
||||
}
|
||||
if withLables, _ := cmd.Flags().GetBool("with-labels"); withLables {
|
||||
l.Labels = &issue.Labels
|
||||
l.Labels = (*gitlab.LabelOptions)(&issue.Labels)
|
||||
}
|
||||
|
||||
if a, _ := cmd.Flags().GetString("assignee"); a != "" {
|
||||
|
|
|
@ -166,7 +166,7 @@ func listRun(opts *ListOptions) error {
|
|||
}
|
||||
|
||||
l := &gitlab.ListProjectMergeRequestsOptions{
|
||||
State: gitlab.String(opts.State),
|
||||
State: gitlab.Ptr(opts.State),
|
||||
}
|
||||
jsonOutput := opts.OutputFormat == "json"
|
||||
if jsonOutput {
|
||||
|
@ -182,31 +182,31 @@ func listRun(opts *ListOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.AuthorID = gitlab.Int(u.ID)
|
||||
l.AuthorID = gitlab.Ptr(u.ID)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if opts.SourceBranch != "" {
|
||||
l.SourceBranch = gitlab.String(opts.SourceBranch)
|
||||
l.SourceBranch = gitlab.Ptr(opts.SourceBranch)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if opts.TargetBranch != "" {
|
||||
l.TargetBranch = gitlab.String(opts.TargetBranch)
|
||||
l.TargetBranch = gitlab.Ptr(opts.TargetBranch)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if opts.Search != "" {
|
||||
l.Search = gitlab.String(opts.Search)
|
||||
l.Search = gitlab.Ptr(opts.Search)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if len(opts.Labels) > 0 {
|
||||
l.Labels = (*gitlab.Labels)(&opts.Labels)
|
||||
l.Labels = (*gitlab.LabelOptions)(&opts.Labels)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if len(opts.NotLabels) > 0 {
|
||||
l.NotLabels = (*gitlab.Labels)(&opts.NotLabels)
|
||||
l.NotLabels = (*gitlab.LabelOptions)(&opts.NotLabels)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if opts.Milestone != "" {
|
||||
l.Milestone = gitlab.String(opts.Milestone)
|
||||
l.Milestone = gitlab.Ptr(opts.Milestone)
|
||||
opts.ListType = "search"
|
||||
}
|
||||
if opts.Page != 0 {
|
||||
|
@ -216,12 +216,12 @@ func listRun(opts *ListOptions) error {
|
|||
l.PerPage = opts.PerPage
|
||||
}
|
||||
if opts.Draft {
|
||||
l.WIP = gitlab.String("yes")
|
||||
l.WIP = gitlab.Ptr("yes")
|
||||
opts.ListType = "search"
|
||||
}
|
||||
|
||||
if opts.Mine {
|
||||
l.Scope = gitlab.String("assigned_to_me")
|
||||
l.Scope = gitlab.Ptr("assigned_to_me")
|
||||
opts.ListType = "search"
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
[],
|
||||
"source_project_id": 29316529,
|
||||
"target_project_id": 29316529,
|
||||
"labels": "",
|
||||
"labels": [],
|
||||
"label_details": null,
|
||||
"description": "Closes #1",
|
||||
"draft": true,
|
||||
|
@ -142,7 +142,7 @@
|
|||
[],
|
||||
"source_project_id": 29316529,
|
||||
"target_project_id": 29316529,
|
||||
"labels": "",
|
||||
"labels": [],
|
||||
"label_details": null,
|
||||
"description": "",
|
||||
"draft": false,
|
||||
|
|
|
@ -151,16 +151,16 @@ func NewCmdMerge(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
mergeOpts := &gitlab.AcceptMergeRequestOptions{}
|
||||
if opts.MergeCommitMessage != "" {
|
||||
mergeOpts.MergeCommitMessage = gitlab.String(opts.MergeCommitMessage)
|
||||
mergeOpts.MergeCommitMessage = gitlab.Ptr(opts.MergeCommitMessage)
|
||||
}
|
||||
if opts.SquashMessage != "" {
|
||||
mergeOpts.SquashCommitMessage = gitlab.String(opts.SquashMessage)
|
||||
mergeOpts.SquashCommitMessage = gitlab.Ptr(opts.SquashMessage)
|
||||
}
|
||||
if opts.SquashBeforeMerge {
|
||||
mergeOpts.Squash = gitlab.Bool(true)
|
||||
mergeOpts.Squash = gitlab.Ptr(true)
|
||||
}
|
||||
if opts.RemoveSourceBranch {
|
||||
mergeOpts.ShouldRemoveSourceBranch = gitlab.Bool(true)
|
||||
mergeOpts.ShouldRemoveSourceBranch = gitlab.Ptr(true)
|
||||
}
|
||||
if opts.SetAutoMerge && mr.Pipeline != nil {
|
||||
if mr.Pipeline.Status == "canceled" || mr.Pipeline.Status == "failed" {
|
||||
|
@ -168,10 +168,10 @@ func NewCmdMerge(f *cmdutils.Factory) *cobra.Command {
|
|||
fmt.Fprintln(f.IO.StdOut, c.FailedIcon(), "Cannot perform merge action")
|
||||
return cmdutils.SilentError
|
||||
}
|
||||
mergeOpts.MergeWhenPipelineSucceeds = gitlab.Bool(true)
|
||||
mergeOpts.MergeWhenPipelineSucceeds = gitlab.Ptr(true)
|
||||
}
|
||||
if opts.SHA != "" {
|
||||
mergeOpts.SHA = gitlab.String(opts.SHA)
|
||||
mergeOpts.SHA = gitlab.Ptr(opts.SHA)
|
||||
}
|
||||
|
||||
if opts.RebaseBeforeMerge {
|
||||
|
@ -211,7 +211,6 @@ func NewCmdMerge(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
return err
|
||||
}, retry.Attempts(3), retry.Delay(time.Second*6))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -234,14 +234,14 @@ var getMRForBranch = func(apiClient *gitlab.Client, baseRepo glrepo.Interface, a
|
|||
}
|
||||
|
||||
opts := gitlab.ListProjectMergeRequestsOptions{
|
||||
SourceBranch: gitlab.String(currentBranch),
|
||||
SourceBranch: gitlab.Ptr(currentBranch),
|
||||
}
|
||||
|
||||
// Set the state value if it is not empty, if it is empty then it will look at all possible
|
||||
// values, 'any' is also a descriptive keyword used in the source code that is equivalent to
|
||||
// passing nothing on
|
||||
if state != "" && state != "any" {
|
||||
opts.State = gitlab.String(state)
|
||||
opts.State = gitlab.Ptr(state)
|
||||
}
|
||||
|
||||
mrs, err := api.ListMRs(apiClient, baseRepo.FullName(), &opts)
|
||||
|
@ -291,7 +291,7 @@ var getMRForBranch = func(apiClient *gitlab.Client, baseRepo glrepo.Interface, a
|
|||
return mrMap[pickedMR], nil
|
||||
}
|
||||
|
||||
func RebaseMR(ios *iostreams.IOStreams, apiClient *gitlab.Client, repo glrepo.Interface, mr *gitlab.MergeRequest, rebaseOpts gitlab.RequestOptionFunc) error {
|
||||
func RebaseMR(ios *iostreams.IOStreams, apiClient *gitlab.Client, repo glrepo.Interface, mr *gitlab.MergeRequest, rebaseOpts *gitlab.RebaseMergeRequestOptions) error {
|
||||
ios.StartSpinner("Sending rebase request...")
|
||||
err := api.RebaseMR(apiClient, repo.FullName(), mr.IID, rebaseOpts)
|
||||
if err != nil {
|
||||
|
@ -300,7 +300,7 @@ func RebaseMR(ios *iostreams.IOStreams, apiClient *gitlab.Client, repo glrepo.In
|
|||
ios.StopSpinner("")
|
||||
|
||||
opts := &gitlab.GetMergeRequestsOptions{}
|
||||
opts.IncludeRebaseInProgress = gitlab.Bool(true)
|
||||
opts.IncludeRebaseInProgress = gitlab.Ptr(true)
|
||||
ios.StartSpinner("Checking rebase status...")
|
||||
errorMSG := ""
|
||||
i := 0
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
package rebase
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/mr/mrutils"
|
||||
|
||||
"github.com/hashicorp/go-retryablehttp"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -44,18 +42,10 @@ func NewCmdRebase(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
requestOptionFunc := func(req *retryablehttp.Request) error {
|
||||
if opts.SkipCI {
|
||||
q := req.URL.Query()
|
||||
q.Add("skip_ci", strconv.FormatBool(opts.SkipCI))
|
||||
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = mrutils.RebaseMR(f.IO, apiClient, repo, mr, requestOptionFunc); err != nil {
|
||||
if err = mrutils.RebaseMR(f.IO, apiClient, repo, mr,
|
||||
&gitlab.RebaseMergeRequestOptions{
|
||||
SkipCI: gitlab.Ptr(opts.SkipCI),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ func TestMrRebase(t *testing.T) {
|
|||
},
|
||||
{
|
||||
http.MethodPut,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123/rebase?skip_ci=true",
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123/rebase",
|
||||
http.StatusAccepted,
|
||||
`{ "rebase_in_progress": true }`,
|
||||
},
|
||||
|
|
|
@ -36,7 +36,7 @@ func NewCmdReopen(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
l := &gitlab.UpdateMergeRequestOptions{}
|
||||
l.StateEvent = gitlab.String("reopen")
|
||||
l.StateEvent = gitlab.Ptr("reopen")
|
||||
for _, mr := range mrs {
|
||||
if err = mrutils.MRCheckErrors(mr, mrutils.MRCheckErrOptions{
|
||||
Opened: true,
|
||||
|
|
|
@ -116,14 +116,14 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command {
|
|||
mergeTitle = strings.TrimSpace(mergeTitle)
|
||||
}
|
||||
|
||||
l.Title = gitlab.String(mergeTitle)
|
||||
l.Title = gitlab.Ptr(mergeTitle)
|
||||
if m, _ := cmd.Flags().GetBool("lock-discussion"); m {
|
||||
actions = append(actions, "locked discussion")
|
||||
l.DiscussionLocked = gitlab.Bool(m)
|
||||
l.DiscussionLocked = gitlab.Ptr(m)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetBool("unlock-discussion"); m {
|
||||
actions = append(actions, "unlocked discussion")
|
||||
l.DiscussionLocked = gitlab.Bool(false)
|
||||
l.DiscussionLocked = gitlab.Ptr(false)
|
||||
}
|
||||
|
||||
if m, _ := cmd.Flags().GetString("description"); m != "" {
|
||||
|
@ -142,27 +142,27 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
l.Description = gitlab.String("")
|
||||
l.Description = gitlab.Ptr("")
|
||||
err = cmdutils.EditorPrompt(l.Description, "Description", mr.Description, editor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
l.Description = gitlab.String(m)
|
||||
l.Description = gitlab.Ptr(m)
|
||||
}
|
||||
}
|
||||
|
||||
if m, _ := cmd.Flags().GetStringSlice("label"); len(m) != 0 {
|
||||
actions = append(actions, fmt.Sprintf("added labels %s", strings.Join(m, " ")))
|
||||
l.AddLabels = (*gitlab.Labels)(&m)
|
||||
l.AddLabels = (*gitlab.LabelOptions)(&m)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetStringSlice("unlabel"); len(m) != 0 {
|
||||
actions = append(actions, fmt.Sprintf("removed labels %s", strings.Join(m, " ")))
|
||||
l.RemoveLabels = (*gitlab.Labels)(&m)
|
||||
l.RemoveLabels = (*gitlab.LabelOptions)(&m)
|
||||
}
|
||||
if m, _ := cmd.Flags().GetString("target-branch"); m != "" {
|
||||
actions = append(actions, fmt.Sprintf("set target branch to %q", m))
|
||||
l.TargetBranch = gitlab.String(m)
|
||||
l.TargetBranch = gitlab.Ptr(m)
|
||||
}
|
||||
if ok := cmd.Flags().Changed("milestone"); ok {
|
||||
if m, _ := cmd.Flags().GetString("milestone"); m != "" || m == "0" {
|
||||
|
@ -171,11 +171,11 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
actions = append(actions, fmt.Sprintf("added milestone %q", m))
|
||||
l.MilestoneID = gitlab.Int(mID)
|
||||
l.MilestoneID = gitlab.Ptr(mID)
|
||||
} else {
|
||||
// Unassign the Milestone
|
||||
actions = append(actions, "unassigned milestone")
|
||||
l.MilestoneID = gitlab.Int(0)
|
||||
l.MilestoneID = gitlab.Ptr(0)
|
||||
}
|
||||
}
|
||||
if cmd.Flags().Changed("unassign") {
|
||||
|
@ -218,7 +218,7 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command {
|
|||
actions = append(actions, "enabled removal of source branch on merge")
|
||||
}
|
||||
|
||||
l.RemoveSourceBranch = gitlab.Bool(!mr.ForceRemoveSourceBranch)
|
||||
l.RemoveSourceBranch = gitlab.Ptr(!mr.ForceRemoveSourceBranch)
|
||||
}
|
||||
|
||||
if squashBeforeMerge, _ := cmd.Flags().GetBool("squash-before-merge"); squashBeforeMerge {
|
||||
|
@ -229,7 +229,7 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command {
|
|||
actions = append(actions, "enabled squashing of commits before merge")
|
||||
}
|
||||
|
||||
l.Squash = gitlab.Bool(!mr.Squash)
|
||||
l.Squash = gitlab.Ptr(!mr.Squash)
|
||||
}
|
||||
|
||||
fmt.Fprintf(f.IO.StdOut, "- Updating merge request !%d\n", mr.IID)
|
||||
|
|
|
@ -52,9 +52,9 @@ func NewCmdView(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
mr, baseRepo, err := mrutils.MRFromArgsWithOpts(f, args, &gitlab.GetMergeRequestsOptions{
|
||||
IncludeDivergedCommitsCount: gitlab.Bool(true),
|
||||
RenderHTML: gitlab.Bool(true),
|
||||
IncludeRebaseInProgress: gitlab.Bool(true),
|
||||
IncludeDivergedCommitsCount: gitlab.Ptr(true),
|
||||
RenderHTML: gitlab.Ptr(true),
|
||||
IncludeRebaseInProgress: gitlab.Ptr(true),
|
||||
}, "any")
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -85,7 +85,7 @@ func NewCmdView(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
if opts.ShowComments {
|
||||
l := &gitlab.ListMergeRequestNotesOptions{
|
||||
Sort: gitlab.String("asc"),
|
||||
Sort: gitlab.Ptr("asc"),
|
||||
}
|
||||
l.Page = opts.CommentPageNumber
|
||||
l.PerPage = opts.CommentLimit
|
||||
|
|
|
@ -66,9 +66,9 @@ func NewCmdArchive(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
l := &gitlab.ArchiveOptions{}
|
||||
l.Format = gitlab.String(format)
|
||||
l.Format = gitlab.Ptr(format)
|
||||
if sha, _ := cmd.Flags().GetString("sha"); sha != "" {
|
||||
l.SHA = gitlab.String(sha)
|
||||
l.SHA = gitlab.Ptr(sha)
|
||||
}
|
||||
ext := *l.Format
|
||||
archiveName := strings.ReplaceAll(repo.FullName(), "/", "-") + "." + ext
|
||||
|
|
|
@ -186,26 +186,26 @@ func groupClone(opts *CloneOptions, ctxOpts *ContextOpts) error {
|
|||
c := opts.IO.Color()
|
||||
ListGroupProjectOpts := &gitlab.ListGroupProjectsOptions{}
|
||||
if opts.WithShared {
|
||||
ListGroupProjectOpts.WithShared = gitlab.Bool(true)
|
||||
ListGroupProjectOpts.WithShared = gitlab.Ptr(true)
|
||||
}
|
||||
if opts.WithMREnabled {
|
||||
ListGroupProjectOpts.WithMergeRequestsEnabled = gitlab.Bool(true)
|
||||
ListGroupProjectOpts.WithMergeRequestsEnabled = gitlab.Ptr(true)
|
||||
}
|
||||
if opts.WithIssuesEnabled {
|
||||
ListGroupProjectOpts.WithIssuesEnabled = gitlab.Bool(true)
|
||||
ListGroupProjectOpts.WithIssuesEnabled = gitlab.Ptr(true)
|
||||
}
|
||||
if opts.Owned {
|
||||
ListGroupProjectOpts.Owned = gitlab.Bool(true)
|
||||
ListGroupProjectOpts.Owned = gitlab.Ptr(true)
|
||||
}
|
||||
if opts.ArchivedSet {
|
||||
ListGroupProjectOpts.Archived = gitlab.Bool(opts.Archived)
|
||||
ListGroupProjectOpts.Archived = gitlab.Ptr(opts.Archived)
|
||||
}
|
||||
if opts.IncludeSubgroups {
|
||||
includeSubGroups := true
|
||||
ListGroupProjectOpts.IncludeSubGroups = &includeSubGroups
|
||||
}
|
||||
if opts.Visibility != "" {
|
||||
ListGroupProjectOpts.Visibility = gitlab.Visibility(gitlab.VisibilityValue(opts.Visibility))
|
||||
ListGroupProjectOpts.Visibility = gitlab.Ptr(gitlab.VisibilityValue(opts.Visibility))
|
||||
}
|
||||
|
||||
ListGroupProjectOpts.PerPage = 100
|
||||
|
|
|
@ -77,10 +77,10 @@ func runE(opts *Options) error {
|
|||
}
|
||||
|
||||
l := &gitlab.ListContributorsOptions{
|
||||
OrderBy: gitlab.String(opts.OrderBy),
|
||||
OrderBy: gitlab.Ptr(opts.OrderBy),
|
||||
}
|
||||
if opts.Sort != "" {
|
||||
l.Sort = gitlab.String(opts.Sort)
|
||||
l.Sort = gitlab.Ptr(opts.Sort)
|
||||
}
|
||||
l.PerPage = opts.PerPage
|
||||
l.Page = opts.Page
|
||||
|
|
|
@ -152,12 +152,12 @@ func runCreateProject(cmd *cobra.Command, args []string, f *cmdutils.Factory) er
|
|||
readme, _ := cmd.Flags().GetBool("readme")
|
||||
|
||||
opts := &gitlab.CreateProjectOptions{
|
||||
Name: gitlab.String(name),
|
||||
Path: gitlab.String(projectPath),
|
||||
Description: gitlab.String(description),
|
||||
DefaultBranch: gitlab.String(defaultBranch),
|
||||
Name: gitlab.Ptr(name),
|
||||
Path: gitlab.Ptr(projectPath),
|
||||
Description: gitlab.Ptr(description),
|
||||
DefaultBranch: gitlab.Ptr(defaultBranch),
|
||||
TagList: &tags,
|
||||
InitializeWithReadme: gitlab.Bool(readme),
|
||||
InitializeWithReadme: gitlab.Ptr(readme),
|
||||
}
|
||||
|
||||
if visiblity != "" {
|
||||
|
|
|
@ -137,10 +137,10 @@ func forkRun(opts *ForkOptions) error {
|
|||
|
||||
forkOpts := &gitlab.ForkProjectOptions{}
|
||||
if opts.Name != "" {
|
||||
forkOpts.Name = gitlab.String(opts.Name)
|
||||
forkOpts.Name = gitlab.Ptr(opts.Name)
|
||||
}
|
||||
if opts.Path != "" {
|
||||
forkOpts.Path = gitlab.String(opts.Path)
|
||||
forkOpts.Path = gitlab.Ptr(opts.Path)
|
||||
}
|
||||
|
||||
forkedProject, err := api.ForkProject(opts.LabClient, opts.RepoToFork.FullName(), forkOpts)
|
||||
|
|
|
@ -106,31 +106,31 @@ func runE(opts *Options) error {
|
|||
|
||||
func listAllProjects(apiClient *gitlab.Client, opts Options) ([]*gitlab.Project, *gitlab.Response, error) {
|
||||
l := &gitlab.ListProjectsOptions{
|
||||
OrderBy: gitlab.String(opts.OrderBy),
|
||||
OrderBy: gitlab.Ptr(opts.OrderBy),
|
||||
}
|
||||
|
||||
// Other filters only valid if FilterAll not true
|
||||
if !opts.FilterAll {
|
||||
if !opts.FilterStarred && !opts.FilterMember {
|
||||
// if no other filters are passed, default to Owned filter
|
||||
l.Owned = gitlab.Bool(true)
|
||||
l.Owned = gitlab.Ptr(true)
|
||||
}
|
||||
|
||||
if opts.FilterOwned {
|
||||
l.Owned = gitlab.Bool(opts.FilterOwned)
|
||||
l.Owned = gitlab.Ptr(opts.FilterOwned)
|
||||
}
|
||||
|
||||
if opts.FilterStarred {
|
||||
l.Starred = gitlab.Bool(opts.FilterStarred)
|
||||
l.Starred = gitlab.Ptr(opts.FilterStarred)
|
||||
}
|
||||
|
||||
if opts.FilterMember {
|
||||
l.Membership = gitlab.Bool(opts.FilterMember)
|
||||
l.Membership = gitlab.Ptr(opts.FilterMember)
|
||||
}
|
||||
}
|
||||
|
||||
if opts.Sort != "" {
|
||||
l.Sort = gitlab.String(opts.Sort)
|
||||
l.Sort = gitlab.Ptr(opts.Sort)
|
||||
}
|
||||
|
||||
l.PerPage = opts.PerPage
|
||||
|
@ -157,27 +157,27 @@ func listAllProjectsForGroup(apiClient *gitlab.Client, opts Options) ([]*gitlab.
|
|||
}
|
||||
|
||||
l := &gitlab.ListGroupProjectsOptions{
|
||||
OrderBy: gitlab.String(opts.OrderBy),
|
||||
OrderBy: gitlab.Ptr(opts.OrderBy),
|
||||
}
|
||||
|
||||
// Other filters only valid if FilterAll not true
|
||||
if !opts.FilterAll {
|
||||
if !opts.FilterStarred && !opts.FilterMember {
|
||||
// if no other filters are passed, default to Owned filter
|
||||
l.Owned = gitlab.Bool(true)
|
||||
l.Owned = gitlab.Ptr(true)
|
||||
}
|
||||
|
||||
if opts.FilterOwned {
|
||||
l.Owned = gitlab.Bool(opts.FilterOwned)
|
||||
l.Owned = gitlab.Ptr(opts.FilterOwned)
|
||||
}
|
||||
|
||||
if opts.FilterStarred {
|
||||
l.Starred = gitlab.Bool(opts.FilterStarred)
|
||||
l.Starred = gitlab.Ptr(opts.FilterStarred)
|
||||
}
|
||||
}
|
||||
|
||||
if opts.Sort != "" {
|
||||
l.Sort = gitlab.String(opts.Sort)
|
||||
l.Sort = gitlab.Ptr(opts.Sort)
|
||||
}
|
||||
|
||||
l.PerPage = opts.PerPage
|
||||
|
|
|
@ -217,7 +217,6 @@ func printProjectContentTTY(opts *ViewOptions, project *gitlab.Project, readme *
|
|||
fullName := project.NameWithNamespace
|
||||
if project.Description != "" {
|
||||
description, err = utils.RenderMarkdownWithoutIndentations(project.Description, opts.GlamourStyle)
|
||||
|
||||
if err != nil {
|
||||
description = project.Description
|
||||
}
|
||||
|
@ -227,7 +226,6 @@ func printProjectContentTTY(opts *ViewOptions, project *gitlab.Project, readme *
|
|||
|
||||
if readme != nil {
|
||||
readmeContent, err = utils.RenderMarkdown(readme.Content, opts.GlamourStyle)
|
||||
|
||||
if err != nil {
|
||||
readmeContent = readme.Content
|
||||
}
|
||||
|
|
|
@ -338,7 +338,6 @@ func createRun(opts *CreateOpts) error {
|
|||
}
|
||||
|
||||
release, _, err = client.Releases.CreateRelease(repo.FullName(), createOpts)
|
||||
|
||||
if err != nil {
|
||||
return releaseFailedErr(err, start)
|
||||
}
|
||||
|
|
|
@ -81,7 +81,6 @@ func (c *Context) UploadFiles(projectID, tagName string) error {
|
|||
FilePath: &filename,
|
||||
LinkType: file.Type,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -98,9 +98,9 @@ func runCreate(client *gitlab.Client, repo glrepo.Interface, opts *CreateOpts) e
|
|||
snippet, err := api.CreateProjectSnippet(client, repo.FullName(), &gitlab.CreateProjectSnippetOptions{
|
||||
Title: &opts.Title,
|
||||
Description: &opts.Description,
|
||||
Content: gitlab.String(string(content)),
|
||||
Content: gitlab.Ptr(string(content)),
|
||||
FileName: &opts.DisplayFilename,
|
||||
Visibility: gitlab.Visibility(gitlab.VisibilityValue(opts.Visibility)),
|
||||
Visibility: gitlab.Ptr(gitlab.VisibilityValue(opts.Visibility)),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create snippet. %w", err)
|
||||
|
|
|
@ -107,13 +107,13 @@ func setRun(opts *SetOpts) error {
|
|||
if opts.Group != "" {
|
||||
// creating group-level variable
|
||||
createVarOpts := &gitlab.CreateGroupVariableOptions{
|
||||
Key: gitlab.String(opts.Key),
|
||||
Value: gitlab.String(opts.Value),
|
||||
EnvironmentScope: gitlab.String(opts.Scope),
|
||||
Masked: gitlab.Bool(opts.Masked),
|
||||
Protected: gitlab.Bool(opts.Protected),
|
||||
VariableType: gitlab.VariableType(gitlab.VariableTypeValue(opts.Type)),
|
||||
Raw: gitlab.Bool(opts.Raw),
|
||||
Key: gitlab.Ptr(opts.Key),
|
||||
Value: gitlab.Ptr(opts.Value),
|
||||
EnvironmentScope: gitlab.Ptr(opts.Scope),
|
||||
Masked: gitlab.Ptr(opts.Masked),
|
||||
Protected: gitlab.Ptr(opts.Protected),
|
||||
VariableType: gitlab.Ptr(gitlab.VariableTypeValue(opts.Type)),
|
||||
Raw: gitlab.Ptr(opts.Raw),
|
||||
}
|
||||
_, err = api.CreateGroupVariable(httpClient, opts.Group, createVarOpts)
|
||||
if err != nil {
|
||||
|
@ -130,13 +130,13 @@ func setRun(opts *SetOpts) error {
|
|||
return err
|
||||
}
|
||||
createVarOpts := &gitlab.CreateProjectVariableOptions{
|
||||
Key: gitlab.String(opts.Key),
|
||||
Value: gitlab.String(opts.Value),
|
||||
EnvironmentScope: gitlab.String(opts.Scope),
|
||||
Masked: gitlab.Bool(opts.Masked),
|
||||
Protected: gitlab.Bool(opts.Protected),
|
||||
VariableType: gitlab.VariableType(gitlab.VariableTypeValue(opts.Type)),
|
||||
Raw: gitlab.Bool(opts.Raw),
|
||||
Key: gitlab.Ptr(opts.Key),
|
||||
Value: gitlab.Ptr(opts.Value),
|
||||
EnvironmentScope: gitlab.Ptr(opts.Scope),
|
||||
Masked: gitlab.Ptr(opts.Masked),
|
||||
Protected: gitlab.Ptr(opts.Protected),
|
||||
VariableType: gitlab.Ptr(gitlab.VariableTypeValue(opts.Type)),
|
||||
Raw: gitlab.Ptr(opts.Raw),
|
||||
}
|
||||
_, err = api.CreateProjectVariable(httpClient, baseRepo.FullName(), createVarOpts)
|
||||
if err != nil {
|
||||
|
|
|
@ -111,12 +111,12 @@ func updateRun(opts *UpdateOpts) error {
|
|||
if opts.Group != "" {
|
||||
// update group-level variable
|
||||
updateGroupVarOpts := &gitlab.UpdateGroupVariableOptions{
|
||||
Value: gitlab.String(opts.Value),
|
||||
VariableType: gitlab.VariableType(gitlab.VariableTypeValue(opts.Type)),
|
||||
Masked: gitlab.Bool(opts.Masked),
|
||||
Protected: gitlab.Bool(opts.Protected),
|
||||
Raw: gitlab.Bool(opts.Raw),
|
||||
EnvironmentScope: gitlab.String(opts.Scope),
|
||||
Value: gitlab.Ptr(opts.Value),
|
||||
VariableType: gitlab.Ptr(gitlab.VariableTypeValue(opts.Type)),
|
||||
Masked: gitlab.Ptr(opts.Masked),
|
||||
Protected: gitlab.Ptr(opts.Protected),
|
||||
Raw: gitlab.Ptr(opts.Raw),
|
||||
EnvironmentScope: gitlab.Ptr(opts.Scope),
|
||||
}
|
||||
|
||||
_, err = api.UpdateGroupVariable(httpClient, opts.Group, opts.Key, updateGroupVarOpts)
|
||||
|
@ -135,12 +135,12 @@ func updateRun(opts *UpdateOpts) error {
|
|||
}
|
||||
|
||||
updateProjectVarOpts := &gitlab.UpdateProjectVariableOptions{
|
||||
Value: gitlab.String(opts.Value),
|
||||
VariableType: gitlab.VariableType(gitlab.VariableTypeValue(opts.Type)),
|
||||
Masked: gitlab.Bool(opts.Masked),
|
||||
Protected: gitlab.Bool(opts.Protected),
|
||||
Raw: gitlab.Bool(opts.Raw),
|
||||
EnvironmentScope: gitlab.String(opts.Scope),
|
||||
Value: gitlab.Ptr(opts.Value),
|
||||
VariableType: gitlab.Ptr(gitlab.VariableTypeValue(opts.Type)),
|
||||
Masked: gitlab.Ptr(opts.Masked),
|
||||
Protected: gitlab.Ptr(opts.Protected),
|
||||
Raw: gitlab.Ptr(opts.Raw),
|
||||
EnvironmentScope: gitlab.Ptr(opts.Scope),
|
||||
}
|
||||
|
||||
_, err = api.UpdateProjectVariable(httpClient, baseRepo.FullName(), opts.Key, updateProjectVarOpts)
|
||||
|
|
|
@ -43,6 +43,7 @@ pipeline
|
|||
- [`list`](list.md)
|
||||
- [`retry`](retry.md)
|
||||
- [`run`](run.md)
|
||||
- [`run-trig`](run-trig.md)
|
||||
- [`status`](status.md)
|
||||
- [`trace`](trace.md)
|
||||
- [`trigger`](trigger.md)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
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 ci run-trig`
|
||||
|
||||
Run a CI/CD pipeline trigger
|
||||
|
||||
```plaintext
|
||||
glab ci run-trig [flags]
|
||||
```
|
||||
|
||||
## Aliases
|
||||
|
||||
```plaintext
|
||||
run-trig
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```plaintext
|
||||
glab ci run-trig -t xxxx
|
||||
glab ci run-trig -t xxxx -b main
|
||||
glab ci run-trig -t xxxx -b main --variables key1:val1
|
||||
glab ci run-trig -t xxxx -b main --variables key1:val1,key2:val2
|
||||
glab ci run-trig -t xxxx -b main --variables key1:val1 --variables key2:val2
|
||||
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
```plaintext
|
||||
-b, --branch string Create pipeline on branch/ref <string>
|
||||
-t, --token string Pipeline trigger token (can be omitted only if CI_JOB_TOKEN environment variable is set)
|
||||
--variables strings Pass variables to pipeline in format <key>:<value>
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
|
@ -19,13 +19,13 @@ Get and set key/value strings.
|
|||
|
||||
Current respected settings:
|
||||
|
||||
- token: Your GitLab access token, defaults to environment variables
|
||||
- token: your GitLab access token, defaults to environment variables
|
||||
- host: if unset, defaults to `https://gitlab.com`
|
||||
- browser: if unset, defaults to environment variables
|
||||
- editor: if unset, defaults to environment variables
|
||||
- visual: alternative for editor. If unset, defaults to environment variables
|
||||
- glamour_style: Your desired Markdown renderer style. Options are dark, light, notty. Custom styles are allowed using [glamour](https://github.com/charmbracelet/glamour#styles)
|
||||
- glab_pager: Your desired pager command to use (e.g. less -R)
|
||||
- browser: if unset, default browser is used. Override with environment variable $BROWSER
|
||||
- editor: if unset, default editor is used. Override with environment variable $EDITOR
|
||||
- visual: takes precedence over editor. If unset, default editor is used. Override with environment variable $VISUAL
|
||||
- glamour_style: your desired Markdown renderer style. Options are dark, light, notty. Custom styles are allowed using [glamour](https://github.com/charmbracelet/glamour#styles)
|
||||
- glab_pager: your desired pager command to use (e.g. less -R)
|
||||
- check_update: if true, notifies of any available updates to glab. Defaults to true
|
||||
- display_hyperlinks: if true, and using a TTY, outputs hyperlinks for issues and MR lists. Defaults to false
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ glab incident list --milestone release-2.0.0 --opened
|
|||
--not-assignee strings Filter incident by not being assigneed to <username>
|
||||
--not-author strings Filter by not being by author(s) <username>
|
||||
--not-label strings Filter incident by lack of label <name>
|
||||
-F, --output string One of 'details', 'ids', 'urls' or 'json' (default "details")
|
||||
-O, --output string One of 'text' or 'json' (default "text")
|
||||
-F, --output-format string One of 'details', 'ids', 'urls' (default "details")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page. (default 30)
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
|
|
|
@ -49,7 +49,8 @@ glab issue list --milestone release-2.0.0 --opened
|
|||
--not-assignee strings Filter issue by not being assigneed to <username>
|
||||
--not-author strings Filter by not being by author(s) <username>
|
||||
--not-label strings Filter issue by lack of label <name>
|
||||
-F, --output string One of 'details', 'ids', 'urls' or 'json' (default "details")
|
||||
-O, --output string One of 'text' or 'json' (default "text")
|
||||
-F, --output-format string One of 'details', 'ids', 'urls' (default "details")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page. (default 30)
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
|
|
20
go.mod
20
go.mod
|
@ -15,7 +15,7 @@ require (
|
|||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/gosuri/uilive v0.0.4
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2
|
||||
github.com/hashicorp/go-retryablehttp v0.7.5
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/lunixbochs/vtclean v1.0.0
|
||||
|
@ -34,11 +34,11 @@ require (
|
|||
github.com/spf13/viper v1.16.0
|
||||
github.com/stretchr/testify v1.8.3
|
||||
github.com/tidwall/pretty v1.2.1
|
||||
github.com/xanzy/go-gitlab v0.93.0
|
||||
github.com/xanzy/go-gitlab v0.103.0
|
||||
github.com/zalando/go-keyring v0.2.3
|
||||
golang.org/x/sync v0.2.0
|
||||
golang.org/x/term v0.13.0
|
||||
golang.org/x/text v0.13.0
|
||||
golang.org/x/term v0.18.0
|
||||
golang.org/x/text v0.14.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apimachinery v0.27.2
|
||||
k8s.io/client-go v0.27.2
|
||||
|
@ -59,7 +59,7 @@ require (
|
|||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
|
@ -86,12 +86,10 @@ require (
|
|||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/yuin/goldmark v1.5.4 // indirect
|
||||
github.com/yuin/goldmark-emoji v1.0.1 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.8.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
golang.org/x/net v0.23.0 // indirect
|
||||
golang.org/x/oauth2 v0.19.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
|
45
go.sum
45
go.sum
|
@ -142,9 +142,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
|||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
|
||||
|
@ -158,7 +157,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
|
@ -204,8 +202,8 @@ github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXc
|
|||
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
|
@ -335,8 +333,8 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8
|
|||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/xanzy/go-gitlab v0.93.0 h1:/Fy4akqKIQasZgQ2xj2xJBrEZ+iCW+iC+9qLEt19tgo=
|
||||
github.com/xanzy/go-gitlab v0.93.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
|
||||
github.com/xanzy/go-gitlab v0.103.0 h1:J9pTQoq0GsEFqzd6srCM1QfdfKAxSNz6mT6ntrpNF2w=
|
||||
github.com/xanzy/go-gitlab v0.103.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
@ -431,8 +429,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -442,8 +440,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
|
||||
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
|
||||
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
||||
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -501,14 +499,14 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -518,13 +516,13 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
|
@ -604,7 +602,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
|||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
|
@ -668,10 +665,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
@ -51,7 +51,6 @@ func (a *AliasConfig) Write() error {
|
|||
return err
|
||||
}
|
||||
err = WriteConfigFile(aliasesConfigFile(), yamlNormalize(aliasesBytes))
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write config: %w", err)
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ func (a *LocalConfig) Write() error {
|
|||
return err
|
||||
}
|
||||
err = WriteConfigFile(LocalConfigFile(), yamlNormalize(localConfigBytes))
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write config: %w", err)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package utils
|
|||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -22,6 +23,15 @@ func OpenInBrowser(url, browserType string) error {
|
|||
return run.PrepareCmd(browseCmd).Run()
|
||||
}
|
||||
|
||||
func SanitizePathName(path string) string {
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
// Prefix the path with "/" ensures that filepath.Clean removes all `/..`
|
||||
// See rule 4 of filepath.Clean for more information: https://pkg.go.dev/path/filepath#Clean
|
||||
path = "/" + path
|
||||
}
|
||||
return filepath.Clean(path)
|
||||
}
|
||||
|
||||
func RenderMarkdown(text, glamourStyle string) (string, error) {
|
||||
opts := MarkdownRenderOpts{
|
||||
glamour.WithStylePath(getStyle(glamourStyle)),
|
||||
|
|
|
@ -110,6 +110,44 @@ func Test_PresentInIntSlice(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_SanitizePathName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filename string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "A regular filename",
|
||||
filename: "cli-v1.22.0.json",
|
||||
want: "/cli-v1.22.0.json",
|
||||
},
|
||||
{
|
||||
name: "A regular filename in a directory",
|
||||
filename: "cli/cli-v1.22.0.json",
|
||||
want: "/cli/cli-v1.22.0.json",
|
||||
},
|
||||
{
|
||||
name: "A filename with directory traversal",
|
||||
filename: "cli-v1.../../22.0.zip",
|
||||
want: "/22.0.zip",
|
||||
},
|
||||
{
|
||||
name: "A particularly nasty filename",
|
||||
filename: "..././..././..././etc/password_file",
|
||||
want: "/.../.../.../etc/password_file",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
filePathWanted := SanitizePathName(tt.filename)
|
||||
|
||||
if filePathWanted != tt.want {
|
||||
t.Errorf("SanitizePathName() got = %s, want = %s", filePathWanted, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_CommonElementsInStringSlice(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
|
Loading…
Reference in New Issue