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/rhodecode/__init__.py
Normal file
0
zerver/webhooks/rhodecode/__init__.py
Normal file
29
zerver/webhooks/rhodecode/doc.md
Normal file
29
zerver/webhooks/rhodecode/doc.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Zulip RhodeCode integration
|
||||
|
||||
Get RhodeCode notifications in Zulip!
|
||||
|
||||
{start_tabs}
|
||||
|
||||
1. {!create-an-incoming-webhook.md!}
|
||||
|
||||
1. {!generate-webhook-url-with-branch-filtering.md!}
|
||||
|
||||
1. From your repository on RhodeCode, open the **Repository Settings** tab.
|
||||
Select **Integrations**, click on **Create new integration**, and
|
||||
select **Webhook**.
|
||||
|
||||
1. Set **Webhook URL** to the URL generated above. Select the
|
||||
[events](#filtering-incoming-events) you would like to receive notifications
|
||||
for, and click **Submit**.
|
||||
|
||||
{end_tabs}
|
||||
|
||||
{!congrats.md!}
|
||||
|
||||

|
||||
|
||||
{!event-filtering-additional-feature.md!}
|
||||
|
||||
### Related documentation
|
||||
|
||||
{!webhooks-url-specification.md!}
|
||||
61
zerver/webhooks/rhodecode/fixtures/push.json
Normal file
61
zerver/webhooks/rhodecode/fixtures/push.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"event": {
|
||||
"repo": {
|
||||
"repo_name": "u/yuroitaki/zulip-testing",
|
||||
"permalink_url": "https://code.rhodecode.com/_1936",
|
||||
"repo_type": "git",
|
||||
"extra_fields": {},
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing",
|
||||
"repo_id": 1936
|
||||
},
|
||||
"actor_ip": "14.192.208.163",
|
||||
"utc_timestamp": "2022-06-26T10:14:12.449",
|
||||
"name": "repo-push",
|
||||
"actor": {
|
||||
"user_id": 2263,
|
||||
"username": "yuroitaki"
|
||||
},
|
||||
"push": {
|
||||
"issues": {},
|
||||
"commits": [
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "3d6c5671a9b74b34d21b7b545f19ae7e9553a75a"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Modify README",
|
||||
"raw_id": "2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c",
|
||||
"author": "Yuro Itaki <yuroitaki@email.com>",
|
||||
"short_id": "2b8c0ebf5071",
|
||||
"branch": "master",
|
||||
"revision": 1,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c",
|
||||
"message_html": "Modify README\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c",
|
||||
"message": "Modify README\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": [
|
||||
"master"
|
||||
]
|
||||
},
|
||||
"date": "2022-06-26T10:14:05",
|
||||
"reviewers": []
|
||||
}
|
||||
],
|
||||
"branches": [
|
||||
{
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changelog?branch=master",
|
||||
"name": "master"
|
||||
}
|
||||
],
|
||||
"tags": []
|
||||
},
|
||||
"server_url": "https://code.rhodecode.com"
|
||||
},
|
||||
"token": ""
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"event": {
|
||||
"repo": {
|
||||
"repo_name": "u/yuroitaki/zulip-testing",
|
||||
"permalink_url": "https://code.rhodecode.com/_1936",
|
||||
"repo_type": "git",
|
||||
"extra_fields": {},
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing",
|
||||
"repo_id": 1936
|
||||
},
|
||||
"actor_ip": "14.192.212.32",
|
||||
"utc_timestamp": "2022-07-10T08:07:32.747",
|
||||
"name": "repo-push",
|
||||
"actor": {
|
||||
"user_id": 2263,
|
||||
"username": "yuroitaki"
|
||||
},
|
||||
"push": {
|
||||
"issues": {},
|
||||
"commits": [],
|
||||
"branches": [
|
||||
{
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changelog?branch=dev",
|
||||
"name": "dev"
|
||||
}
|
||||
],
|
||||
"tags": []
|
||||
},
|
||||
"server_url": "https://code.rhodecode.com"
|
||||
},
|
||||
"token": ""
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"event": {
|
||||
"repo": {
|
||||
"repo_name": "u/yuroitaki/zulip-testing",
|
||||
"permalink_url": "https://code.rhodecode.com/_1936",
|
||||
"repo_type": "git",
|
||||
"extra_fields": {},
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing",
|
||||
"repo_id": 1936
|
||||
},
|
||||
"actor_ip": "14.192.212.32",
|
||||
"utc_timestamp": "2022-07-10T08:22:48.930",
|
||||
"name": "repo-push",
|
||||
"actor": {
|
||||
"user_id": 2263,
|
||||
"username": "yuroitaki"
|
||||
},
|
||||
"push": {
|
||||
"issues": {},
|
||||
"commits": [
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Add test.py",
|
||||
"raw_id": "b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"author": "Yuro Itaki <yuroitaki@email.com>",
|
||||
"short_id": "b0d892e1cdd4",
|
||||
"branch": "master",
|
||||
"revision": 2,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"message_html": "Add test.py\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"message": "Add test.py\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": []
|
||||
},
|
||||
"date": "2022-07-10T08:21:51",
|
||||
"reviewers": []
|
||||
},
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "b0d892e1cdd4236b1f74debca1772ea330ff5acd"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Modify test.py",
|
||||
"raw_id": "6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"author": "Itachi Sensei <itachisensei@email.com>",
|
||||
"short_id": "6dbae5f842f8",
|
||||
"branch": "master",
|
||||
"revision": 3,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message_html": "Modify test.py\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message": "Modify test.py\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": [
|
||||
"master"
|
||||
]
|
||||
},
|
||||
"date": "2022-07-10T08:22:42",
|
||||
"reviewers": []
|
||||
}
|
||||
],
|
||||
"branches": [
|
||||
{
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changelog?branch=master",
|
||||
"name": "master"
|
||||
}
|
||||
],
|
||||
"tags": []
|
||||
},
|
||||
"server_url": "https://code.rhodecode.com"
|
||||
},
|
||||
"token": ""
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
{
|
||||
"event": {
|
||||
"repo": {
|
||||
"repo_name": "u/yuroitaki/zulip-testing",
|
||||
"permalink_url": "https://code.rhodecode.com/_1936",
|
||||
"repo_type": "git",
|
||||
"extra_fields": {},
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing",
|
||||
"repo_id": 1936
|
||||
},
|
||||
"actor_ip": "14.192.212.32",
|
||||
"utc_timestamp": "2022-07-10T08:22:48.930",
|
||||
"name": "repo-push",
|
||||
"actor": {
|
||||
"user_id": 2263,
|
||||
"username": "yuroitaki"
|
||||
},
|
||||
"push": {
|
||||
"issues": {},
|
||||
"commits": [
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Add test.py",
|
||||
"raw_id": "b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"author": "Yuro Itaki <yuroitaki@email.com>",
|
||||
"short_id": "b0d892e1cdd4",
|
||||
"branch": "master",
|
||||
"revision": 2,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"message_html": "Add test.py\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"message": "Add test.py\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": []
|
||||
},
|
||||
"date": "2022-07-10T08:21:51",
|
||||
"reviewers": []
|
||||
},
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "b0d892e1cdd4236b1f74debca1772ea330ff5acd"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Modify test.py",
|
||||
"raw_id": "6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"author": "Itachi Sensei <itachisensei@email.com>",
|
||||
"short_id": "6dbae5f842f8",
|
||||
"branch": "master",
|
||||
"revision": 3,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message_html": "Modify test.py\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message": "Modify test.py\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": [
|
||||
"master"
|
||||
]
|
||||
},
|
||||
"date": "2022-07-10T08:22:42",
|
||||
"reviewers": []
|
||||
},
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "b0d892e1cdd4236b1f74debca1772ea330ff5acd"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Modify test.py",
|
||||
"raw_id": "6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"author": "Itachi Sensei <itachisensei@email.com>",
|
||||
"short_id": "6dbae5f842f8",
|
||||
"branch": "master",
|
||||
"revision": 3,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message_html": "Modify test.py\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message": "Modify test.py\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": [
|
||||
"master"
|
||||
]
|
||||
},
|
||||
"date": "2022-07-10T08:22:42",
|
||||
"reviewers": []
|
||||
},
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "b0d892e1cdd4236b1f74debca1772ea330ff5acd"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Modify test.py",
|
||||
"raw_id": "6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"author": "Jonas Nielsen <jonasnielsen@email.com>",
|
||||
"short_id": "6dbae5f842f8",
|
||||
"branch": "master",
|
||||
"revision": 3,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message_html": "Modify test.py\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message": "Modify test.py\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": [
|
||||
"master"
|
||||
]
|
||||
},
|
||||
"date": "2022-07-10T08:22:42",
|
||||
"reviewers": []
|
||||
},
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "b0d892e1cdd4236b1f74debca1772ea330ff5acd"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Modify test.py",
|
||||
"raw_id": "6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"author": "Lelouch Strange <lelouchstrange@email.com>",
|
||||
"short_id": "6dbae5f842f8",
|
||||
"branch": "master",
|
||||
"revision": 3,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message_html": "Modify test.py\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473",
|
||||
"message": "Modify test.py\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": [
|
||||
"master"
|
||||
]
|
||||
},
|
||||
"date": "2022-07-10T08:22:42",
|
||||
"reviewers": []
|
||||
},
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"raw_id": "2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c"
|
||||
}
|
||||
],
|
||||
"message_html_title": "Add test.py",
|
||||
"raw_id": "b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"author": "Yuro Itaki <yuroitaki@email.com>",
|
||||
"short_id": "b0d892e1cdd4",
|
||||
"branch": "master",
|
||||
"revision": 2,
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"message_html": "Add test.py\n",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd",
|
||||
"message": "Add test.py\n",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": []
|
||||
},
|
||||
"date": "2022-07-10T08:21:51",
|
||||
"reviewers": []
|
||||
}
|
||||
],
|
||||
"branches": [
|
||||
{
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changelog?branch=master",
|
||||
"name": "master"
|
||||
}
|
||||
],
|
||||
"tags": []
|
||||
},
|
||||
"server_url": "https://code.rhodecode.com"
|
||||
},
|
||||
"token": ""
|
||||
}
|
||||
49
zerver/webhooks/rhodecode/fixtures/push__remove_branch.json
Normal file
49
zerver/webhooks/rhodecode/fixtures/push__remove_branch.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"event": {
|
||||
"repo": {
|
||||
"repo_name": "u/yuroitaki/zulip-testing",
|
||||
"permalink_url": "https://code.rhodecode.com/_1936",
|
||||
"repo_type": "git",
|
||||
"extra_fields": {},
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing",
|
||||
"repo_id": 1936
|
||||
},
|
||||
"actor_ip": "14.192.212.32",
|
||||
"utc_timestamp": "2022-07-10T09:01:54.648",
|
||||
"name": "repo-push",
|
||||
"actor": {
|
||||
"user_id": 2263,
|
||||
"username": "yuroitaki"
|
||||
},
|
||||
"push": {
|
||||
"issues": {},
|
||||
"commits": [
|
||||
{
|
||||
"message_html_title": "Deleted branch dev",
|
||||
"raw_id": "delete_branch=>dev",
|
||||
"author": "Yuro Itaki <yuroitaki@email.com>",
|
||||
"reviewers": [],
|
||||
"branch": null,
|
||||
"short_id": "delete_branch=>dev",
|
||||
"permalink_url": "https://code.rhodecode.com/1936/changeset/delete_branch=%3Edev",
|
||||
"message_html": "Deleted branch dev",
|
||||
"mentions": [],
|
||||
"url": "https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/delete_branch=%3Edev",
|
||||
"message": "Deleted branch dev",
|
||||
"issues": [],
|
||||
"refs": {
|
||||
"tags": [],
|
||||
"bookmarks": [],
|
||||
"branches": []
|
||||
},
|
||||
"date": "2022-07-10T09:01:54.670",
|
||||
"git_ref_change": "branch_delete"
|
||||
}
|
||||
],
|
||||
"branches": [],
|
||||
"tags": []
|
||||
},
|
||||
"server_url": "https://code.rhodecode.com"
|
||||
},
|
||||
"token": ""
|
||||
}
|
||||
58
zerver/webhooks/rhodecode/tests.py
Normal file
58
zerver/webhooks/rhodecode/tests.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from zerver.lib.test_classes import WebhookTestCase
|
||||
from zerver.lib.webhooks.git import COMMITS_LIMIT
|
||||
|
||||
|
||||
class RhodecodeHookTests(WebhookTestCase):
|
||||
def test_push_event_message(self) -> None:
|
||||
expected_topic_name = "u/yuroitaki/zulip-testing / master"
|
||||
expected_message = "yuroitaki pushed 1 commit to branch master. Commits by Yuro Itaki <yuroitaki@email.com> (1).\n\n* Modify README ([2b8c0ebf507](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c))"
|
||||
self.check_webhook("push", expected_topic_name, expected_message)
|
||||
|
||||
def test_push_event_message_filtered_by_branches(self) -> None:
|
||||
self.url = self.build_webhook_url(branches="master,dev")
|
||||
expected_topic_name = "u/yuroitaki/zulip-testing / master"
|
||||
expected_message = "yuroitaki pushed 1 commit to branch master. Commits by Yuro Itaki <yuroitaki@email.com> (1).\n\n* Modify README ([2b8c0ebf507](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c))"
|
||||
self.check_webhook("push", expected_topic_name, expected_message)
|
||||
|
||||
@patch("zerver.lib.webhooks.common.check_send_webhook_message")
|
||||
def test_push_event_message_filtered_by_branches_ignore(
|
||||
self, check_send_webhook_message_mock: MagicMock
|
||||
) -> None:
|
||||
self.url = self.build_webhook_url(branches="development")
|
||||
payload = self.get_body("push")
|
||||
result = self.client_post(self.url, payload, content_type="application/json")
|
||||
self.assertFalse(check_send_webhook_message_mock.called)
|
||||
self.assert_json_success(result)
|
||||
|
||||
def test_push_local_branch_without_commits(self) -> None:
|
||||
expected_topic_name = "u/yuroitaki/zulip-testing / dev"
|
||||
expected_message = "yuroitaki pushed the branch dev."
|
||||
self.check_webhook(
|
||||
"push__local_branch_without_commits", expected_topic_name, expected_message
|
||||
)
|
||||
|
||||
def test_push_multiple_committers(self) -> None:
|
||||
expected_topic_name = "u/yuroitaki/zulip-testing / master"
|
||||
expected_message = "yuroitaki pushed 2 commits to branch master. Commits by Itachi Sensei <itachisensei@email.com> (1) and Yuro Itaki <yuroitaki@email.com> (1).\n\n* Add test.py ([b0d892e1cdd](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd))\n* Modify test.py ([6dbae5f842f](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473))"
|
||||
self.check_webhook("push__multiple_committers", expected_topic_name, expected_message)
|
||||
|
||||
def test_push_multiple_committers_with_others(self) -> None:
|
||||
expected_topic_name = "u/yuroitaki/zulip-testing / master"
|
||||
commits_info = "* Modify test.py ([6dbae5f842f](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/6dbae5f842f80ccb05508a1de7aace9d0f327473))\n"
|
||||
expected_message = f"yuroitaki pushed 6 commits to branch master. Commits by Itachi Sensei <itachisensei@email.com> (2), Yuro Itaki <yuroitaki@email.com> (2), Jonas Nielsen <jonasnielsen@email.com> (1) and others (1).\n\n* Add test.py ([b0d892e1cdd](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd))\n{commits_info * 4}* Add test.py ([b0d892e1cdd](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/b0d892e1cdd4236b1f74debca1772ea330ff5acd))"
|
||||
self.check_webhook(
|
||||
"push__multiple_committers_with_others", expected_topic_name, expected_message
|
||||
)
|
||||
|
||||
def test_push_commits_more_than_limit(self) -> None:
|
||||
expected_topic_name = "u/yuroitaki/zulip-testing / master"
|
||||
commits_info = "* Modify README ([2b8c0ebf507](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/2b8c0ebf50710bc2e1cdb6a33071dd2435ad667c))\n"
|
||||
expected_message = f"yuroitaki pushed 50 commits to branch master. Commits by Yuro Itaki <yuroitaki@email.com> (50).\n\n{commits_info * COMMITS_LIMIT}[and {50 - COMMITS_LIMIT} more commit(s)]"
|
||||
self.check_webhook("push__commits_more_than_limit", expected_topic_name, expected_message)
|
||||
|
||||
def test_push_remove_branch(self) -> None:
|
||||
expected_topic_name = "u/yuroitaki/zulip-testing / dev"
|
||||
expected_message = "yuroitaki pushed 1 commit to branch dev. Commits by Yuro Itaki <yuroitaki@email.com> (1).\n\n* Deleted branch dev ([delete_bran](https://code.rhodecode.com/u/yuroitaki/zulip-testing/changeset/delete_branch=%3Edev))"
|
||||
self.check_webhook("push__remove_branch", expected_topic_name, expected_message)
|
||||
101
zerver/webhooks/rhodecode/view.py
Normal file
101
zerver/webhooks/rhodecode/view.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
from zerver.decorator import webhook_view
|
||||
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
|
||||
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 (
|
||||
TOPIC_WITH_BRANCH_TEMPLATE,
|
||||
get_push_commits_event_message,
|
||||
is_branch_name_notifiable,
|
||||
)
|
||||
from zerver.models import UserProfile
|
||||
|
||||
|
||||
def get_push_commits_body(payload: WildValue) -> str:
|
||||
commits_data = [
|
||||
{
|
||||
"name": commit["author"].tame(check_string),
|
||||
"sha": commit["raw_id"].tame(check_string),
|
||||
"url": commit["url"].tame(check_string),
|
||||
"message": commit["message"].tame(check_string),
|
||||
}
|
||||
for commit in payload["event"]["push"]["commits"]
|
||||
]
|
||||
return get_push_commits_event_message(
|
||||
get_user_name(payload),
|
||||
None,
|
||||
get_push_branch_name(payload),
|
||||
commits_data,
|
||||
)
|
||||
|
||||
|
||||
def get_user_name(payload: WildValue) -> str:
|
||||
return payload["event"]["actor"]["username"].tame(check_string)
|
||||
|
||||
|
||||
def get_push_branch_name(payload: WildValue) -> str:
|
||||
branches = payload["event"]["push"]["branches"]
|
||||
try:
|
||||
return branches[0]["name"].tame(check_string)
|
||||
# this error happens when the event is a push to delete remote branch, where
|
||||
# branches will be an empty list
|
||||
except ValidationError:
|
||||
return payload["event"]["push"]["commits"][0]["raw_id"].tame(check_string).split("=>")[1]
|
||||
|
||||
|
||||
def get_event_name(payload: WildValue, branches: str | None) -> str | None:
|
||||
event_name = payload["event"]["name"].tame(check_string)
|
||||
if event_name == "repo-push" and branches is not None:
|
||||
branch = get_push_branch_name(payload)
|
||||
if not is_branch_name_notifiable(branch, branches):
|
||||
return None
|
||||
if event_name in EVENT_FUNCTION_MAPPER:
|
||||
return event_name
|
||||
raise UnsupportedWebhookEventTypeError(event_name)
|
||||
|
||||
|
||||
def get_repository_name(payload: WildValue) -> str:
|
||||
return payload["event"]["repo"]["repo_name"].tame(check_string)
|
||||
|
||||
|
||||
def get_topic_based_on_event(payload: WildValue, event: str) -> str:
|
||||
if event == "repo-push":
|
||||
return TOPIC_WITH_BRANCH_TEMPLATE.format(
|
||||
repo=get_repository_name(payload), branch=get_push_branch_name(payload)
|
||||
)
|
||||
return get_repository_name(payload) # nocoverage
|
||||
|
||||
|
||||
EVENT_FUNCTION_MAPPER: dict[str, Callable[[WildValue], str]] = {
|
||||
"repo-push": get_push_commits_body,
|
||||
}
|
||||
|
||||
ALL_EVENT_TYPES = list(EVENT_FUNCTION_MAPPER.keys())
|
||||
|
||||
|
||||
@webhook_view("RhodeCode", all_event_types=ALL_EVENT_TYPES)
|
||||
@typed_endpoint
|
||||
def api_rhodecode_webhook(
|
||||
request: HttpRequest,
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: str | None = None,
|
||||
) -> HttpResponse:
|
||||
event = get_event_name(payload, branches)
|
||||
if event is None:
|
||||
return json_success(request)
|
||||
|
||||
topic_name = get_topic_based_on_event(payload, event)
|
||||
|
||||
body_function = EVENT_FUNCTION_MAPPER[event]
|
||||
body = body_function(payload)
|
||||
|
||||
check_send_webhook_message(request, user_profile, topic_name, body)
|
||||
return json_success(request)
|
||||
Reference in New Issue
Block a user