Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions backend/controllers/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@ func (d DiggerController) GithubAppWebHook(c *gin.Context) {
return
}
}
case *github.InstallationRepositoriesEvent:
slog.Info("Processing InstallationRepositoriesEvent",
"action", *event.Action,
"installationId", *event.Installation.ID,
"repositoriesAdded", len(event.RepositoriesAdded),
"repositoriesRemoved", len(event.RepositoriesRemoved),
)

err := handleInstallationRepositoriesEvent(event, appId64)
if err != nil {
slog.Error("Failed to handle installation repositories event", "error", err)
c.String(http.StatusAccepted, "Failed to handle webhook event.")
return
}
case *github.PushEvent:
slog.Info("Processing PushEvent",
"repo", *event.Repo.FullName,
Expand Down
10 changes: 8 additions & 2 deletions backend/controllers/github_callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,19 @@ func (d DiggerController) GithubAppCallbackPage(c *gin.Context) {
c.String(http.StatusBadRequest, "installation_id parameter for github app is empty")
return
}

//setupAction := c.Request.URL.Query()["setup_action"][0]
codeParams, codeExists := c.Request.URL.Query()["code"]

// Code parameter is only provided for fresh installations, not for updates
// If code is missing, this is likely an update - just show success page
// The actual repository changes will be handled by the InstallationRepositoriesEvent webhook
if !codeExists || len(codeParams) == 0 {
slog.Error("There was no code in the url query parameters")
c.String(http.StatusBadRequest, "could not find the code query parameter for github app")
slog.Info("No code parameter - likely an installation update, showing success page")
c.HTML(http.StatusOK, "github_success.tmpl", gin.H{})
return
}

code := codeParams[0]
if len(code) < 1 {
slog.Error("Code parameter is empty")
Expand Down
68 changes: 67 additions & 1 deletion backend/controllers/github_installation.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package controllers

import (
"log/slog"

"github.com/diggerhq/digger/backend/models"
"github.com/google/go-github/v61/github"
"log/slog"
)

func handleInstallationDeletedEvent(installation *github.InstallationEvent, appId int64) error {
Expand Down Expand Up @@ -47,3 +48,68 @@ func handleInstallationDeletedEvent(installation *github.InstallationEvent, appI
slog.Info("Successfully handled installation deleted event", "installationId", installationId)
return nil
}

func handleInstallationRepositoriesEvent(event *github.InstallationRepositoriesEvent, appId int64) error {
installationId := *event.Installation.ID
action := *event.Action

slog.Info("Handling installation repositories event",
"installationId", installationId,
"appId", appId,
"action", action,
"repositoriesAdded", len(event.RepositoriesAdded),
"repositoriesRemoved", len(event.RepositoriesRemoved),
)

// Handle removed repositories
for _, repo := range event.RepositoriesRemoved {
repoFullName := *repo.FullName
slog.Info("Removing repository from installation",
"installationId", installationId,
"repoFullName", repoFullName,
)

_, err := models.DB.GithubRepoRemoved(installationId, appId, repoFullName)
if err != nil {
slog.Error("Error removing GitHub repo",
"installationId", installationId,
"repoFullName", repoFullName,
"error", err,
)
return err
}
}

// Handle added repositories
for _, repo := range event.RepositoriesAdded {
repoFullName := *repo.FullName
slog.Info("Adding repository to installation",
"installationId", installationId,
"repoFullName", repoFullName,
)

_, err := models.DB.GithubRepoAdded(
installationId,
appId,
*event.Installation.Account.Login,
*event.Installation.Account.ID,
repoFullName,
)
if err != nil {
slog.Error("Error adding GitHub repo",
"installationId", installationId,
"repoFullName", repoFullName,
"error", err,
)
return err
}
}

slog.Info("Successfully handled installation repositories event",
"installationId", installationId,
"repositoriesAdded", len(event.RepositoriesAdded),
"repositoriesRemoved", len(event.RepositoriesRemoved),
)

return nil
}
31 changes: 31 additions & 0 deletions backend/controllers/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,3 +866,34 @@ func TestJobsTreeWithThreeLevels(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, result["333"].DiggerJobID, parentLinks[0].ParentDiggerJobId)
}

func TestHandleInstallationRepositoriesEvent(t *testing.T) {
teardownSuite, database := setupSuite(t)
defer teardownSuite(t)

// Test repositories added event
var addedEvent github.InstallationRepositoriesEvent
err := json.Unmarshal([]byte(installationRepositoriesAddedPayload), &addedEvent)
assert.NoError(t, err)

err = handleInstallationRepositoriesEvent(&addedEvent, 360162)
assert.NoError(t, err)

// Verify repo was added
installation, err := database.GetGithubAppInstallationByIdAndRepo(41584295, "diggerhq/test-github-action")
assert.NoError(t, err)
assert.NotNil(t, installation)
assert.Equal(t, "diggerhq/test-github-action", installation.Repo)

// Test repositories removed event
var removedEvent github.InstallationRepositoriesEvent
err = json.Unmarshal([]byte(installationRepositoriesDeletedPayload), &removedEvent)
assert.NoError(t, err)

err = handleInstallationRepositoriesEvent(&removedEvent, 360162)
assert.NoError(t, err)

// Verify repo was removed (soft deleted)
installation, err = database.GetGithubAppInstallationByIdAndRepo(41584295, "diggerhq/test-github-action")
assert.Error(t, err) // Should error because repo is deleted
}
Loading