snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
This commit is contained in:
0
zerver/webhooks/gocd/__init__.py
Normal file
0
zerver/webhooks/gocd/__init__.py
Normal file
39
zerver/webhooks/gocd/doc.md
Normal file
39
zerver/webhooks/gocd/doc.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Zulip GoCD integration
|
||||
|
||||
Get GoCD notifications in Zulip!
|
||||
|
||||
{start_tabs}
|
||||
|
||||
1. {!create-an-incoming-webhook.md!}
|
||||
|
||||
1. {!generate-webhook-url-basic.md!}
|
||||
|
||||
1. [Download][1] and [install][2] Sentry's **GoCD WebHook Notification
|
||||
plugin**.
|
||||
|
||||
!!! warn ""
|
||||
|
||||
**Note**: the GoCD WebHook Notification plugin will only send
|
||||
webhook payloads over HTTPS.
|
||||
|
||||
1. In your GoCD server, go to **Admin > Server Configuration > Plugins**,
|
||||
and click on the gear icon beside the **GoCD WebHook Notification
|
||||
plugin** that you installed.
|
||||
|
||||
1. Set **WebHook URL** to the URL generated above, and click **Save**.
|
||||
|
||||
{end_tabs}
|
||||
|
||||
{!congrats.md!}
|
||||
|
||||

