-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use ProviderManager in webhook handler #3202
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,6 @@ import ( | |
"github.com/stacklok/minder/internal/engine/entities" | ||
"github.com/stacklok/minder/internal/events" | ||
"github.com/stacklok/minder/internal/projects/features" | ||
"github.com/stacklok/minder/internal/providers" | ||
"github.com/stacklok/minder/internal/providers/github/installations" | ||
ghprov "github.com/stacklok/minder/internal/providers/github/service" | ||
"github.com/stacklok/minder/internal/repositories" | ||
|
@@ -501,22 +500,6 @@ func (s *Server) parseGithubEventForProcessing( | |
return fmt.Errorf("error getting repo information from payload: %w", err) | ||
} | ||
|
||
// get the provider for the repository | ||
prov, err := s.providerStore.GetByID(ctx, dbRepo.ProviderID) | ||
if err != nil { | ||
return fmt.Errorf("error getting provider: %w", err) | ||
} | ||
|
||
pbOpts := []providers.ProviderBuilderOption{ | ||
providers.WithProviderMetrics(s.provMt), | ||
providers.WithRestClientCache(s.restClientCache), | ||
} | ||
provBuilder, err := providers.GetProviderBuilder(ctx, *prov, s.store, s.cryptoEngine, &s.cfg.Provider, | ||
s.fallbackTokenClient, pbOpts...) | ||
if err != nil { | ||
return fmt.Errorf("error building client: %w", err) | ||
} | ||
|
||
var action string // explicit declaration to use the default value | ||
action, err = util.JQReadFrom[string](ctx, ".action", payload) | ||
if err != nil && !errors.Is(err, util.ErrNoValueFound) { | ||
|
@@ -526,9 +509,9 @@ func (s *Server) parseGithubEventForProcessing( | |
// determine if the payload is an artifact published event | ||
// TODO: this needs to be managed via signals | ||
if ent == pb.Entity_ENTITY_ARTIFACTS && action == WebhookActionEventPublished { | ||
return s.parseArtifactPublishedEvent(ctx, payload, msg, dbRepo, provBuilder, action) | ||
return s.parseArtifactPublishedEvent(ctx, payload, msg, dbRepo, dbRepo.ProviderID, action) | ||
} else if ent == pb.Entity_ENTITY_PULL_REQUESTS { | ||
return parsePullRequestModEvent(ctx, payload, msg, dbRepo, s.store, provBuilder, action) | ||
return s.parsePullRequestModEvent(ctx, payload, msg, dbRepo, dbRepo.ProviderID, action) | ||
} else if ent == pb.Entity_ENTITY_REPOSITORIES { | ||
return parseRepoEvent(payload, msg, dbRepo, action) | ||
} | ||
|
@@ -581,7 +564,7 @@ func (s *Server) parseArtifactPublishedEvent( | |
whPayload map[string]any, | ||
msg *message.Message, | ||
dbrepo db.Repository, | ||
prov *providers.ProviderBuilder, | ||
providerID uuid.UUID, | ||
action string, | ||
) error { | ||
// we need to have information about package and repository | ||
|
@@ -590,15 +573,15 @@ func (s *Server) parseArtifactPublishedEvent( | |
return nil | ||
} | ||
|
||
// NOTE(jaosorior): this webhook is very specific to github | ||
if !prov.Implements(db.ProviderTypeGithub) { | ||
log.Printf("provider %s is not supported for github webhook", prov.GetName()) | ||
return nil | ||
provider, err := s.providerManager.InstantiateFromID(ctx, providerID) | ||
if err != nil { | ||
log.Printf("error instantiating provider: %v", err) | ||
return err | ||
} | ||
|
||
cli, err := prov.GetGitHub() | ||
cli, err := provifv1.As[provifv1.GitHub](provider) | ||
if err != nil { | ||
log.Printf("error creating github provider: %v", err) | ||
log.Printf("error instantiating provider: %v", err) | ||
return err | ||
} | ||
|
||
|
@@ -641,33 +624,32 @@ func (s *Server) parseArtifactPublishedEvent( | |
return eiw.ToMessage(msg) | ||
} | ||
|
||
func parsePullRequestModEvent( | ||
func (s *Server) parsePullRequestModEvent( | ||
ctx context.Context, | ||
whPayload map[string]any, | ||
msg *message.Message, | ||
dbrepo db.Repository, | ||
store db.Store, | ||
prov *providers.ProviderBuilder, | ||
providerID uuid.UUID, | ||
action string, | ||
) error { | ||
// NOTE(jaosorior): this webhook is very specific to github | ||
if !prov.Implements(db.ProviderTypeGithub) { | ||
log.Printf("provider %s is not supported for github webhook", prov.GetName()) | ||
return nil | ||
provider, err := s.providerManager.InstantiateFromID(ctx, providerID) | ||
if err != nil { | ||
log.Printf("error instantiating provider: %v", err) | ||
return err | ||
} | ||
|
||
cli, err := prov.GetGitHub() | ||
cli, err := provifv1.As[provifv1.GitHub](provider) | ||
if err != nil { | ||
log.Printf("error creating github provider: %v", err) | ||
return nil | ||
log.Printf("error instantiating provider: %v", err) | ||
return err | ||
} | ||
|
||
prEvalInfo, err := getPullRequestInfoFromPayload(ctx, whPayload) | ||
if err != nil { | ||
return fmt.Errorf("error getting pull request information from payload: %w", err) | ||
} | ||
|
||
dbPr, err := reconcilePrWithDb(ctx, store, dbrepo, prEvalInfo) | ||
dbPr, err := s.reconcilePrWithDb(ctx, dbrepo, prEvalInfo) | ||
if errors.Is(err, errNotHandled) { | ||
return err | ||
} else if err != nil { | ||
|
@@ -864,9 +846,8 @@ func getPullRequestInfoFromPayload( | |
}, nil | ||
} | ||
|
||
func reconcilePrWithDb( | ||
func (s *Server) reconcilePrWithDb( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed some functions to methods so we do not need to pass around the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Long-term, we want these to be in the provider implementation and not the server, correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eventually, yes. |
||
ctx context.Context, | ||
store db.Store, | ||
dbrepo db.Repository, | ||
prEvalInfo *pb.PullRequest, | ||
) (*db.PullRequest, error) { | ||
|
@@ -875,7 +856,7 @@ func reconcilePrWithDb( | |
|
||
switch prEvalInfo.Action { | ||
case WebhookActionEventOpened, WebhookActionEventSynchronize: | ||
dbPr, err := store.UpsertPullRequest(ctx, db.UpsertPullRequestParams{ | ||
dbPr, err := s.store.UpsertPullRequest(ctx, db.UpsertPullRequestParams{ | ||
RepositoryID: dbrepo.ID, | ||
PrNumber: prEvalInfo.Number, | ||
}) | ||
|
@@ -887,7 +868,7 @@ func reconcilePrWithDb( | |
retPr = &dbPr | ||
retErr = nil | ||
case WebhookActionEventClosed: | ||
err := store.DeletePullRequest(ctx, db.DeletePullRequestParams{ | ||
err := s.store.DeletePullRequest(ctx, db.DeletePullRequestParams{ | ||
RepositoryID: dbrepo.ID, | ||
PrNumber: prEvalInfo.Number, | ||
}) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,6 @@ import ( | |
"bytes" | ||
"context" | ||
"database/sql" | ||
"encoding/base64" | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
|
@@ -35,10 +34,8 @@ import ( | |
"github.com/stretchr/testify/require" | ||
"github.com/stretchr/testify/suite" | ||
"go.uber.org/mock/gomock" | ||
"golang.org/x/oauth2" | ||
|
||
mockdb "github.com/stacklok/minder/database/mock" | ||
"github.com/stacklok/minder/internal/crypto" | ||
"github.com/stacklok/minder/internal/db" | ||
"github.com/stacklok/minder/internal/engine/entities" | ||
"github.com/stacklok/minder/internal/events" | ||
|
@@ -246,27 +243,6 @@ func (s *UnitTestSuite) TestHandleWebHookRepository() { | |
projectID := uuid.New() | ||
providerID := uuid.New() | ||
|
||
// create a test oauth2 token | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No longer needed because the token querying is not triggered unless the provider is actually instantiated. The test case for the handler does not need the provider to be instantiated. |
||
token := oauth2.Token{ | ||
AccessToken: "test", | ||
TokenType: "test", | ||
} | ||
// marshal the token | ||
byteToken, err := json.Marshal(token) | ||
require.NoError(t, err, "failed to marshal decryptedToken") | ||
// encrypt the token | ||
encryptedToken, err := crypto.EncryptBytes("test", byteToken) | ||
require.NoError(t, err, "failed to encrypt token") | ||
|
||
// Encode the token to Base64 | ||
encodedToken := base64.StdEncoding.EncodeToString(encryptedToken) | ||
mockStore.EXPECT().GetAccessTokenByProjectID(gomock.Any(), gomock.Any()).Return(db.ProviderAccessToken{ | ||
EncryptedToken: encodedToken, | ||
ID: 1, | ||
ProjectID: projectID, | ||
Provider: providerName, | ||
}, nil) | ||
|
||
mockStore.EXPECT(). | ||
GetRepositoryByRepoID(gomock.Any(), gomock.Any()). | ||
Return(db.Repository{ | ||
|
@@ -277,14 +253,6 @@ func (s *UnitTestSuite) TestHandleWebHookRepository() { | |
ProviderID: providerID, | ||
}, nil) | ||
|
||
mockStore.EXPECT(). | ||
GetProviderByID(gomock.Any(), gomock.Eq(providerID)). | ||
Return(db.Provider{ | ||
ID: providerID, | ||
ProjectID: projectID, | ||
Name: providerName, | ||
}, nil) | ||
|
||
hook := srv.HandleGitHubWebHook() | ||
port, err := rand.GetRandomPort() | ||
if err != nil { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is still true, we just think it's obvious, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct - but this particular codepath is so Github-specific that it's not really worth noting any more.