|
| 1 | +package notification |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + |
| 7 | + argocdv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" |
| 8 | + "github.com/go-logr/logr" |
| 9 | + "github.com/int128/argocd-commenter/internal/github" |
| 10 | + "k8s.io/apimachinery/pkg/util/errors" |
| 11 | +) |
| 12 | + |
| 13 | +type Client interface { |
| 14 | + CreateComment(ctx context.Context, comment Comment, app argocdv1alpha1.Application) error |
| 15 | + CreateDeployment(ctx context.Context, ds DeploymentStatus) error |
| 16 | + CheckIfDeploymentIsAlreadyHealthy(ctx context.Context, deploymentURL string) (bool, error) |
| 17 | +} |
| 18 | + |
| 19 | +func NewClient(ghc github.Client) Client { |
| 20 | + return &client{ghc: ghc} |
| 21 | +} |
| 22 | + |
| 23 | +func IsNotFoundError(err error) bool { |
| 24 | + return github.IsNotFoundError(err) |
| 25 | +} |
| 26 | + |
| 27 | +type Comment struct { |
| 28 | + GitHubRepository github.Repository |
| 29 | + Revision string |
| 30 | + Body string |
| 31 | +} |
| 32 | + |
| 33 | +type client struct { |
| 34 | + ghc github.Client |
| 35 | +} |
| 36 | + |
| 37 | +func (c client) CreateComment(ctx context.Context, comment Comment, app argocdv1alpha1.Application) error { |
| 38 | + logger := logr.FromContextOrDiscard(ctx).WithValues( |
| 39 | + "revision", comment.Revision, |
| 40 | + "repository", comment.GitHubRepository, |
| 41 | + ) |
| 42 | + pulls, err := c.ghc.ListPullRequests(ctx, comment.GitHubRepository, comment.Revision) |
| 43 | + if err != nil { |
| 44 | + return fmt.Errorf("unable to list pull requests of revision %s: %w", comment.Revision, err) |
| 45 | + } |
| 46 | + relatedPullNumbers := filterPullRequestsRelatedToEvent(pulls, app) |
| 47 | + if len(relatedPullNumbers) == 0 { |
| 48 | + logger.Info("no pull request related to the revision") |
| 49 | + return nil |
| 50 | + } |
| 51 | + if err := c.createComment(ctx, comment.GitHubRepository, relatedPullNumbers, comment.Body); err != nil { |
| 52 | + return fmt.Errorf("unable to create comment(s) on revision %s: %w", comment.Revision, err) |
| 53 | + } |
| 54 | + logger.Info("created comment(s)", "pulls", relatedPullNumbers) |
| 55 | + return nil |
| 56 | +} |
| 57 | + |
| 58 | +func (c client) createComment(ctx context.Context, repository github.Repository, pullNumbers []int, body string) error { |
| 59 | + var errs []error |
| 60 | + for _, pullNumber := range pullNumbers { |
| 61 | + if err := c.ghc.CreateComment(ctx, repository, pullNumber, body); err != nil { |
| 62 | + errs = append(errs, err) |
| 63 | + continue |
| 64 | + } |
| 65 | + } |
| 66 | + if len(errs) > 0 { |
| 67 | + return errors.NewAggregate(errs) |
| 68 | + } |
| 69 | + return nil |
| 70 | +} |
| 71 | + |
| 72 | +type DeploymentStatus struct { |
| 73 | + GitHubDeployment github.Deployment |
| 74 | + GitHubDeploymentStatus github.DeploymentStatus |
| 75 | +} |
| 76 | + |
| 77 | +func (c client) CreateDeployment(ctx context.Context, ds DeploymentStatus) error { |
| 78 | + logger := logr.FromContextOrDiscard(ctx).WithValues( |
| 79 | + "deployment", ds.GitHubDeployment, |
| 80 | + "state", ds.GitHubDeploymentStatus.State, |
| 81 | + ) |
| 82 | + if err := c.ghc.CreateDeploymentStatus(ctx, ds.GitHubDeployment, ds.GitHubDeploymentStatus); err != nil { |
| 83 | + return fmt.Errorf("unable to create a deployment status of %s: %w", ds.GitHubDeploymentStatus.State, err) |
| 84 | + } |
| 85 | + logger.Info("created a deployment status") |
| 86 | + return nil |
| 87 | +} |
| 88 | + |
| 89 | +func (c client) CheckIfDeploymentIsAlreadyHealthy(ctx context.Context, deploymentURL string) (bool, error) { |
| 90 | + deployment := github.ParseDeploymentURL(deploymentURL) |
| 91 | + if deployment == nil { |
| 92 | + return false, nil |
| 93 | + } |
| 94 | + latestDeploymentStatus, err := c.ghc.FindLatestDeploymentStatus(ctx, *deployment) |
| 95 | + if err != nil { |
| 96 | + return false, fmt.Errorf("unable to find the latest deployment status: %w", err) |
| 97 | + } |
| 98 | + if latestDeploymentStatus == nil { |
| 99 | + return false, nil |
| 100 | + } |
| 101 | + return latestDeploymentStatus.State == "success", nil |
| 102 | +} |
0 commit comments