Skip to content
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

feat(bitbucketserver): multiple improvements to bitbucketserver event source #2921

Conversation

ryancurrah
Copy link
Contributor

@ryancurrah ryancurrah commented Nov 26, 2023

There are no breaking changes in the pull request, the event source will behave the same by default. One bigger internal change is that the Bitbucket Server client is now created once, set on the Route struct.


This Pull Request contains 3 improvements to the Bitbucket Server Event source.

  1. Customizable Apply Webhook Check Interval

Currently the apply webhook check runs every 60 seconds which could be to often. This is now configurable.

  1. Manage Webhooks for Entire Projects

When a list of Bitbucket Server Projects are provided the event source will ensure a webhook exists in all repositories in the provided project.

  1. Ability to skip Refs Changed event type when a Pull Request is Open for the same commit.

This feature aims to reduce redundant workflow triggers caused by Bitbucket's event handling. Specifically, when a Pull Request is opened and a new commit is pushed, Bitbucket sends two events: repo:refs_changed and either pr:from_ref_created (for a new PR) or pr:from_ref_updated (for an existing PR). This results in multiple workflows being launched for both Branch and Pull Request events.

To address this, the Pull Request adds a boolean option named skipBranchRefsChangedOnOpenPR. This option, when enabled, performs a check to determine if a Pull Request is open for a specific branch commit associated with a repo:refs_changed event. If a PR is open for that commit, the new feature will skip sending the repo:refs_changed event. This effectively prevents the triggering of multiple workflows for the same commit in the scenario where a Pull Request is opened.

@ryancurrah ryancurrah changed the title feat(bitbucketserver): multiple improvements to bitbucket server even… feat(bitbucketserver): multiple improvements to bitbucketserver event source Nov 26, 2023
@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch 4 times, most recently from 299a80a to 461fbe8 Compare November 27, 2023 05:21
@ryancurrah
Copy link
Contributor Author

Testing these changes in our environment. When they have baked for a little bit I will change this PR to Ready for Review.

Copy link
Member

@whynowy whynowy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daniel-codefresh - could you take a look?

pkg/apis/eventsource/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/eventsource/v1alpha1/types.go Outdated Show resolved Hide resolved
@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch from 49094db to 37958b8 Compare December 1, 2023 15:40
@ryancurrah
Copy link
Contributor Author

ryancurrah commented Dec 1, 2023

Fixed incorrect protobuf struct tag options 37958b8.

Though these types should be auto generated, not doing so makes modifications error prone.

@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch from 132bc9c to 964d305 Compare December 15, 2023 21:30
@ryancurrah ryancurrah marked this pull request as ready for review December 15, 2023 21:31
@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch from 964d305 to 818996b Compare December 15, 2023 21:32
@ryancurrah
Copy link
Contributor Author

@daniel-codefresh this is ready for review.

@ryancurrah
Copy link
Contributor Author

Hey @daniel-codefresh I hope you had a great holidays and happy new year. I am wondering if you would be able to review this?

@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch from 14187f8 to a81564e Compare January 16, 2024 14:26
@ryancurrah
Copy link
Contributor Author

Is anyone available to review this @whynowy?