|
||||
|
||||
### Related Branches
|
||||
|
||||
- [GoCD plugin user guide][3]
|
||||
|
||||
{!webhooks-url-specification.md!}
|
||||
|
||||
[1]: https://github.com/getsentry/gocd-webhook-notification-plugin/releases
|
||||
[2]: https://docs.gocd.org/current/extension_points/plugin_user_guide.html#installing-and-uninstalling-of-plugins
|
||||
[3]: https://docs.gocd.org/current/extension_points/plugin_user_guide.html
|
||||
47
zerver/webhooks/gocd/fixtures/pipeline_building.json
Normal file
47
zerver/webhooks/gocd/fixtures/pipeline_building.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"data": {
|
||||
"pipeline": {
|
||||
"name": "Pipeline",
|
||||
"counter": "90",
|
||||
"group": "defaultGroup",
|
||||
"build-cause": [
|
||||
{
|
||||
"material": {
|
||||
"git-configuration": {
|
||||
"shallow-clone": false,
|
||||
"branch": "main",
|
||||
"url": "https://github.com/swayam0322/Test"
|
||||
},
|
||||
"type": "git"
|
||||
},
|
||||
"changed": false,
|
||||
"modifications": [
|
||||
{
|
||||
"revision": "59f3c6e4540b6a89ad5505790e5efdf964e7b837",
|
||||
"modified-time": "Jan 31, 2024, 1:56:14 AM",
|
||||
"data": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"stage": {
|
||||
"name": "Stage",
|
||||
"counter": "1",
|
||||
"approval-type": "success",
|
||||
"approved-by": "anonymous",
|
||||
"state": "Building",
|
||||
"result": "Unknown",
|
||||
"create-time": "Feb 1, 2024, 1:58:13 AM",
|
||||
"jobs": [
|
||||
{
|
||||
"name": "Job",
|
||||
"schedule-time": "Feb 1, 2024, 1:58:13 AM",
|
||||
"state": "Scheduled",
|
||||
"result": "Unknown"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "stage"
|
||||
}
|
||||
50
zerver/webhooks/gocd/fixtures/pipeline_failed.json
Normal file
50
zerver/webhooks/gocd/fixtures/pipeline_failed.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"data": {
|
||||
"pipeline": {
|
||||
"name": "pipeline-one",
|
||||
"counter": "7",
|
||||
"group": "defaultGroup",
|
||||
"build-cause": [
|
||||
{
|
||||
"material": {
|
||||
"git-configuration": {
|
||||
"shallow-clone": false,
|
||||
"branch": "master",
|
||||
"url": "https://github.com/PieterCK/getting-started-repo.git"
|
||||
},
|
||||
"type": "git"
|
||||
},
|
||||
"changed": false,
|
||||
"modifications": [
|
||||
{
|
||||
"revision": "963eb239c7b91eac2e15c727e06e908fd334e6f9",
|
||||
"modified-time": "Dec 14, 2016, 5:09:14 AM",
|
||||
"data": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"stage": {
|
||||
"name": "stage-two",
|
||||
"counter": "1",
|
||||
"approval-type": "success",
|
||||
"approved-by": "anonymous",
|
||||
"state": "Failed",
|
||||
"result": "Failed",
|
||||
"create-time": "Aug 28, 2024, 9:30:19 PM",
|
||||
"last-transition-time": "Aug 28, 2024, 9:31:00 PM",
|
||||
"jobs": [
|
||||
{
|
||||
"name": "task-two",
|
||||
"schedule-time": "Aug 28, 2024, 9:30:19 PM",
|
||||
"complete-time": "Aug 28, 2024, 9:31:00 PM",
|
||||
"state": "Completed",
|
||||
"result": "Failed",
|
||||
"agent-uuid": "a35cf64c-7746-46ae-ba65-597d70898d50"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "stage"
|
||||
}
|
||||
50
zerver/webhooks/gocd/fixtures/pipeline_passed.json
Normal file
50
zerver/webhooks/gocd/fixtures/pipeline_passed.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"data": {
|
||||
"pipeline": {
|
||||
"name": "Pipeline",
|
||||
"counter": "90",
|
||||
"group": "defaultGroup",
|
||||
"build-cause": [
|
||||
{
|
||||
"material": {
|
||||
"git-configuration": {
|
||||
"shallow-clone": false,
|
||||
"branch": "main",
|
||||
"url": "https://github.com/swayam0322/Test"
|
||||
},
|
||||
"type": "git"
|
||||
},
|
||||
"changed": false,
|
||||
"modifications": [
|
||||
{
|
||||
"revision": "59f3c6e4540b6a89ad5505790e5efdf964e7b837",
|
||||
"modified-time": "Jan 31, 2024, 1:56:14 AM",
|
||||
"data": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"stage": {
|
||||
"name": "Stage",
|
||||
"counter": "1",
|
||||
"approval-type": "success",
|
||||
"approved-by": "anonymous",
|
||||
"state": "Passed",
|
||||
"result": "Passed",
|
||||
"create-time": "Feb 1, 2024, 1:58:13 AM",
|
||||
"last-transition-time": "Feb 1, 2024, 1:58:40 AM",
|
||||
"jobs": [
|
||||
{
|
||||
"name": "Job",
|
||||
"schedule-time": "Feb 1, 2024, 1:58:13 AM",
|
||||
"complete-time": "Feb 1, 2024, 1:58:40 AM",
|
||||
"state": "Completed",
|
||||
"result": "Passed",
|
||||
"agent-uuid": "95dde0d9-8da7-48ae-8572-5c7de18bff88"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "stage"
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
{
|
||||
"data": {
|
||||
"pipeline": {
|
||||
"name": "test-pipeline",
|
||||
"counter": "6",
|
||||
"group": "defaultGroup",
|
||||
"build-cause": [
|
||||
{
|
||||
"material": {
|
||||
"git-configuration": {
|
||||
"shallow-clone": false,
|
||||
"branch": "master",
|
||||
"url": "https://github.com/PieterCK/getting-started-repo.git"
|
||||
},
|
||||
"type": "git"
|
||||
},
|
||||
"changed": false,
|
||||
"modifications": [
|
||||
{
|
||||
"revision": "963eb239c7b91eac2e15c727e06e908fd334e6f9",
|
||||
"modified-time": "Dec 14, 2016, 5:09:14 AM",
|
||||
"data": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"stage": {
|
||||
"name": "backend-tests",
|
||||
"counter": "1",
|
||||
"approval-type": "success",
|
||||
"approved-by": "changes",
|
||||
"state": "Failed",
|
||||
"result": "Failed",
|
||||
"create-time": "Aug 29, 2024, 3:59:18 PM",
|
||||
"last-transition-time": "Aug 29, 2024, 4:00:15 PM",
|
||||
"jobs": [
|
||||
{
|
||||
"name": "check-backend-lints",
|
||||
"schedule-time": "Aug 29, 2024, 3:59:18 PM",
|
||||
"complete-time": "Aug 29, 2024, 3:59:23 PM",
|
||||
"state": "Completed",
|
||||
"result": "Failed",
|
||||
"agent-uuid": "a35cf64c-7746-46ae-ba65-597d70898d50"
|
||||
},
|
||||
{
|
||||
"name": "check-backend-tests",
|
||||
"schedule-time": "Aug 29, 2024, 3:59:18 PM",
|
||||
"complete-time": "Aug 29, 2024, 3:59:47 PM",
|
||||
"state": "Completed",
|
||||
"result": "Passed",
|
||||
"agent-uuid": "a35cf64c-7746-46ae-ba65-597d70898d50"
|
||||
},
|
||||
{
|
||||
"name": "test-frontend-js",
|
||||
"schedule-time": "Aug 29, 2024, 3:59:18 PM",
|
||||
"complete-time": "Aug 29, 2024, 4:00:15 PM",
|
||||
"state": "Completed",
|
||||
"result": "Failed",
|
||||
"agent-uuid": "a35cf64c-7746-46ae-ba65-597d70898d50"
|
||||
},
|
||||
{
|
||||
"name": "zulip-ci-debian-12",
|
||||
"schedule-time": "Aug 29, 2024, 3:59:18 PM",
|
||||
"complete-time": "Aug 29, 2024, 4:00:11 PM",
|
||||
"state": "Completed",
|
||||
"result": "Passed",
|
||||
"agent-uuid": "a35cf64c-7746-46ae-ba65-597d70898d50"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "stage"
|
||||
}
|
||||
44
zerver/webhooks/gocd/tests.py
Normal file
44
zerver/webhooks/gocd/tests.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from zerver.lib.test_classes import WebhookTestCase
|
||||
|
||||
|
||||
class GocdHookTests(WebhookTestCase):
|
||||
def test_building_pipeline(self) -> None:
|
||||
expected_topic = "Pipeline / Stage"
|
||||
expected_message = """**Pipeline building**: Pipeline / Stage
|
||||
- **Commit**: [`59f3c6e4540`](https://github.com/swayam0322/Test/commit/59f3c6e4540) on branch `main`
|
||||
- **Started**: <time:Feb 1, 2024, 1:58:13 AM>"""
|
||||
|
||||
self.check_webhook(
|
||||
"pipeline_building",
|
||||
expected_topic,
|
||||
expected_message,
|
||||
)
|
||||
|
||||
def test_completed_pipeline_success(self) -> None:
|
||||
expected_topic = "Pipeline / Stage"
|
||||
expected_message = """:green_circle: **Build passed**: Pipeline / Stage
|
||||
- **Commit**: [`59f3c6e4540`](https://github.com/swayam0322/Test/commit/59f3c6e4540) on branch `main`
|
||||
- **Started**: <time:Feb 1, 2024, 1:58:13 AM>
|
||||
- **Finished**: <time:Feb 1, 2024, 1:58:40 AM>
|
||||
- **Passed**: `Job`"""
|
||||
|
||||
self.check_webhook("pipeline_passed", expected_topic, expected_message)
|
||||
|
||||
def test_completed_pipeline_fail(self) -> None:
|
||||
expected_topic = "pipeline-one / stage-two"
|
||||
expected_message = """:red_circle: **Build failed**: pipeline-one / stage-two
|
||||
- **Commit**: [`963eb239c7b`](https://github.com/PieterCK/getting-started-repo.git/commit/963eb239c7b) on branch `master`
|
||||
- **Started**: <time:Aug 28, 2024, 9:30:19 PM>
|
||||
- **Finished**: <time:Aug 28, 2024, 9:31:00 PM>
|
||||
- **Failed**: `task-two`"""
|
||||
self.check_webhook("pipeline_failed", expected_topic, expected_message)
|
||||
|
||||
def test_completed_pipeline_with_mixed_result(self) -> None:
|
||||
expected_topic = "test-pipeline / backend-tests"
|
||||
expected_message = """:red_circle: **Build failed**: test-pipeline / backend-tests
|
||||
- **Commit**: [`963eb239c7b`](https://github.com/PieterCK/getting-started-repo.git/commit/963eb239c7b) on branch `master`
|
||||
- **Started**: <time:Aug 29, 2024, 3:59:18 PM>
|
||||
- **Finished**: <time:Aug 29, 2024, 4:00:15 PM>
|
||||
- **Failed**: `check-backend-lints`, `test-frontend-js`
|
||||
- **Passed**: `check-backend-tests`, `zulip-ci-debian-12`"""
|
||||
self.check_webhook("pipeline_with_mixed_job_result", expected_topic, expected_message)
|
||||
111
zerver/webhooks/gocd/view.py
Normal file
111
zerver/webhooks/gocd/view.py
Normal file
@@ -0,0 +1,111 @@
|
||||
# Webhooks for external integrations.
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
from zerver.decorator import webhook_view
|
||||
from zerver.lib.response import json_success
|
||||
from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint
|
||||
from zerver.lib.validator import WildValue, check_string
|
||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||
from zerver.lib.webhooks.git import get_short_sha
|
||||
from zerver.models import UserProfile
|
||||
|
||||
COMMIT_INFO_TEMPLATE = """[`{commit_details}`]({commit_link}) on branch `{branch_name}`"""
|
||||
TOPIC_TEMPLATE = "{pipeline} / {stage}"
|
||||
|
||||
SCHEDULED_BODY_TEMPLATE = """
|
||||
**Pipeline {status}**: {pipeline} / {stage}
|
||||
- **Commit**: {commit_details}
|
||||
- **Started**: <time:{start_time}>
|
||||
"""
|
||||
|
||||
COMPLETED_BODY_TEMPLATE = """
|
||||
{emoji} **Build {status}**: {pipeline} / {stage}
|
||||
- **Commit**: {commit_details}
|
||||
- **Started**: <time:{start_time}>
|
||||
- **Finished**: <time:{end_time}>
|
||||
"""
|
||||
|
||||
|
||||
@webhook_view("Gocd")
|
||||
@typed_endpoint
|
||||
def api_gocd_webhook(
|
||||
request: HttpRequest,
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
) -> HttpResponse:
|
||||
type = payload["type"].tame(check_string)
|
||||
if type == "stage":
|
||||
body = get_body(payload)
|
||||
topic_name = get_topic(payload)
|
||||
check_send_webhook_message(request, user_profile, topic_name, body)
|
||||
return json_success(request)
|
||||
|
||||
|
||||
def get_topic(payload: WildValue) -> str:
|
||||
return TOPIC_TEMPLATE.format(
|
||||
pipeline=payload["data"]["pipeline"]["name"].tame(check_string),
|
||||
stage=payload["data"]["pipeline"]["stage"]["name"].tame(check_string),
|
||||
)
|
||||
|
||||
|
||||
def get_commit_details(payload: WildValue) -> str:
|
||||
build = payload["data"]["pipeline"]["build-cause"][0]
|
||||
material = build["material"]
|
||||
url_base = material["git-configuration"]["url"].tame(check_string)
|
||||
revision = build["modifications"][0]["revision"].tame(check_string)
|
||||
commit_sha = get_short_sha(revision)
|
||||
url = f"{url_base}/commit/{commit_sha}"
|
||||
branch = material["git-configuration"]["branch"].tame(check_string)
|
||||
return COMMIT_INFO_TEMPLATE.format(
|
||||
commit_details=commit_sha,
|
||||
commit_link=url,
|
||||
branch_name=branch,
|
||||
)
|
||||
|
||||
|
||||
def get_jobs_details(pipeline_data: WildValue) -> str:
|
||||
job_dict_list = pipeline_data["stage"]["jobs"]
|
||||
formatted_job_dict = defaultdict(list)
|
||||
job_details_template = ""
|
||||
|
||||
for job in job_dict_list:
|
||||
job_name = job["name"].tame(check_string)
|
||||
job_result = job["result"].tame(check_string)
|
||||
formatted_job_dict[job_result].append(f"`{job_name}`")
|
||||
|
||||
for key in formatted_job_dict:
|
||||
formatted_job_list = ", ".join(formatted_job_dict[key])
|
||||
job_details_template += f"- **{key}**: {formatted_job_list}\n"
|
||||
|
||||
return job_details_template
|
||||
|
||||
|
||||
def get_body(payload: WildValue) -> str:
|
||||
pipeline_data = payload["data"]["pipeline"]
|
||||
body_details = {
|
||||
"commit_details": get_commit_details(payload),
|
||||
"status": pipeline_data["stage"]["state"].tame(check_string).lower(),
|
||||
"pipeline": pipeline_data["name"].tame(check_string),
|
||||
"stage": pipeline_data["stage"]["name"].tame(check_string),
|
||||
"start_time": pipeline_data["stage"]["create-time"].tame(check_string),
|
||||
}
|
||||
|
||||
if body_details["status"] == "building":
|
||||
return SCHEDULED_BODY_TEMPLATE.format(**body_details)
|
||||
|
||||
result = pipeline_data["stage"]["result"].tame(check_string)
|
||||
body_details.update(
|
||||
{
|
||||
"result": result,
|
||||
"emoji": ":green_circle:" if result == "Passed" else ":red_circle:",
|
||||
"end_time": pipeline_data["stage"]["last-transition-time"].tame(check_string),
|
||||
}
|
||||
)
|
||||
body = COMPLETED_BODY_TEMPLATE.format(**body_details)
|
||||
|
||||
body += get_jobs_details(pipeline_data)
|
||||
return body
|
||||
Reference in New Issue
Block a user