Skip to content

Commit

Permalink
Add check run notification
Browse files Browse the repository at this point in the history
  • Loading branch information
int128 committed Sep 19, 2022
1 parent 9621795 commit 2d23341
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ jobs:
env:
PULL_REQUEST_BODY: "e2e-test ${{ github.repository }}#${{ github.event.pull_request.number }}"
DEPLOYMENT_URL: ${{ steps.deployment-app1.outputs.url }}
COMMIT_URL: ${{ github.api_url }}/repos/${{ github.repository }}/commits/${{ steps.commit.outputs.sha }}
GITHUB_TOKEN: ${{ steps.octoken.outputs.token }}

- run: make -C e2e_test restart-app1
Expand All @@ -126,6 +127,7 @@ jobs:
env:
PULL_REQUEST_BODY: "e2e-test ${{ github.repository }}#${{ github.event.pull_request.number }}"
DEPLOYMENT_URL: ${{ steps.deployment-app2.outputs.url }}
COMMIT_URL: ${{ github.api_url }}/repos/${{ github.repository }}/commits/${{ steps.commit.outputs.sha }}
GITHUB_TOKEN: ${{ steps.octoken.outputs.token }}

# show logs
Expand Down
3 changes: 3 additions & 0 deletions controllers/applicationhealthcomment_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ func (r *ApplicationHealthCommentReconciler) Reconcile(ctx context.Context, req
if err := r.Notification.Comment(ctx, e); err != nil {
logger.Error(err, "unable to send a comment")
}
if err := r.Notification.CheckRun(ctx, e); err != nil {
logger.Error(err, "unable to send a check run notification")
}
return ctrl.Result{}, nil
}

Expand Down
3 changes: 3 additions & 0 deletions controllers/applicationphase_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func (r *ApplicationPhaseReconciler) Reconcile(ctx context.Context, req ctrl.Req
if err := r.Notification.Deployment(ctx, e); err != nil {
logger.Error(err, "unable to send a deployment status")
}
if err := r.Notification.CheckRun(ctx, e); err != nil {
logger.Error(err, "unable to send a check run notification")
}
return ctrl.Result{}, nil
}

Expand Down
2 changes: 2 additions & 0 deletions e2e_test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ undeploy:
# fixture
deploy-app1:
kubectl -n argocd annotate application app1 'argocd-commenter.int128.github.io/deployment-url=$(DEPLOYMENT_URL)'
kubectl -n argocd annotate application app1 'argocd-commenter.int128.github.io/commit-url=$(COMMIT_URL)'
$(MAKE) -C argocd-commenter-e2e-test-repository update-manifest-app1
./wait-for-sync-status.sh app1 $(FIXTURE_BRANCH)/main Synced Succeeded Healthy

Expand All @@ -53,6 +54,7 @@ restart-app1:

deploy-app2:
kubectl -n argocd annotate application app2 'argocd-commenter.int128.github.io/deployment-url=$(DEPLOYMENT_URL)'
kubectl -n argocd annotate application app2 'argocd-commenter.int128.github.io/commit-url=$(COMMIT_URL)'
$(MAKE) -C argocd-commenter-e2e-test-repository update-manifest-app2
./wait-for-sync-status.sh app2 $(FIXTURE_BRANCH)/main OutOfSync Failed Healthy

Expand Down
54 changes: 54 additions & 0 deletions pkg/github/checkrun.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package github

import (
"context"
"fmt"
"github.com/google/go-github/v39/github"
"regexp"
)

type Commit struct {
Repository Repository
SHA string
}

var patternCommitURL = regexp.MustCompile(`^https://api\.github\.com/repos/(.+?)/(.+?)/commits/([0-9a-f]+)$`)

func ParseCommitURL(s string) *Commit {
m := patternCommitURL.FindStringSubmatch(s)
if len(m) != 4 {
return nil
}
return &Commit{
Repository: Repository{Owner: m[1], Name: m[2]},
SHA: m[3],
}
}

type CheckRun struct {
Name string
Status string
Conclusion string
Title string
Summary string
}

