Skip to content

Commit

Permalink
Allow GitHub InstallationID override
Browse files Browse the repository at this point in the history
Signed-off-by: Dustin Lactin <[email protected]>
  • Loading branch information
dlactin committed Nov 20, 2024
1 parent 2fef5c9 commit 67fae0c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 8 deletions.
64 changes: 58 additions & 6 deletions pkg/services/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type GitHubNotification struct {
Status *GitHubStatus `json:"status,omitempty"`
Deployment *GitHubDeployment `json:"deployment,omitempty"`
PullRequestComment *GitHubPullRequestComment `json:"pullRequestComment,omitempty"`
InstallationID string `json:"installationID,omitempty"`
RepoURLPath string `json:"repoURLPath,omitempty"`
RevisionPath string `json:"revisionPath,omitempty"`
}
Expand Down Expand Up @@ -75,6 +76,11 @@ func (g *GitHubNotification) GetTemplater(name string, f texttemplate.FuncMap) (
g.RevisionPath = revisionTemplate
}

installationID, err := texttemplate.New(name).Funcs(f).Parse(g.InstallationID)
if err != nil {
return nil, err
}

repoURL, err := texttemplate.New(name).Funcs(f).Parse(g.RepoURLPath)
if err != nil {
return nil, err
Expand Down Expand Up @@ -142,11 +148,18 @@ func (g *GitHubNotification) GetTemplater(name string, f texttemplate.FuncMap) (
return func(notification *Notification, vars map[string]interface{}) error {
if notification.GitHub == nil {
notification.GitHub = &GitHubNotification{
RepoURLPath: g.RepoURLPath,
RevisionPath: g.RevisionPath,
RepoURLPath: g.RepoURLPath,
RevisionPath: g.RevisionPath,
InstallationID: g.InstallationID,
}
}

var installationData bytes.Buffer
if err := installationID.Execute(&installationData, vars); err != nil {
return err
}
notification.GitHub.InstallationID = installationData.String()

var repoData bytes.Buffer
if err := repoURL.Execute(&repoData, vars); err != nil {
return err
Expand Down Expand Up @@ -284,10 +297,7 @@ func NewGitHubService(opts GitHubOptions) (NotificationService, error) {
}
}

return &gitHubService{
opts: opts,
client: client,
}, nil
return &gitHubService{opts: opts, client: client}, nil
}

type gitHubService struct {
Expand Down Expand Up @@ -326,6 +336,48 @@ func (g gitHubService) Send(notification Notification, _ Destination) error {
if len(u) < 2 {
return fmt.Errorf("GitHub.repoURL (%s) does not have a `/`", notification.GitHub.repoURL)
}
if g.opts.InstallationID == nil {
if notification.GitHub.InstallationID == "" {
return fmt.Errorf("GitHub Installation ID not found")
}
}
// If an alternate InstallationID is being provided create a new GitHub app client and use that instead
if notification.GitHub.InstallationID != "" {
url := "https://api.github.com"
if g.opts.EnterpriseBaseURL != "" {
url = g.opts.EnterpriseBaseURL
}

appID, err := cast.ToInt64E(g.opts.AppID)
if err != nil {
return nil
}

installationID, err := cast.ToInt64E(g.opts.InstallationID)
if err != nil {
return nil
}

tr := httputil.NewLoggingRoundTripper(
httputil.NewTransport(url, false), log.WithField("service", "github"))
itr, err := ghinstallation.New(tr, appID, installationID, []byte(g.opts.PrivateKey))
if err != nil {
return nil
}

var client *github.Client
if g.opts.EnterpriseBaseURL == "" {
client = github.NewClient(&http.Client{Transport: itr})
} else {
itr.BaseURL = g.opts.EnterpriseBaseURL
client, err = github.NewEnterpriseClient(g.opts.EnterpriseBaseURL, "", &http.Client{Transport: itr})
if err != nil {
return nil
}
}
g.client = client
}

if notification.GitHub.Status != nil {
// maximum is 140 characters
description := trunc(notification.Message, 140)
Expand Down
21 changes: 19 additions & 2 deletions pkg/services/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,29 @@ func TestSend_GitHubService_BadURL(t *testing.T) {
assert.ErrorContains(t, e, "does not have a `/`")
}

func TestGetTemplater_GithubNotification_MissingInstallationID(t *testing.T) {
e := gitHubService{}.Send(
Notification{
GitHub: &GitHubNotification{
repoURL: "https://github.com/",
},
},
Destination{
Service: "test",
Recipient: "test",
},
)
assert.ErrorContains(t, e, "Installation ID not found")
}

func TestGetTemplater_GitHub_Deployment(t *testing.T) {
f := false
tr := true
n := Notification{
GitHub: &GitHubNotification{
RepoURLPath: "{{.sync.spec.git.repo}}",
RevisionPath: "{{.sync.status.lastSyncedCommit}}",
InstallationID: "12345",
RepoURLPath: "{{.sync.spec.git.repo}}",
RevisionPath: "{{.sync.status.lastSyncedCommit}}",
Deployment: &GitHubDeployment{
Reference: "v0.0.1",
State: "success",
Expand Down Expand Up @@ -167,6 +183,7 @@ func TestGetTemplater_GitHub_Deployment(t *testing.T) {
return
}

assert.Equal(t, "12345", notification.GitHub.InstallationID)
assert.Equal(t, "{{.sync.spec.git.repo}}", notification.GitHub.RepoURLPath)
assert.Equal(t, "{{.sync.status.lastSyncedCommit}}", notification.GitHub.RevisionPath)
assert.Equal(t, "https://github.com/argoproj-labs/argocd-notifications.git", notification.GitHub.repoURL)
Expand Down

0 comments on commit 67fae0c

Please sign in to comment.