mirror of https://gitlab.com/gitlab-org/cli.git
fix(ci): Fix issue where `ci get` fails if user is not maintainer
This commit is contained in:
parent
b7e9261562
commit
1dbeae7bb6
|
@ -172,17 +172,11 @@ var GetPipeline = func(client *gitlab.Client, pid int, l *gitlab.RequestOptionFu
|
|||
return pipe, nil
|
||||
}
|
||||
|
||||
var GetPipelineVariables = func(client *gitlab.Client, pid int, l *gitlab.RequestOptionFunc, repo interface{}) ([]*gitlab.PipelineVariable, error) {
|
||||
var GetPipelineVariables = func(client *gitlab.Client, pid int, l *gitlab.RequestOptionFunc, projectID int) ([]*gitlab.PipelineVariable, error) {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
}
|
||||
|
||||
pipe, _, err := client.Pipelines.GetPipeline(repo, pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
projectID := pipe.ProjectID
|
||||
|
||||
pipelineVars, _, err := client.Pipelines.GetPipelineVariables(projectID, pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -3,6 +3,7 @@ package status
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
|
@ -15,6 +16,8 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const NoVariablesInPipelineMessage = "No variables found in pipeline."
|
||||
|
||||
type PipelineMergedResponse struct {
|
||||
*gitlab.Pipeline
|
||||
Jobs []*gitlab.Job `json:"jobs"`
|
||||
|
@ -68,9 +71,14 @@ func NewCmdGet(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
variables, err := api.GetPipelineVariables(apiClient, pipelineId, nil, repo.FullName())
|
||||
if err != nil {
|
||||
return err
|
||||
showVariables, _ := cmd.Flags().GetBool("with-variables")
|
||||
|
||||
var variables []*gitlab.PipelineVariable
|
||||
if showVariables {
|
||||
variables, err = api.GetPipelineVariables(apiClient, pipelineId, nil, pipeline.ProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
mergedPipelineObject := &PipelineMergedResponse{
|
||||
|
@ -83,7 +91,7 @@ func NewCmdGet(f *cmdutils.Factory) *cobra.Command {
|
|||
if outputFormat == "json" {
|
||||
printJSON(*mergedPipelineObject)
|
||||
} else {
|
||||
printTable(*mergedPipelineObject)
|
||||
printTable(*mergedPipelineObject, f.IO.StdOut)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -93,6 +101,7 @@ func NewCmdGet(f *cmdutils.Factory) *cobra.Command {
|
|||
pipelineGetCmd.Flags().StringP("branch", "b", "", "Check pipeline status for a branch. (Default is current branch)")
|
||||
pipelineGetCmd.Flags().IntP("pipeline-id", "p", 0, "Provide pipeline ID")
|
||||
pipelineGetCmd.Flags().StringP("output-format", "o", "text", "Format output as: text, json")
|
||||
pipelineGetCmd.Flags().Bool("with-variables", false, "Show variables in pipeline (maintainer role required)")
|
||||
|
||||
return pipelineGetCmd
|
||||
}
|
||||
|
@ -102,8 +111,8 @@ func printJSON(p PipelineMergedResponse) {
|
|||
fmt.Println(string(JSONStr))
|
||||
}
|
||||
|
||||
func printTable(p PipelineMergedResponse) {
|
||||
fmt.Print("# Pipeline:\n")
|
||||
func printTable(p PipelineMergedResponse, dest io.Writer) {
|
||||
fmt.Fprint(dest, "# Pipeline:\n")
|
||||
pipelineTable := tableprinter.NewTablePrinter()
|
||||
pipelineTable.AddRow("id:", strconv.Itoa(p.ID))
|
||||
pipelineTable.AddRow("status:", p.Status)
|
||||
|
@ -116,20 +125,26 @@ func printTable(p PipelineMergedResponse) {
|
|||
pipelineTable.AddRow("created:", p.CreatedAt)
|
||||
pipelineTable.AddRow("started:", p.StartedAt)
|
||||
pipelineTable.AddRow("updated:", p.UpdatedAt)
|
||||
fmt.Println(pipelineTable.String())
|
||||
fmt.Fprintln(dest, pipelineTable.String())
|
||||
|
||||
fmt.Print("# Jobs:\n")
|
||||
fmt.Fprint(dest, "# Jobs:\n")
|
||||
jobTable := tableprinter.NewTablePrinter()
|
||||
for _, j := range p.Jobs {
|
||||
j := j
|
||||
jobTable.AddRow(j.Name+":", j.Status)
|
||||
}
|
||||
fmt.Println(jobTable.String())
|
||||
fmt.Fprintln(dest, jobTable.String())
|
||||
|
||||
fmt.Print("# Variables:\n")
|
||||
varTable := tableprinter.NewTablePrinter()
|
||||
for _, v := range p.Variables {
|
||||
varTable.AddRow(v.Key+":", v.Value)
|
||||
if p.Variables != nil {
|
||||
fmt.Fprint(dest, "# Variables:\n")
|
||||
if len(p.Variables) == 0 {
|
||||
fmt.Fprint(dest, NoVariablesInPipelineMessage)
|
||||
}
|
||||
|
||||
varTable := tableprinter.NewTablePrinter()
|
||||
for _, v := range p.Variables {
|
||||
varTable.AddRow(v.Key+":", v.Value)
|
||||
}
|
||||
fmt.Fprintln(dest, varTable.String())
|
||||
}
|
||||
fmt.Println(varTable.String())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package status
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper, isTTY bool, args string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
cmd := NewCmdGet(factory)
|
||||
|
||||
return cmdtest.ExecuteCommand(cmd, args, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestCIGet(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args string
|
||||
httpMocks []httpMock
|
||||
expectedOut string
|
||||
}{
|
||||
{
|
||||
name: "when get is called on an existing pipeline",
|
||||
args: "-p=123 -b=main",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"status": "pending",
|
||||
"source": "push",
|
||||
"user": {
|
||||
"username": "test"
|
||||
},
|
||||
"created_at": "2023-10-10T00:00:00Z",
|
||||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/123/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
`[]`,
|
||||
},
|
||||
},
|
||||
expectedOut: "# Pipeline:\nid:\t123\nstatus:\tpending\nsource:\tpush\nref:\t\nsha:\t\ntag:\tfalse\nyaml Errors:\t\nuser:\ttest\ncreated:\t2023-10-10 00:00:00 +0000 UTC\nstarted:\t2023-10-10 00:00:00 +0000 UTC\nupdated:\t2023-10-10 00:00:00 +0000 UTC\n\n# Jobs:\n\n",
|
||||
},
|
||||
{
|
||||
name: "when get is called on an existing pipeline with variables",
|
||||
args: "-p=456 -b=main --with-variables",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/456",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 456,
|
||||
"iid": 456,
|
||||
"project_id": 5,
|
||||
"status": "pending",
|
||||
"source": "push",
|
||||
"user": {
|
||||
"username": "test"
|
||||
},
|
||||
"created_at": "2023-10-10T00:00:00Z",
|
||||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/456/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
`[]`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/5/pipelines/456/variables",
|
||||
http.StatusOK,
|
||||
`[{
|
||||
"key": "RUN_NIGHTLY_BUILD",
|
||||
"variable_type": "env_var",
|
||||
"value": "true"
|
||||
}]`,
|
||||
},
|
||||
},
|
||||
expectedOut: "# Pipeline:\nid:\t456\nstatus:\tpending\nsource:\tpush\nref:\t\nsha:\t\ntag:\tfalse\nyaml Errors:\t\nuser:\ttest\ncreated:\t2023-10-10 00:00:00 +0000 UTC\nstarted:\t2023-10-10 00:00:00 +0000 UTC\nupdated:\t2023-10-10 00:00:00 +0000 UTC\n\n# Jobs:\n\n# Variables:\nRUN_NIGHTLY_BUILD:\ttrue\n\n",
|
||||
},
|
||||
{
|
||||
name: "when get is called on an existing pipeline with variables however no variables are found",
|
||||
args: "-p=456 -b=main --with-variables",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/456",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 456,
|
||||
"iid": 456,
|
||||
"project_id": 5,
|
||||
"status": "pending",
|
||||
"source": "push",
|
||||
"user": {
|
||||
"username": "test"
|
||||
},
|
||||
"created_at": "2023-10-10T00:00:00Z",
|
||||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/456/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
`[]`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/5/pipelines/456/variables",
|
||||
http.StatusOK,
|
||||
"[]",
|
||||
},
|
||||
},
|
||||
expectedOut: "# Pipeline:\nid:\t456\nstatus:\tpending\nsource:\tpush\nref:\t\nsha:\t\ntag:\tfalse\nyaml Errors:\t\nuser:\ttest\ncreated:\t2023-10-10 00:00:00 +0000 UTC\nstarted:\t2023-10-10 00:00:00 +0000 UTC\nupdated:\t2023-10-10 00:00:00 +0000 UTC\n\n# Jobs:\n\n# Variables:\nNo variables found in pipeline.\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeHTTP := &httpmock.Mocker{
|
||||
MatchURL: httpmock.PathAndQuerystring,
|
||||
}
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
}
|
||||
|
||||
output, err := runCommand(fakeHTTP, false, tc.args)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Equal(t, tc.expectedOut, output.String())
|
||||
assert.Empty(t, output.Stderr())
|
||||
})
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ glab ci -R some/project -p 12345
|
|||
-b, --branch string Check pipeline status for a branch. (Default is current branch)
|
||||
-o, --output-format string Format output as: text, json (default "text")
|
||||
-p, --pipeline-id int Provide pipeline ID
|
||||
--with-variables Show variables in pipeline (maintainer role required)
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
Loading…
Reference in New Issue