[Integration][GitHub] Add skipWebhookManagement config#3156
[Integration][GitHub] Add skipWebhookManagement config#3156jasonnwakaeze-debug wants to merge 9 commits intomainfrom
Conversation
Review Summary by QodoAdd skipWebhookManagement config to GitHub integration
WalkthroughsDescription• Add skipWebhookManagement config to disable automatic webhook creation • Implement early return in on_start() when flag is enabled • Add comprehensive test coverage for webhook management skip logic • Update changelog and integration spec documentation Diagramflowchart LR
A["Integration startup"] --> B{"skipWebhookManagement<br/>enabled?"}
B -->|Yes| C["Skip webhook creation<br/>and patching"]
B -->|No| D["Proceed with webhook<br/>management"]
C --> E["Return early"]
D --> F["Create/update webhooks"]
File Changes1. integrations/github/main.py
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
Pull request overview
Adds a new configuration flag to allow the GitHub integration to skip webhook creation/patching during startup, preventing unintended webhook secret updates when customers opt out of webhook secret verification.
Changes:
- Added
skipWebhookManagementconfig option to the integration spec (defaultfalse). - Updated startup flow (
on_start) to return early when webhook management is skipped. - Added tests covering the new skip behavior and updated changelog entry.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| integrations/github/main.py | Adds an early-exit in on_start() when webhook management is disabled via config. |
| integrations/github/.port/spec.yaml | Introduces skipWebhookManagement boolean configuration option. |
| integrations/github/tests/github/webhook/test_skip_webhook_management.py | Adds unit tests to verify webhook creation is skipped/enabled based on the flag. |
| integrations/github/CHANGELOG.md | Documents the new configuration option in release notes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| self, mock_ocean_context: Any | ||
| ) -> None: | ||
| ocean.integration_config["skip_webhook_management"] = True | ||
| ocean.app.config.event_listener.should_process_webhooks = True | ||
|
|
||
| mock_create = AsyncMock() | ||
| with patch("main._create_webhooks_for_organization", mock_create): | ||
| import main # noqa: F401 — triggers @ocean.on_start() registration | ||
|
|
||
| await _get_on_start_fn()() | ||
|
|
||
| mock_create.assert_not_called() | ||
| ocean.integration_config.pop("skip_webhook_management", None) | ||
|
|
||
| async def test_on_start_proceeds_when_flag_not_set( | ||
| self, mock_ocean_context: Any | ||
| ) -> None: | ||
| ocean.integration_config.pop("skip_webhook_management", None) | ||
| ocean.app.config.event_listener.should_process_webhooks = True | ||
|
|
||
| mock_create = AsyncMock() | ||
| with patch("main._create_webhooks_for_organization", mock_create): | ||
| import main # noqa: F401 | ||
|
|
||
| await _get_on_start_fn()() | ||
|
|
||
| mock_create.assert_called_once() |
There was a problem hiding this comment.
The test mutates global ocean.integration_config and cleans it up only at the end of the test body. If an assertion fails (or an exception occurs before cleanup), skip_webhook_management can leak into subsequent tests and change their behavior. Use monkeypatch/try...finally (or a fixture) to guarantee cleanup, and consider resetting ocean.app.integration.on_start's mock call history to keep the test isolated.
| self, mock_ocean_context: Any | |
| ) -> None: | |
| ocean.integration_config["skip_webhook_management"] = True | |
| ocean.app.config.event_listener.should_process_webhooks = True | |
| mock_create = AsyncMock() | |
| with patch("main._create_webhooks_for_organization", mock_create): | |
| import main # noqa: F401 — triggers @ocean.on_start() registration | |
| await _get_on_start_fn()() | |
| mock_create.assert_not_called() | |
| ocean.integration_config.pop("skip_webhook_management", None) | |
| async def test_on_start_proceeds_when_flag_not_set( | |
| self, mock_ocean_context: Any | |
| ) -> None: | |
| ocean.integration_config.pop("skip_webhook_management", None) | |
| ocean.app.config.event_listener.should_process_webhooks = True | |
| mock_create = AsyncMock() | |
| with patch("main._create_webhooks_for_organization", mock_create): | |
| import main # noqa: F401 | |
| await _get_on_start_fn()() | |
| mock_create.assert_called_once() | |
| self, mock_ocean_context: Any, monkeypatch: pytest.MonkeyPatch | |
| ) -> None: | |
| monkeypatch.setitem(ocean.integration_config, "skip_webhook_management", True) | |
| monkeypatch.setattr( | |
| ocean.app.config.event_listener, "should_process_webhooks", True | |
| ) | |
| mock_create = AsyncMock() | |
| try: | |
| with patch("main._create_webhooks_for_organization", mock_create): | |
| import main # noqa: F401 — triggers @ocean.on_start() registration | |
| await _get_on_start_fn()() | |
| mock_create.assert_not_called() | |
| finally: | |
| ocean.app.integration.on_start.reset_mock() # type: ignore[attr-defined] | |
| async def test_on_start_proceeds_when_flag_not_set( | |
| self, mock_ocean_context: Any, monkeypatch: pytest.MonkeyPatch | |
| ) -> None: | |
| monkeypatch.delitem( | |
| ocean.integration_config, "skip_webhook_management", raising=False | |
| ) | |
| monkeypatch.setattr( | |
| ocean.app.config.event_listener, "should_process_webhooks", True | |
| ) | |
| mock_create = AsyncMock() | |
| try: | |
| with patch("main._create_webhooks_for_organization", mock_create): | |
| import main # noqa: F401 | |
| await _get_on_start_fn()() | |
| mock_create.assert_called_once() | |
| finally: | |
| ocean.app.integration.on_start.reset_mock() # type: ignore[attr-defined] |
| ocean.integration_config.pop("skip_webhook_management", None) | ||
| ocean.app.config.event_listener.should_process_webhooks = True | ||
|
|
||
| mock_create = AsyncMock() | ||
| with patch("main._create_webhooks_for_organization", mock_create): | ||
| import main # noqa: F401 | ||
|
|
||
| await _get_on_start_fn()() | ||
|
|
||
| mock_create.assert_called_once() |
There was a problem hiding this comment.
This test relies on a previously-registered @ocean.on_start() function via ocean.app.integration.on_start.call_args. Since main is imported only once per test worker, the registration and mock call history can be influenced by earlier tests/imports. To make this deterministic, reset the on_start mock and/or importlib.reload(main) before extracting the registered function.
| ### Features | ||
|
|
||
| - Bumped ocean version to ^0.41.4 | ||
| - Added `skipWebhookManagement` configuration option to disable automatic webhook creation and patching. |
There was a problem hiding this comment.
Trailing whitespace at the end of this changelog bullet can cause noisy diffs and may trip markdown/style tooling. Remove the extra space after the period.
| - Added `skipWebhookManagement` configuration option to disable automatic webhook creation and patching. | |
| - Added `skipWebhookManagement` configuration option to disable automatic webhook creation and patching. |
mk-armah
left a comment
There was a problem hiding this comment.
The goal is to skip webhook patching ...
There was a problem hiding this comment.
- Its overwritting existing
- Its an improvement not a feature
Co-authored-by: Michael Kofi Armah <mikeyarmah@gmail.com>
Co-authored-by: Michael Kofi Armah <mikeyarmah@gmail.com>
Description
What -
New boolean config skipWebhookManagement (default false). When enabled, the integration skips all webhook creation and patching on GitHub during startup. This lets customers remove webhookSecret (so the integration skips HMAC verification) without the side effect of the integration stripping the secret from the org webhook.
Why -
How -
Type of change
Please leave one option from the following and delete the rest:
All tests should be run against the port production environment(using a testing org).
Core testing checklist
Integration testing checklist
examplesfolder in the integration directory.Preflight checklist
Screenshots
Include screenshots from your environment showing how the resources of the integration will look.
API Documentation
Provide links to the API documentation used for this integration.