Skip to content

Commit

Permalink
Merge pull request #2 from RoryQ/missing-required-retries
Browse files Browse the repository at this point in the history
retry on missing required checks in case they are still being created
  • Loading branch information
RoryQ authored Apr 23, 2024
2 parents 785781e + 10df184 commit fce5aaf
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 15 deletions.
4 changes: 3 additions & 1 deletion action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ inputs:
description: Initial delay before polling.
poll_frequency_seconds:
description: Polling frequency.
missing_required_retry_count:
description: Number of times to retry if a required check is missing, for cases where the workflow is still being created.
version:
description: Release version of action to run.
runs:
using: node16
using: node20
main: index.js
branding:
icon: "check-square"
Expand Down
16 changes: 12 additions & 4 deletions pkg/reqcheck/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import (
"context"
"fmt"
"regexp"
"slices"
"strings"
"time"

"github.com/google/go-github/v61/github"
"github.com/samber/lo"
"github.com/sethvargo/go-githubactions"
"slices"

"github.com/roryq/required-checks/pkg/pullrequest"
)
Expand All @@ -34,6 +34,7 @@ func Run(ctx context.Context, cfg *Config, action *githubactions.Action, gh *git
return err
}

missingRequiredCount := 0
foundSelf := false
for {
checks, err := pr.ListChecks(ctx, cfg.TargetSHA, nil)
Expand All @@ -60,12 +61,17 @@ func Run(ctx context.Context, cfg *Config, action *githubactions.Action, gh *git
}
}

// If required is not found, retry in case the workflow is still being created then fail as there will not be a successful check.
requiredNotFound := lo.OmitByValues(requiredSet, []bool{true})
if len(requiredNotFound) > 0 {
return fmt.Errorf("required checks not found: %q", lo.Keys(requiredNotFound))
missingRequiredCount++
if missingRequiredCount > cfg.MissingRequiredRetryCount {
return fmt.Errorf("required checks not found: %q", lo.Keys(requiredNotFound))
}
action.Infof("Required checks not found: %q, continuing another %d times before failing", lo.Keys(requiredNotFound), cfg.MissingRequiredRetryCount-missingRequiredCount)
}

// any failed
// Find failed conclusions, and fail early if there is.
failed := lo.Filter(toCheck, func(item *github.CheckRun, _ int) bool {
return slices.Contains(failedConclusions, item.GetConclusion())
})
Expand All @@ -74,16 +80,18 @@ func Run(ctx context.Context, cfg *Config, action *githubactions.Action, gh *git
return fmt.Errorf("required checks failed: %q", checkNames(failed))
}

// not completed
// Wait until all statuses are completed.
notCompleted := lo.Filter(toCheck, func(item *github.CheckRun, _ int) bool {
return item.GetStatus() != StatusCompleted
})

// Break out of the loop if all checks are completed.
if len(notCompleted) == 0 {
action.Infof("All checks completed")
break
}

// sleep and try again.
action.Infof("Not all checks completed: %q", checkNames(notCompleted))
action.Infof("Waiting %s before next check", cfg.PollFrequency)
time.Sleep(cfg.PollFrequency)
Expand Down
29 changes: 20 additions & 9 deletions pkg/reqcheck/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,25 @@ import (
)

type Config struct {
RequiredWorkflowPatterns []string
InitialDelay time.Duration
PollFrequency time.Duration
TargetSHA string
RequiredWorkflowPatterns []string
InitialDelay time.Duration
PollFrequency time.Duration
MissingRequiredRetryCount int
TargetSHA string
}

const (
InitialDelayDefault = 15 * time.Second
PollFrequencyDefault = 30 * time.Second
InitialDelayDefault = 15 * time.Second
PollFrequencyDefault = 30 * time.Second
MissingRequiredRetryCountDefault = 2
)

func ConfigFromInputs(action *githubactions.Action) (*Config, error) {
action.Infof("Reading Config From Inputs")
c := Config{
InitialDelay: InitialDelayDefault,
PollFrequency: PollFrequencyDefault,
InitialDelay: InitialDelayDefault,
PollFrequency: PollFrequencyDefault,
MissingRequiredRetryCount: MissingRequiredRetryCountDefault,
}
requiredWorkflowPatterns := action.GetInput(inputs.RequiredWorkflowPatterns)
if requiredWorkflowPatterns != "" {
Expand All @@ -51,7 +54,15 @@ func ConfigFromInputs(action *githubactions.Action) (*Config, error) {
c.PollFrequency = time.Duration(pfs) * time.Second
}
}


if missingRequiredRetryCount := action.GetInput(inputs.MissingRequiredRetryCount); missingRequiredRetryCount != "" {
if mrrc, err := strconv.Atoi(missingRequiredRetryCount); err != nil {
action.Warningf("Failed to parse MissingRequiredRetryCount: %s", err)
} else {
c.MissingRequiredRetryCount = mrrc
}
}

var err error
c.TargetSHA, err = defaultTargetSHA(action)
if err != nil {
Expand Down
5 changes: 4 additions & 1 deletion pkg/reqcheck/inputs/inputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const (

TargetSHA = "TARGET_SHA"

// MissingRequiredRetryCount is the number of times to retry if a required check is missing, for cases where the workflow is still being created.
MissingRequiredRetryCount = "MISSING_REQUIRED_RETRY_COUNT"

// Version release version of the action to run
Version = "version"
Version = "VERSION"
)

0 comments on commit fce5aaf

Please sign in to comment.