@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch 4 times, most recently from 5843a9c to b0ed545 Compare January 20, 2024 15:06
@@ -32,6 +32,9 @@ type WebhookContext struct {
// Default value: 1048576 (1MB).
// +optional
MaxPayloadSize *int64 `json:"maxPayloadSize,omitempty" protobuf:"bytes,9,opt,name=maxPayloadSize"`
// CheckInterval is a duration in which to wait before checking that the webhooks exist, e.g. 1s, 30m, 2h... (defaults to 1m)
// +optional
CheckInterval string `json:"checkInterval" protobuf:"bytes,10,opt,name=checkInterval"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use *metav1.Duration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it but I get this error when running make codegen.

The swagger spec at "api/openapi-spec/swagger.json" is invalid against swagger specification 2.0.
See errors below:
- some references could not be resolved in spec. First found: object has no key "io.k8s.apimachinery.pkg.apis.meta.v1.Duration"

I was copying an existing duration example from here, as I did not see any uses of a Duration type, probably for this reason maybe?

CheckInterval string `json:"checkInterval,omitempty" protobuf:"bytes,3,opt,name=checkInterval"`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can fix this later.

Just realized it's added to the generic WebhookContext, which is used by many event sources. This is not right, please move to bigbuckets specific types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, I will move this.

if err != nil {
return fmt.Errorf("failed to get bitbucketserver token. err: %w", err)
}
if !bitbucketserverEventSource.DeleteHookOnFinish && len(router.hookIDs) == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning early to make the code more readable by removing a level of nesting. I should split this up into two if statements though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done. ✅

ctx, cancel := context.WithCancel(ctx)
defer cancel()

bitbucketClient := newBitbucketServerClient(ctx, bitbucketConfig, bitbucketToken)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ctx will be cancelled when this function exits, will the bitbucketConfig still be able to used for delete the webhook?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I created a second client that will be used by PostInactivate. I also ensured that the customClient uses the ctx.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, I don't think this is a good approach, maybe just extract the way to get a client to a function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your instructions aren't clear here. I will take a second look though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this again, I feel this is the right approach using a separate instance of the bitbucket client for deleting which does not use the canceled context and adding the bitbucket clients to the Router struct which can be accessed by the different functions is a common approach to using clients.

Copy link
Contributor Author

@ryancurrah ryancurrah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes pushed and responded to comments. Thanks for reviewing.

if err != nil {
return fmt.Errorf("failed to get bitbucketserver token. err: %w", err)
}
if !bitbucketserverEventSource.DeleteHookOnFinish && len(router.hookIDs) == 0 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning early to make the code more readable by removing a level of nesting. I should split this up into two if statements though.

ctx, cancel := context.WithCancel(ctx)
defer cancel()

bitbucketClient := newBitbucketServerClient(ctx, bitbucketConfig, bitbucketToken)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I created a second client that will be used by PostInactivate. I also ensured that the customClient uses the ctx.

@@ -32,6 +32,9 @@ type WebhookContext struct {
// Default value: 1048576 (1MB).
// +optional
MaxPayloadSize *int64 `json:"maxPayloadSize,omitempty" protobuf:"bytes,9,opt,name=maxPayloadSize"`
// CheckInterval is a duration in which to wait before checking that the webhooks exist, e.g. 1s, 30m, 2h... (defaults to 1m)
// +optional
CheckInterval string `json:"checkInterval" protobuf:"bytes,10,opt,name=checkInterval"`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it but I get this error when running make codegen.

The swagger spec at "api/openapi-spec/swagger.json" is invalid against swagger specification 2.0.
See errors below:
- some references could not be resolved in spec. First found: object has no key "io.k8s.apimachinery.pkg.apis.meta.v1.Duration"

I was copying an existing duration example from here, as I did not see any uses of a Duration type, probably for this reason maybe?

CheckInterval string `json:"checkInterval,omitempty" protobuf:"bytes,3,opt,name=checkInterval"`

@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch 2 times, most recently from 2f216ee to fa58b2d Compare January 27, 2024 16:49
@ryancurrah
Copy link
Contributor Author

@whynowy this is ready for review again.

@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch from fa58b2d to b8338ad Compare February 1, 2024 18:58
@@ -32,6 +32,9 @@ type WebhookContext struct {
// Default value: 1048576 (1MB).
// +optional
MaxPayloadSize *int64 `json:"maxPayloadSize,omitempty" protobuf:"bytes,9,opt,name=maxPayloadSize"`
// CheckInterval is a duration in which to wait before checking that the webhooks exist, e.g. 1s, 30m, 2h... (defaults to 1m)
// +optional
CheckInterval string `json:"checkInterval" protobuf:"bytes,10,opt,name=checkInterval"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can fix this later.

Just realized it's added to the generic WebhookContext, which is used by many event sources. This is not right, please move to bigbuckets specific types.

@@ -93,6 +98,40 @@ func (router *Router) HandleRoute(writer http.ResponseWriter, request *http.Requ
return
}

// When SkipBranchRefsChangedOnOpenPR is enabled and webhook event type is repo:refs_changed,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there so specific logic hardcoded?

If there's a requirement like you mentioned in the PR description, instead of doing this, you can use filter feature in the Sensor take the events you are interested.

Copy link
Contributor Author

@ryancurrah ryancurrah Feb 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I met with Pipekit folks about this and we determined that a filter would not work, because of the API call and self-signed certificate required. This addition goes a long way for Argo to replace the multibranch pipeline in Jenkins, also note that this behaviour is opt-in not opt-out so they have to specifically enable it.

ctx, cancel := context.WithCancel(ctx)
defer cancel()

bitbucketClient := newBitbucketServerClient(ctx, bitbucketConfig, bitbucketToken)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, I don't think this is a good approach, maybe just extract the way to get a client to a function?

@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch 2 times, most recently from 4a7608b to 7886c94 Compare February 16, 2024 18:44
Copy link
Member

@whynowy whynowy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the conflict.

@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch 2 times, most recently from c53f9d4 to 63d9a44 Compare February 19, 2024 15:43
@ryancurrah
Copy link
Contributor Author

Please fix the conflict.

Done and also squashed commits for a clean merge.

@ryancurrah
Copy link
Contributor Author

@whynowy hoping this gets merged before another conflict in go.mod.

@whynowy
Copy link
Member

whynowy commented Feb 25, 2024

Please fix the conflict.

Done and also squashed commits for a clean merge.

Sorry, you have to do it again... Ping me on slack after you do it.

…t source

This Pull Request contains 3 improvements to the Bitbucket Server Event source.

1. Customizable Apply Webhook Check Interval

Currently the apply webhook check runs every 60 seconds which could be to often. This is now configurable.

2. Manage Webhooks for Entire Projects

When a list of Bitbucket Server Projects are provided the event source will ensure a webhook exists in all repositories in the provided project.

3. Ability to Skip Refs Changed when a Pull Request is Open

A new option has been added that adds a check when a wehook is received, when a repo:refs_changed event is received a check will be ran to skip publishing the event if a Pull Request is opened. This is to get around the issue that Bitbucket will send this event even when a Pull Request is opened and there is already a pr:from_ref_updated event that would launch multiple workflow. This allows us to have a branch, pull request and tag workflows.

Signed-off-by: Ryan Currah <[email protected]>
@ryancurrah ryancurrah force-pushed the multiple-improvements-to-the-bitbucket-server-eventsource branch from 63d9a44 to 58fa25b Compare February 25, 2024 17:31
@whynowy whynowy merged commit 8cbbbef into argoproj:master Feb 25, 2024
8 checks passed
@ryancurrah ryancurrah deleted the multiple-improvements-to-the-bitbucket-server-eventsource branch February 25, 2024 17:53
@tooptoop4
Copy link
Contributor

when dis bad boy gonna be released?

whynowy pushed a commit that referenced this pull request Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants