Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add -E flag to exit with the pr sate on unix shell #2298

Merged
merged 1 commit into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/cmd/tkn_pipeline_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ my-csi-template and my-volume-claim-template)

```
--dry-run preview PipelineRun without running it
-E, --exit-with-pipelinerun-error when using --showlog, exit with pipelinerun to the unix shell, 0 if success, 1 if error, 2 on unknown status
-f, --filename string local or remote file name containing a Pipeline definition to start a PipelineRun
--finally-timeout string timeout for Finally TaskRuns
-h, --help help for start
Expand Down
19 changes: 10 additions & 9 deletions docs/cmd/tkn_pipelinerun_logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ Show the logs of PipelineRun named 'microservice-1' for all Tasks and steps (inc
### Options

```
-a, --all show all logs including init steps injected by tekton
-f, --follow stream live logs
-F, --fzf use fzf to select a PipelineRun
-h, --help help for logs
-L, --last show logs for last PipelineRun
--limit int lists number of PipelineRuns (default 5)
--prefix prefix each log line with the log source (task name and step name) (default true)
-t, --task strings show logs for mentioned Tasks only
--timestamps show logs with timestamp
-a, --all show all logs including init steps injected by tekton
-E, --exit-with-pipelinerun-error exit with pipelinerun to the unix shell, 0 if success, 1 if error, 2 on unknown status
-f, --follow stream live logs
-F, --fzf use fzf to select a PipelineRun
-h, --help help for logs
-L, --last show logs for last PipelineRun
--limit int lists number of PipelineRuns (default 5)
--prefix prefix each log line with the log source (task name and step name) (default true)
-t, --task strings show logs for mentioned Tasks only
--timestamps show logs with timestamp
```

### Options inherited from parent commands
Expand Down
4 changes: 4 additions & 0 deletions docs/man/man1/tkn-pipeline-start.1
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Parameters, at least those that have no default value
\fB\-\-dry\-run\fP[=false]
preview PipelineRun without running it

.PP
\fB\-E\fP, \fB\-\-exit\-with\-pipelinerun\-error\fP[=false]
when using \-\-showlog, exit with pipelinerun to the unix shell, 0 if success, 1 if error, 2 on unknown status

.PP
\fB\-f\fP, \fB\-\-filename\fP=""
local or remote file name containing a Pipeline definition to start a PipelineRun
Expand Down
4 changes: 4 additions & 0 deletions docs/man/man1/tkn-pipelinerun-logs.1
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Show the logs of a PipelineRun
\fB\-a\fP, \fB\-\-all\fP[=false]
show all logs including init steps injected by tekton

.PP
\fB\-E\fP, \fB\-\-exit\-with\-pipelinerun\-error\fP[=false]
exit with pipelinerun to the unix shell, 0 if success, 1 if error, 2 on unknown status

.PP
\fB\-f\fP, \fB\-\-follow\fP[=false]
stream live logs
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/pipeline/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type startOptions struct {
Labels []string
ShowLog bool
DryRun bool
ExitWithPrError bool
Output string
PrefixName string
TimeOut string
Expand Down Expand Up @@ -195,6 +196,7 @@ For passing the workspaces via flags:
c.Flags().BoolVarP(&opt.UseParamDefaults, "use-param-defaults", "", false, "use default parameter values without prompting for input")
c.Flags().StringVar(&opt.PodTemplate, "pod-template", "", "local or remote file containing a PodTemplate definition")
c.Flags().BoolVarP(&opt.SkipOptionalWorkspace, "skip-optional-workspace", "", false, "skips the prompt for optional workspaces")
c.Flags().BoolVarP(&opt.ExitWithPrError, "exit-with-pipelinerun-error", "E", false, "when using --showlog, exit with pipelinerun to the unix shell, 0 if success, 1 if error, 2 on unknown status")

c.Flags().StringVarP(&opt.ServiceAccountName, "serviceaccount", "s", "", "pass the serviceaccount name")
_ = c.RegisterFlagCompletionFunc("serviceaccount",
Expand Down Expand Up @@ -413,6 +415,7 @@ func (opt *startOptions) startPipeline(pipelineStart *v1beta1.Pipeline) error {
Prefixing: true,
Params: opt.cliparams,
AllSteps: false,
ExitWithPrError: opt.ExitWithPrError,
}
return prcmd.Run(runLogOpts)
}
Expand Down
26 changes: 26 additions & 0 deletions pkg/cmd/pipelinerun/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"github.com/tektoncd/cli/pkg/log"
"github.com/tektoncd/cli/pkg/options"
pipelinerunpkg "github.com/tektoncd/cli/pkg/pipelinerun"
tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -82,6 +84,7 @@ Show the logs of PipelineRun named 'microservice-1' for all Tasks and steps (inc
c.Flags().BoolVarP(&opts.Follow, "follow", "f", false, "stream live logs")
c.Flags().BoolVarP(&opts.Timestamps, "timestamps", "", false, "show logs with timestamp")
c.Flags().BoolVarP(&opts.Prefixing, "prefix", "", true, "prefix each log line with the log source (task name and step name)")
c.Flags().BoolVarP(&opts.ExitWithPrError, "exit-with-pipelinerun-error", "E", false, "exit with pipelinerun to the unix shell, 0 if success, 1 if error, 2 on unknown status")
c.Flags().StringSliceVarP(&opts.Tasks, "task", "t", []string{}, "show logs for mentioned Tasks only")
c.Flags().IntVarP(&opts.Limit, "limit", "", defaultLimit, "lists number of PipelineRuns")
return c
Expand Down Expand Up @@ -109,9 +112,32 @@ func Run(opts *options.LogOptions) error {

log.NewWriter(log.LogTypePipeline, opts.Prefixing).Write(opts.Stream, logC, errC)

// get pipelinerun status
if opts.ExitWithPrError {
clients, err := opts.Params.Clients()
if err != nil {
return err
}
pr, err := pipelinerunpkg.GetPipelineRun(pipelineRunGroupResource, clients, opts.PipelineRunName, opts.Params.Namespace())
if err != nil {
return err
}
os.Exit(prStatusToUnixStatus(pr))
}

return nil
}

func prStatusToUnixStatus(pr *tektonv1.PipelineRun) int {
if len(pr.Status.Conditions) == 0 {
return 2
}
if pr.Status.Conditions[0].Status == corev1.ConditionFalse {
return 1
}
return 0
}

func askRunName(opts *options.LogOptions) error {
lOpts := metav1.ListOptions{}

Expand Down
65 changes: 59 additions & 6 deletions pkg/cmd/pipelinerun/logs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,65 @@ func TestLog_no_pipelinerun_argument(t *testing.T) {
}
}

func TestLog_PrStatusToUnixStatus(t *testing.T) {
testCases := []struct {
name string
pr *v1.PipelineRun
expected int
}{
{
name: "No conditions",
pr: &v1.PipelineRun{
Status: v1.PipelineRunStatus{
Status: duckv1.Status{
Conditions: duckv1.Conditions{},
},
},
},
expected: 2,
},
{
name: "Condition status is false",
pr: &v1.PipelineRun{
Status: v1.PipelineRunStatus{
Status: duckv1.Status{
Conditions: duckv1.Conditions{
{
Status: corev1.ConditionFalse,
},
},
},
},
},
expected: 1,
},
{
name: "Condition status true",
pr: &v1.PipelineRun{
Status: v1.PipelineRunStatus{
Status: duckv1.Status{
Conditions: duckv1.Conditions{
{
Status: corev1.ConditionTrue,
},
},
},
},
},
expected: 0,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := prStatusToUnixStatus(tc.pr)
if result != tc.expected {
t.Errorf("Expected %d, got %d", tc.expected, result)
}
})
}
}

func TestLog_run_found_v1beta1(t *testing.T) {
clock := test.FakeClock()
pdata := []*v1beta1.Pipeline{
Expand Down Expand Up @@ -1673,7 +1732,6 @@ func TestPipelinerunLog_follow_mode_v1beta1(t *testing.T) {
cb.UnstructuredV1beta1PR(prs[0], versionv1beta1),
cb.UnstructuredV1beta1P(pps[0], versionv1beta1),
)

if err != nil {
t.Errorf("unable to create dynamic client: %v", err)
}
Expand Down Expand Up @@ -1862,7 +1920,6 @@ func TestPipelinerunLog_follow_mode(t *testing.T) {
cb.UnstructuredPR(prs[0], version),
cb.UnstructuredP(pps[0], version),
)

if err != nil {
t.Errorf("unable to create dynamic client: %v", err)
}
Expand Down Expand Up @@ -2517,7 +2574,6 @@ func TestLog_pipelinerun_still_running_v1beta1(t *testing.T) {
updatePRv1beta1(finalPRs, watcher)

output, err := fetchLogs(prlo)

if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand Down Expand Up @@ -2648,7 +2704,6 @@ func TestLog_pipelinerun_still_running(t *testing.T) {
updatePR(finalPRs, watcher)

output, err := fetchLogs(prlo)

if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand Down Expand Up @@ -3502,7 +3557,6 @@ func TestPipelinerunLog_finally_v1beta1(t *testing.T) {
cb.UnstructuredV1beta1PR(prs[0], versionv1beta1),
cb.UnstructuredV1beta1P(pps[0], versionv1beta1),
)

if err != nil {
t.Errorf("unable to create dynamic client: %v", err)
}
Expand Down Expand Up @@ -3752,7 +3806,6 @@ func TestPipelinerunLog_finally(t *testing.T) {
cb.UnstructuredPR(prs[0], version),
cb.UnstructuredP(pps[0], version),
)

if err != nil {
t.Errorf("unable to create dynamic client: %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/options/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type LogOptions struct {
Tail int64
Timestamps bool
Prefixing bool
ExitWithPrError bool
// ActivityTimeout is the amount of time to wait for some activity
// (e.g. Pod ready) before giving up.
ActivityTimeout time.Duration
Expand Down