func (c *client) CreateCheckRun(ctx context.Context, commit Commit, cr CheckRun) error {
o := github.CreateCheckRunOptions{
HeadSHA: commit.SHA,
Name: cr.Name,
Status: github.String(cr.Status),
Output: &github.CheckRunOutput{
Title: github.String(cr.Title),
Summary: github.String(cr.Summary),
},
}
if cr.Conclusion != "" {
o.Conclusion = github.String(cr.Conclusion)
}
_, _, err := c.rest.Checks.CreateCheckRun(ctx, commit.Repository.Owner, commit.Repository.Name, o)
if err != nil {
return fmt.Errorf("GitHub API error: %w", err)
}
return nil
}
1 change: 1 addition & 0 deletions pkg/github/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Client interface {
ListPullRequests(ctx context.Context, r Repository, revision string) ([]PullRequest, error)
CreateComment(ctx context.Context, r Repository, pulls []int, body string) error
CreateDeploymentStatus(ctx context.Context, d Deployment, ds DeploymentStatus) error
CreateCheckRun(ctx context.Context, cr Commit, ds CheckRun) error
}

type Repository struct {
Expand Down
96 changes: 96 additions & 0 deletions pkg/notification/checkrun.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package notification

import (
"context"
"fmt"
"github.com/argoproj/gitops-engine/pkg/health"
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/go-logr/logr"
"github.com/int128/argocd-commenter/pkg/github"
"strings"
)

func (c client) CheckRun(ctx context.Context, e Event) error {
logger := logr.FromContextOrDiscard(ctx)

commitURL := e.Application.Annotations["argocd-commenter.int128.github.io/commit-url"]
commit := github.ParseCommitURL(commitURL)
if commit == nil {
return nil
}

cr := generateCheckRun(e)
if cr == nil {
logger.Info("nothing to update the check run", "event", e)
return nil
}

logger.Info("updating the check run", "checkRun", commitURL)
if err := c.ghc.CreateCheckRun(ctx, *commit, *cr); err != nil {
return fmt.Errorf("unable to create a check run: %w", err)
}
return nil
}

func generateCheckRun(e Event) *github.CheckRun {
applicationURL := fmt.Sprintf("%s/applications/%s", e.ArgoCDURL, e.Application.Name)
externalURLs := strings.Join(e.Application.Status.Summary.ExternalURLs, "\n")

var checkRun github.CheckRun
checkRun.Name = e.Application.Name
checkRun.Summary = fmt.Sprintf(`
## Argo CD
%s
## External URL
%s
`, applicationURL, externalURLs)

if e.PhaseIsChanged {
if e.Application.Status.OperationState == nil {
return nil
}
switch e.Application.Status.OperationState.Phase {
case synccommon.OperationRunning:
checkRun.Status = "in_progress"
checkRun.Title = fmt.Sprintf("Syncing: %s", e.Application.Status.OperationState.Message)
return &checkRun
case synccommon.OperationSucceeded:
checkRun.Status = "completed"
checkRun.Conclusion = "success"
checkRun.Title = fmt.Sprintf("Synced: %s", e.Application.Status.OperationState.Message)
return &checkRun
case synccommon.OperationFailed:
checkRun.Status = "completed"
checkRun.Conclusion = "failure"
checkRun.Title = fmt.Sprintf("Sync Failed: %s", e.Application.Status.OperationState.Message)
return &checkRun
case synccommon.OperationError:
checkRun.Status = "completed"
checkRun.Conclusion = "failure"
checkRun.Title = fmt.Sprintf("Sync Error: %s", e.Application.Status.OperationState.Message)
return &checkRun
}
}

if e.HealthIsChanged {
switch e.Application.Status.Health.Status {
case health.HealthStatusProgressing:
checkRun.Status = "in_progress"
checkRun.Title = fmt.Sprintf("Progressing: %s", e.Application.Status.Health.Message)
return &checkRun
case health.HealthStatusHealthy:
checkRun.Status = "completed"
checkRun.Conclusion = "success"
checkRun.Title = fmt.Sprintf("Healthy: %s", e.Application.Status.Health.Message)
return &checkRun
case health.HealthStatusDegraded:
checkRun.Status = "completed"
checkRun.Conclusion = "failure"
checkRun.Title = fmt.Sprintf("Degraded: %s", e.Application.Status.Health.Message)
return &checkRun
}
}

return nil
}
1 change: 1 addition & 0 deletions pkg/notification/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
type Client interface {
Comment(context.Context, Event) error
Deployment(context.Context, Event) error
CheckRun(context.Context, Event) error
}

func NewClient(ghc github.Client) Client {
Expand Down

0 comments on commit 2d23341

Please sign in to comment.