Skip to content

Commit

Permalink
add an argument to ignore jobs (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
tekiflo authored Jun 22, 2022
1 parent 9898273 commit d6129ef
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ There are some customisation available for Merge Gatekeeper.
| `self` | The name of Merge Gatekeeper job, and defaults to `merge-gatekeeper`. This is used to check other job status, and do not check Merge Gatekeeper itself. If you updated the GitHub Action job name from `merge-gatekeeper` to something else, you would need to specify the new name with this value. | |
| `interval` | Check interval to recheck the job status. Default is set to 30 (sec). | |
| `timeout` | Timeout setup to give up further check. Default is set to 600 (sec). | |
| `ignored` | Jobs to ignore regardless of their statuses. Defined as a comma-separated list. | |
| `ref` | Git ref to check out. This falls back to the HEAD for given PR, but can be set to any ref. | |

<!-- == imptr: inputs / end == -->
Expand Down
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ inputs:
description: "set validate timeout second (default 600)"
required: false
default: "600"
ignored:
description: "set ignored jobs (comma-separated list)"
required: false
default: ""
ref:
description: "set ref of github repository. the ref can be a SHA, a branch name, or tag name"
required: false
Expand All @@ -33,3 +37,4 @@ runs:
- "--interval=${{ inputs.interval }}"
- "--ref=${{ inputs.ref }}"
- "--timeout=${{ inputs.timeout }}"
- "--ignored=${{ inputs.ignored }}"
1 change: 1 addition & 0 deletions docs/action-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
| `self` | The name of Merge Gatekeeper job, and defaults to `merge-gatekeeper`. This is used to check other job status, and do not check Merge Gatekeeper itself. If you updated the GitHub Action job name from `merge-gatekeeper` to something else, you would need to specify the new name with this value. | |
| `interval` | Check interval to recheck the job status. Default is set to 30 (sec). | |
| `timeout` | Timeout setup to give up further check. Default is set to 600 (sec). | |
| `ignored` | Jobs to ignore regardless of their statuses. Defined as a comma-separated list. | |
| `ref` | Git ref to check out. This falls back to the HEAD for given PR, but can be set to any ref. | |

<!-- == export: inputs / end == -->
Expand Down
4 changes: 4 additions & 0 deletions internal/cli/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ var (
timeoutSecond uint
validateInvalSecond uint
selfJobName string
ignoreJobs string
)

func validateCmd() *cobra.Command {
Expand All @@ -48,6 +49,7 @@ func validateCmd() *cobra.Command {
status.WithSelfJob(selfJobName),
status.WithGitHubOwnerAndRepo(owner, repo),
status.WithGitHubRef(ghRef),
status.WithIgnoredJobs(ignoreJobs),
)
if err != nil {
return fmt.Errorf("failed to create validator: %w", err)
Expand All @@ -68,6 +70,8 @@ func validateCmd() *cobra.Command {
cmd.PersistentFlags().UintVar(&timeoutSecond, "timeout", 600, "set validate timeout second")
cmd.PersistentFlags().UintVar(&validateInvalSecond, "interval", 10, "set validate interval second")

cmd.PersistentFlags().StringVarP(&ignoreJobs, "ignore", "i", "", "set ignored jobs (comma-separated list)")

return cmd
}

Expand Down
10 changes: 10 additions & 0 deletions internal/validators/status/option.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package status

import "strings"

type Option func(s *statusValidator)

func WithSelfJob(name string) Option {
Expand Down Expand Up @@ -28,3 +30,11 @@ func WithGitHubRef(ref string) Option {
}
}
}

func WithIgnoredJobs(names string) Option {
return func(s *statusValidator) {
if len(names) != 0 {
s.ignoredJobs = strings.Split(names, ",")
}
}
}
19 changes: 17 additions & 2 deletions internal/validators/status/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type statusValidator struct {
owner string
ref string
selfJobName string
ignoredJobs []string
client github.Client
}

Expand Down Expand Up @@ -76,6 +77,11 @@ func (sv *statusValidator) validateFields() error {
if len(sv.selfJobName) == 0 {
errs = append(errs, errors.New("self job name is empty"))
}
for _, job := range sv.ignoredJobs {
if len(job) == 0 {
errs = append(errs, errors.New("ignored job name is empty"))
}
}
if sv.client == nil {
errs = append(errs, errors.New("github client is empty"))
}
Expand All @@ -102,11 +108,20 @@ func (sv *statusValidator) Validate(ctx context.Context) (validators.Status, err

var successCnt int
for _, ghaStatus := range ghaStatuses {
// This job itself should be considered as success regardless of its status.
if ghaStatus.Job == sv.selfJobName {
var toIgnore bool
for _, ignored := range sv.ignoredJobs {
if ghaStatus.Job == ignored {
toIgnore = true
break
}
}

// Ignored jobs and this job itself should be considered as success regardless of their statuses.
if toIgnore || ghaStatus.Job == sv.selfJobName {
successCnt++
continue
}

st.totalJobs = append(st.totalJobs, ghaStatus.Job)

switch ghaStatus.State {
Expand Down
39 changes: 38 additions & 1 deletion internal/validators/status/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ func TestCreateValidator(t *testing.T) {
WithGitHubOwnerAndRepo("test-owner", "test-repo"),
WithGitHubRef("sha"),
WithSelfJob("job"),
WithIgnoredJobs("job-01,job-02"),
},
want: &statusValidator{
client: &mock.Client{},
owner: "test-owner",
repo: "test-repo",
ref: "sha",
selfJobName: "job",
ignoredJobs: []string{"job-01", "job-02"},
},
wantErr: false,
},
Expand Down Expand Up @@ -79,6 +81,7 @@ func TestCreateValidator(t *testing.T) {
func Test_statusValidator_Validate(t *testing.T) {
type test struct {
selfJobName string
ignoredJobs []string
client github.Client
ctx context.Context
wantErr bool
Expand Down Expand Up @@ -277,11 +280,46 @@ func Test_statusValidator_Validate(t *testing.T) {
errJobs: []string{},
},
},
"returns succeeded status and nil when only an ignored job is failing": {
selfJobName: "self-job",
ignoredJobs: []string{"job-02", "job-03"},
client: &mock.Client{
GetCombinedStatusFunc: func(ctx context.Context, owner, repo, ref string, opts *github.ListOptions) (*github.CombinedStatus, *github.Response, error) {
return &github.CombinedStatus{
Statuses: []*github.RepoStatus{
{
Context: stringPtr("job-01"),
State: stringPtr(successState),
},
{
Context: stringPtr("job-02"),
State: stringPtr(errorState),
},
{
Context: stringPtr("self-job"),
State: stringPtr(pendingState),
},
},
}, nil, nil
},
ListCheckRunsForRefFunc: func(ctx context.Context, owner, repo, ref string, opts *github.ListCheckRunsOptions) (*github.ListCheckRunsResults, *github.Response, error) {
return &github.ListCheckRunsResults{}, nil, nil
},
},
wantErr: false,
wantStatus: &status{
succeeded: true,
totalJobs: []string{"job-01"},
completeJobs: []string{"job-01"},
errJobs: []string{},
},
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
sv := &statusValidator{
selfJobName: tt.selfJobName,
ignoredJobs: tt.ignoredJobs,
client: tt.client,
}
got, err := sv.Validate(tt.ctx)
Expand All @@ -303,7 +341,6 @@ func Test_statusValidator_Validate(t *testing.T) {

func Test_statusValidator_listStatues(t *testing.T) {
type fields struct {
token string
repo string
owner string
ref string
Expand Down

0 comments on commit d6129ef

Please sign in to comment.