Skip to content
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
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,5 @@ Code reviews are required for all submissions via GitHub pull requests.
- if you add any new dependency to a constructor, remember to run wire ./...
- when creating PR message, keep it high-level, what functionality was added, don't add info about testing, no icons, no info about how the message was generated.
- app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts is a special case that we don't want to upgrade, so if it upgrades, put it back to main
- when creating a commit or PR message, NEVER add co-authored by or generated by Claude code
- when creating a commit or PR message, NEVER add co-authored by or generated by Claude code
- if you modify a schema, remember to run `make migration_sync`
1 change: 1 addition & 0 deletions app/cli/cmd/workflow_workflow_run_describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func workflowRunDescribeTableOutput(run *action.WorkflowRunItemFull) error {
if wr.Reason != "" {
gt.AppendRow(table.Row{"Failure Reason", wr.Reason})
}
gt.AppendRow(table.Row{"Policy Status", wr.PolicyStatus})
gt.AppendRow(table.Row{"Runner Link", wr.RunURL})

if run.WorkflowRun.FinishedAt == nil {
Expand Down
16 changes: 11 additions & 5 deletions app/cli/cmd/workflow_workflow_run_list.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024 The Chainloop Authors.
// Copyright 2024-2025 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -33,7 +33,7 @@ func newWorkflowWorkflowRunListCmd() *cobra.Command {
DefaultLimit: 50,
}

var workflowName, projectName, status string
var workflowName, projectName, status, policyStatus string

cmd := &cobra.Command{
Use: "list",
Expand All @@ -44,6 +44,10 @@ func newWorkflowWorkflowRunListCmd() *cobra.Command {
return fmt.Errorf("invalid status %q, please chose one of: %v", status, listAvailableWorkflowStatusFlag())
}

if policyStatus != "" && !slices.Contains([]string{"all", "failed", "passed"}, policyStatus) {
return fmt.Errorf("invalid policy-status %q, please chose one of: all, failed, passed", policyStatus)
}

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
Expand All @@ -55,7 +59,8 @@ func newWorkflowWorkflowRunListCmd() *cobra.Command {
Limit: paginationOpts.Limit,
NextCursor: paginationOpts.NextCursor,
},
Status: status,
Status: status,
PolicyStatus: policyStatus,
},
)
if err != nil {
Expand Down Expand Up @@ -85,6 +90,7 @@ func newWorkflowWorkflowRunListCmd() *cobra.Command {
cmd.Flags().StringVar(&projectName, "project", "", "project name")
cmd.Flags().BoolVar(&full, "full", false, "full report")
cmd.Flags().StringVar(&status, "status", "", fmt.Sprintf("filter by workflow run status: %v", listAvailableWorkflowStatusFlag()))
cmd.Flags().StringVar(&policyStatus, "policy-status", "", "filter by policy violations status: all, failed, passed")
// Add pagination flags
paginationOpts.AddFlags(cmd)

Expand All @@ -97,7 +103,7 @@ func workflowRunListTableOutput(runs []*action.WorkflowRunItem) error {
return nil
}

header := table.Row{"ID", "Workflow", "Version", "State", "Created At", "Runner"}
header := table.Row{"ID", "Workflow", "Version", "State", "Policy Status", "Created At", "Runner"}
if full {
header = append(header, "Finished At", "Failure reason")
}
Expand All @@ -107,7 +113,7 @@ func workflowRunListTableOutput(runs []*action.WorkflowRunItem) error {

for _, p := range runs {
wf := p.Workflow
r := table.Row{p.ID, wf.NamespacedName(), versionString(p.ProjectVersion), p.State, p.CreatedAt.Format(time.RFC822), p.RunnerType}
r := table.Row{p.ID, wf.NamespacedName(), versionString(p.ProjectVersion), p.State, p.PolicyStatus, p.CreatedAt.Format(time.RFC822), p.RunnerType}

if full {
var finishedAt string
Expand Down
15 changes: 8 additions & 7 deletions app/cli/documentation/cli-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3890,13 +3890,14 @@ chainloop workflow workflow-run list [flags]
Options

```
--full full report
-h, --help help for list
--limit int number of items to show (default 50)
--next string cursor to load the next page
--project string project name
--status string filter by workflow run status: [CANCELLED EXPIRED FAILED INITIALIZED SUCCEEDED]
--workflow string workflow name
--full full report
-h, --help help for list
--limit int number of items to show (default 50)
--next string cursor to load the next page
--policy-status string filter by policy violations status: all, failed, passed
--project string project name
--status string filter by workflow run status: [CANCELLED EXPIRED FAILED INITIALIZED SUCCEEDED]
--workflow string workflow name
```

Options inherited from parent commands
Expand Down
27 changes: 26 additions & 1 deletion app/cli/pkg/action/workflow_run_list.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024 The Chainloop Authors.
// Copyright 2024-2025 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -52,6 +52,7 @@ type WorkflowRunItem struct {
ContractRevisionUsed int `json:"contractRevisionUsed"`
ContractRevisionLatest int `json:"contractRevisionLatest"`
ProjectVersion *ProjectVersion `json:"projectVersion,omitempty"`
PolicyStatus string `json:"policyStatus,omitempty"`
}

type ProjectVersion struct {
Expand All @@ -74,6 +75,7 @@ type WorkflowRunListOpts struct {
WorkflowName, ProjectName string
Pagination *PaginationOpts
Status string
PolicyStatus string
}
type PaginationOpts struct {
Limit int
Expand All @@ -95,6 +97,18 @@ func (action *WorkflowRunList) Run(opts *WorkflowRunListOpts) (*PaginatedWorkflo
req.Status = v
}

// Map policy status string to proto enum
if opts.PolicyStatus != "" {
switch opts.PolicyStatus {
case "failed":
req.PolicyViolations = pb.PolicyViolationsFilter_POLICY_VIOLATIONS_FILTER_WITH_VIOLATIONS
case "passed":
req.PolicyViolations = pb.PolicyViolationsFilter_POLICY_VIOLATIONS_FILTER_WITHOUT_VIOLATIONS
case "all":
req.PolicyViolations = pb.PolicyViolationsFilter_POLICY_VIOLATIONS_FILTER_UNSPECIFIED
}
}

resp, err := client.List(context.Background(), req)
if err != nil {
return nil, err
Expand Down Expand Up @@ -145,6 +159,7 @@ func pbWorkflowRunItemToAction(in *pb.WorkflowRunItem) *WorkflowRunItem {
Version: in.GetVersion().GetVersion(),
Prerelease: in.GetVersion().GetPrerelease(),
},
PolicyStatus: humanizedPolicyStatus(in.HasPolicyViolations),
}

if in.GetContractVersion() != nil {
Expand All @@ -158,6 +173,16 @@ func pbWorkflowRunItemToAction(in *pb.WorkflowRunItem) *WorkflowRunItem {
return item
}

func humanizedPolicyStatus(hasPolicyViolations *bool) string {
if hasPolicyViolations == nil {
return "N/A"
}
if *hasPolicyViolations {
return "failed"
}
return "passed"
}

func humanizedRunnerType(in v1.CraftingSchema_Runner_RunnerType) string {
mapping := map[v1.CraftingSchema_Runner_RunnerType]string{
*v1.CraftingSchema_Runner_RUNNER_TYPE_UNSPECIFIED.Enum(): "Unspecified",
Expand Down
Loading
Loading