# Webhooks
> 原文:[https://docs.gitlab.com/ee/user/project/integrations/webhooks.html](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html)
* [Overview](#overview)
* [Use-cases](#use-cases)
* [Webhook endpoint tips](#webhook-endpoint-tips)
* [Secret token](#secret-token)
* [SSL verification](#ssl-verification)
* [Branch filtering](#branch-filtering)
* [Events](#events)
* [Push events](#push-events)
* [Tag events](#tag-events)
* [Issue events](#issue-events)
* [Comment events](#comment-events)
* [Comment on commit](#comment-on-commit)
* [Comment on merge request](#comment-on-merge-request)
* [Comment on issue](#comment-on-issue)
* [Comment on code snippet](#comment-on-code-snippet)
* [Merge request events](#merge-request-events)
* [Wiki Page events](#wiki-page-events)
* [Pipeline events](#pipeline-events)
* [Job events](#job-events)
* [Image URL rewriting](#image-url-rewriting)
* [Testing webhooks](#testing-webhooks)
* [Troubleshoot webhooks](#troubleshoot-webhooks)
* [Receiving duplicate or multiple webhook requests triggered by one event](#receiving-duplicate-or-multiple-webhook-requests-triggered-by-one-event)
* [Troubleshooting: “Unable to get local issuer certificate”](#troubleshooting-unable-to-get-local-issuer-certificate)
* [Example webhook receiver](#example-webhook-receiver)
# Webhooks[](#webhooks "Permalink")
> **注意:**从 GitLab 8.5 开始:
>
> * 不推荐使用`repository`密钥,而推荐使用`project`密钥
> * 不推荐使用`project.ssh_url`密钥,而推荐使用`project.git_ssh_url`密钥
> * 不推荐使用`project.http_url`键,而推荐使用`project.git_http_url`键
>
> **注意:**从 GitLab 11.1 开始,一个月后会自动删除 Webhooks 的日志.
>
> **注意:**从 GitLab 11.2 开始:
>
> * 重写问题,合并请求,评论和 Wiki 页面的`description`字段,以便简单的 Markdown 图像引用(如`![](/uploads/...)` )将其目标 URL 更改为绝对 URL. 有关更多详细信息,请参见[图像 URL 重写](#image-url-rewriting) .
通过项目 webhooks,您可以在例如推送新代码或创建新问题时触发 URL. 您可以将 webhook 配置为侦听特定事件,例如推送,问题或合并请求. GitLab 会将带有数据的 POST 请求发送到 webhook URL.
在大多数情况下,您需要设置自己的[Webhook 接收器](#example-webhook-receiver)以从 GitLab 接收信息,然后根据需要将其发送到另一个应用程序. 我们已经有一个[内置接收器,](slack.html)用于*每个项目*发送[Slack](https://api.slack.com/incoming-webhooks)通知.
## Overview[](#overview "Permalink")
[Webhooks](https://en.wikipedia.org/wiki/Webhook)是" *用户定义的 HTTP 回调* ". 它们通常是由某些事件触发的,例如将代码推送到存储库或将评论发布到博客. 发生该事件时,源应用程序向为 Webhook 配置的 URI 发出 HTTP 请求. 采取的措施可能是任何事情. 常见用途是触发具有持续集成系统的构建或通知错误跟踪系统.
Webhooks 可用于更新外部问题跟踪器,触发 CI 作业,更新备份镜像,甚至部署到您的生产服务器. 他们**每个项目**可以 GitLab 社区版,以及**每个项目和每个组** **GitLab 企业版** .
通过转到项目的**设置➔Webhooks**导航到 webhooks 页面.
**注意:**在 GitLab.com 上,每个项目和每个组的[最大 Webhooks 数量](../../../user/gitlab_com/index.html#maximum-number-of-webhooks)是有限的.
## Use-cases[](#use-cases "Permalink")
* 您可以在 GitLab 中设置一个 Webhook,以在每次作业失败时向[Slack](https://api.slack.com/incoming-webhooks)发送通知.
* 每当在 GitLab 中为特定项目或组创建问题时,您都可以[与 Twilio 集成以通过 SMS 收到通知](https://www.datadoghq.com/blog/send-alerts-sms-customizable-webhooks-twilio/)
* You can use them to [automatically assign labels to merge requests](https://about.gitlab.com/blog/2016/08/19/applying-gitlab-labels-automatically/).
## Webhook endpoint tips[](#webhook-endpoint-tips "Permalink")
如果您正在编写自己的将接收 GitLab webhooks 的端点(Web 服务器),请记住以下几点:
* 您的端点应尽快发送其 HTTP 响应. 如果等待时间太长,GitLab 可能会确定挂钩失败并重试.
* 您的端点应始终返回有效的 HTTP 响应. 如果您不这样做,则 GitLab 会认为挂钩失败并重试. 大多数 HTTP 库会自动为您处理此问题,但是如果您正在编写低级钩子,记住这一点很重要.
* GitLab 会忽略端点返回的 HTTP 状态代码.
## Secret token[](#secret-token "Permalink")
如果您指定一个秘密令牌,它将与挂钩请求一起在`X-Gitlab-Token` HTTP 标头中发送. 您的 webhook 端点可以检查以验证请求是否合法.
## SSL verification[](#ssl-verification "Permalink")
默认情况下,将基于证书颁发机构的内部列表来验证 webhook 端点的 SSL 证书,这意味着该证书无法进行自签名.
您可以在 GitLab 项目的 webhook 设置中将其关闭.
[![SSL Verification](https://img.kancloud.cn/fe/63/fe63e0539335652668f99aa014b0d5a6_1984x1892.png)](img/webhooks_ssl.png)
## Branch filtering[](#branch-filtering "Permalink")
在 GitLab 11.3 中[引入](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/20338) .
可以使用分支名称或通配符模式按分支过滤推送事件,以限制将哪些推送事件发送到您的 Webhook 端点. 默认情况下,该字段为空白,导致所有推送事件都发送到您的 Webhook 端点.
## Events[](#events "Permalink")
下面介绍了受支持的事件.
### Push events[](#push-events "Permalink")
当您推送到存储库时(推送标签时除外)触发.
**注意:**一次推送超过 20 个提交时,出于性能原因, `commits` webhook 属性将仅包含前 20 个. 加载详细的提交数据非常昂贵. 请注意,尽管`commits`属性中仅存在 20 个提交,但`total_commits_count`属性将包含实际总数.
另外,如果单个推送包含三个以上分支的更改(默认情况下,取决于[`push_event_hooks_limit`设置](../../../api/settings.html#list-of-settings-that-can-be-accessed-via-api-calls) ),则不会执行此挂钩.
**请求标头**:
```
X-Gitlab-Event: Push Hook
```
**要求正文:**
```
{ "object_kind": "push", "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "ref": "refs/heads/master", "checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "user_id": 4, "user_name": "John Smith", "user_username": "jsmith", "user_email": "john@example.com", "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80", "project_id": 15, "project":{ "id": 15, "name":"Diaspora", "description":"", "web_url":"http://example.com/mike/diaspora", "avatar_url":null, "git_ssh_url":"git@example.com:mike/diaspora.git", "git_http_url":"http://example.com/mike/diaspora.git", "namespace":"Mike", "visibility_level":0, "path_with_namespace":"mike/diaspora", "default_branch":"master", "homepage":"http://example.com/mike/diaspora", "url":"git@example.com:mike/diaspora.git", "ssh_url":"git@example.com:mike/diaspora.git", "http_url":"http://example.com/mike/diaspora.git" }, "repository":{ "name": "Diaspora", "url": "git@example.com:mike/diaspora.git", "description": "", "homepage": "http://example.com/mike/diaspora", "git_http_url":"http://example.com/mike/diaspora.git", "git_ssh_url":"git@example.com:mike/diaspora.git", "visibility_level":0 }, "commits": [ { "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", "message": "Update Catalan translation to e38cb41.\n\nSee https://gitlab.com/gitlab-org/gitlab for more information", "title": "Update Catalan translation to e38cb41.", "timestamp": "2011-12-12T14:27:31+02:00", "url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", "author": { "name": "Jordi Mallach", "email": "jordi@softcatala.org" }, "added": ["CHANGELOG"], "modified": ["app/controller/application.rb"], "removed": [] }, { "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "message": "fixed readme", "title": "fixed readme", "timestamp": "2012-01-03T23:36:29+02:00", "url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "author": { "name": "GitLab dev user", "email": "gitlabdev@dv6700.(none)" }, "added": ["CHANGELOG"], "modified": ["app/controller/application.rb"], "removed": [] } ], "total_commits_count": 4 }
```
### Tag events[](#tag-events "Permalink")
在创建(或删除)存储库标签时触发.
**注意:**如果单个推送包含三个以上的更改(默认情况下,取决于[`push_event_hooks_limit`设置](../../../api/settings.html#list-of-settings-that-can-be-accessed-via-api-calls) ),则不会执行此挂钩.
**请求标头**:
```
X-Gitlab-Event: Tag Push Hook
```
**要求正文:**
```
{ "object_kind": "tag_push", "before": "0000000000000000000000000000000000000000", "after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", "ref": "refs/tags/v1.0.0", "checkout_sha": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", "user_id": 1, "user_name": "John Smith", "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80", "project_id": 1, "project":{ "id": 1, "name":"Example", "description":"", "web_url":"http://example.com/jsmith/example", "avatar_url":null, "git_ssh_url":"git@example.com:jsmith/example.git", "git_http_url":"http://example.com/jsmith/example.git", "namespace":"Jsmith", "visibility_level":0, "path_with_namespace":"jsmith/example", "default_branch":"master", "homepage":"http://example.com/jsmith/example", "url":"git@example.com:jsmith/example.git", "ssh_url":"git@example.com:jsmith/example.git", "http_url":"http://example.com/jsmith/example.git" }, "repository":{ "name": "Example", "url": "ssh://git@example.com/jsmith/example.git", "description": "", "homepage": "http://example.com/jsmith/example", "git_http_url":"http://example.com/jsmith/example.git", "git_ssh_url":"git@example.com:jsmith/example.git", "visibility_level":0 }, "commits": [], "total_commits_count": 0 }
```
### Issue events[](#issue-events "Permalink")
在创建新问题或更新/关闭/重新打开现有问题时触发.
**请求标头**:
```
X-Gitlab-Event: Issue Hook
```
**要求正文:**
```
{ "object_kind": "issue", "event_type": "issue", "user": { "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon", "email": "admin@example.com" }, "project": { "id": 1, "name":"Gitlab Test", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/gitlabhq/gitlab-test", "avatar_url":null, "git_ssh_url":"git@example.com:gitlabhq/gitlab-test.git", "git_http_url":"http://example.com/gitlabhq/gitlab-test.git", "namespace":"GitlabHQ", "visibility_level":20, "path_with_namespace":"gitlabhq/gitlab-test", "default_branch":"master", "ci_config_path": null, "homepage":"http://example.com/gitlabhq/gitlab-test", "url":"http://example.com/gitlabhq/gitlab-test.git", "ssh_url":"git@example.com:gitlabhq/gitlab-test.git", "http_url":"http://example.com/gitlabhq/gitlab-test.git" }, "object_attributes": { "id": 301, "title": "New API: create/update/delete file", "assignee_ids": [51], "assignee_id": 51, "author_id": 51, "project_id": 14, "created_at": "2013-12-03T17:15:43Z", "updated_at": "2013-12-03T17:15:43Z", "updated_by_id": 1, "last_edited_at": null, "last_edited_by_id": null, "relative_position": 0, "description": "Create new API for manipulations with repository", "milestone_id": null, "state_id": 1, "confidential": false, "discussion_locked": true, "due_date": null, "moved_to_id": null, "duplicated_to_id": null, "time_estimate": 0, "total_time_spent": 0, "human_total_time_spent": null, "human_time_estimate": null, "weight": null, "iid": 23, "url": "http://example.com/diaspora/issues/23", "state": "opened", "action": "open", "labels": [{ "id": 206, "title": "API", "color": "#ffffff", "project_id": 14, "created_at": "2013-12-03T17:15:43Z", "updated_at": "2013-12-03T17:15:43Z", "template": false, "description": "API related issues", "type": "ProjectLabel", "group_id": 41 }] }, "repository": { "name": "Gitlab Test", "url": "http://example.com/gitlabhq/gitlab-test.git", "description": "Aut reprehenderit ut est.", "homepage": "http://example.com/gitlabhq/gitlab-test" }, "assignees": [{ "name": "User1", "username": "user1", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" }], "assignee": { "name": "User1", "username": "user1", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" }, "labels": [{ "id": 206, "title": "API", "color": "#ffffff", "project_id": 14, "created_at": "2013-12-03T17:15:43Z", "updated_at": "2013-12-03T17:15:43Z", "template": false, "description": "API related issues", "type": "ProjectLabel", "group_id": 41 }], "changes": { "updated_by_id": { "previous": null, "current": 1 }, "updated_at": { "previous": "2017-09-15 16:50:55 UTC", "current": "2017-09-15 16:52:00 UTC" }, "labels": { "previous": [{ "id": 206, "title": "API", "color": "#ffffff", "project_id": 14, "created_at": "2013-12-03T17:15:43Z", "updated_at": "2013-12-03T17:15:43Z", "template": false, "description": "API related issues", "type": "ProjectLabel", "group_id": 41 }], "current": [{ "id": 205, "title": "Platform", "color": "#123123", "project_id": 14, "created_at": "2013-12-03T17:15:43Z", "updated_at": "2013-12-03T17:15:43Z", "template": false, "description": "Platform related issues", "type": "ProjectLabel", "group_id": 41 }] } } }
```
> **注意** :不赞成使用`assignee`和`assignee_id`键,现在仅显示第一个受让人.
### Comment events[](#comment-events "Permalink")
在对提交,合并请求,问题和代码段进行新注释时触发. 音符数据将被存储在`object_attributes` (如`note` , `noteable_type` ). 有效负载还将包括有关注释目标的信息. 例如,对问题的评论将在`issue`密钥下包括特定的问题信息. 有效的目标类型:
* `commit`
* `merge_request`
* `issue`
* `snippet`
#### Comment on commit[](#comment-on-commit "Permalink")
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**要求正文:**
```
{ "object_kind": "note", "user": { "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" }, "project_id": 5, "project":{ "id": 5, "name":"Gitlab Test", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/gitlabhq/gitlab-test", "avatar_url":null, "git_ssh_url":"git@example.com:gitlabhq/gitlab-test.git", "git_http_url":"http://example.com/gitlabhq/gitlab-test.git", "namespace":"GitlabHQ", "visibility_level":20, "path_with_namespace":"gitlabhq/gitlab-test", "default_branch":"master", "homepage":"http://example.com/gitlabhq/gitlab-test", "url":"http://example.com/gitlabhq/gitlab-test.git", "ssh_url":"git@example.com:gitlabhq/gitlab-test.git", "http_url":"http://example.com/gitlabhq/gitlab-test.git" }, "repository":{ "name": "Gitlab Test", "url": "http://example.com/gitlab-org/gitlab-test.git", "description": "Aut reprehenderit ut est.", "homepage": "http://example.com/gitlab-org/gitlab-test" }, "object_attributes": { "id": 1243, "note": "This is a commit comment. How does this work?", "noteable_type": "Commit", "author_id": 1, "created_at": "2015-05-17 18:08:09 UTC", "updated_at": "2015-05-17 18:08:09 UTC", "project_id": 5, "attachment":null, "line_code": "bec9703f7a456cd2b4ab5fb3220ae016e3e394e3_0_1", "commit_id": "cfe32cf61b73a0d5e9f13e774abde7ff789b1660", "noteable_id": null, "system": false, "st_diff": { "diff": "--- /dev/null\n+++ b/six\n@@ -0,0 +1 @@\n+Subproject commit 409f37c4f05865e4fb208c771485f211a22c4c2d\n", "new_path": "six", "old_path": "six", "a_mode": "0", "b_mode": "160000", "new_file": true, "renamed_file": false, "deleted_file": false }, "url": "http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660#note_1243" }, "commit": { "id": "cfe32cf61b73a0d5e9f13e774abde7ff789b1660", "message": "Add submodule\n\nSigned-off-by: Example User \u003cuser@example.com.com\u003e\n", "timestamp": "2014-02-27T10:06:20+02:00", "url": "http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660", "author": { "name": "Example User", "email": "user@example.com" } } }
```
#### Comment on merge request[](#comment-on-merge-request "Permalink")
**请求标头**:
```
X-Gitlab-Event: Note Hook
```
**要求正文:**
```
{ "object_kind": "note", "user": { "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" }, "project_id": 5, "project":{ "id": 5, "name":"Gitlab Test", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/gitlab-org/gitlab-test", "avatar_url":null, "git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "git_http_url":"http://example.com/gitlab-org/gitlab-test.git", "namespace":"Gitlab Org", "visibility_level":10, "path_with_namespace":"gitlab-org/gitlab-test", "default_branch":"master", "homepage":"http://example.com/gitlab-org/gitlab-test", "url":"http://example.com/gitlab-org/gitlab-test.git", "ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "http_url":"http://example.com/gitlab-org/gitlab-test.git" }, "repository":{ "name": "Gitlab Test", "url": "http://localhost/gitlab-org/gitlab-test.git", "description": "Aut reprehenderit ut est.", "homepage": "http://example.com/gitlab-org/gitlab-test" }, "object_attributes": { "id": 1244, "note": "This MR needs work.", "noteable_type": "MergeRequest", "author_id": 1, "created_at": "2015-05-17 18:21:36 UTC", "updated_at": "2015-05-17 18:21:36 UTC", "project_id": 5, "attachment": null, "line_code": null, "commit_id": "", "noteable_id": 7, "system": false, "st_diff": null, "url": "http://example.com/gitlab-org/gitlab-test/merge_requests/1#note_1244" }, "merge_request": { "id": 7, "target_branch": "markdown", "source_branch": "master", "source_project_id": 5, "author_id": 8, "assignee_id": 28, "title": "Tempora et eos debitis quae laborum et.", "created_at": "2015-03-01 20:12:53 UTC", "updated_at": "2015-03-21 18:27:27 UTC", "milestone_id": 11, "state": "opened", "merge_status": "cannot_be_merged", "target_project_id": 5, "iid": 1, "description": "Et voluptas corrupti assumenda temporibus. Architecto cum animi eveniet amet asperiores. Vitae numquam voluptate est natus sit et ad id.", "position": 0, "source":{ "name":"Gitlab Test", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/gitlab-org/gitlab-test", "avatar_url":null, "git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "git_http_url":"http://example.com/gitlab-org/gitlab-test.git", "namespace":"Gitlab Org", "visibility_level":10, "path_with_namespace":"gitlab-org/gitlab-test", "default_branch":"master", "homepage":"http://example.com/gitlab-org/gitlab-test", "url":"http://example.com/gitlab-org/gitlab-test.git", "ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "http_url":"http://example.com/gitlab-org/gitlab-test.git" }, "target": { "name":"Gitlab Test", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/gitlab-org/gitlab-test", "avatar_url":null, "git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "git_http_url":"http://example.com/gitlab-org/gitlab-test.git", "namespace":"Gitlab Org", "visibility_level":10, "path_with_namespace":"gitlab-org/gitlab-test", "default_branch":"master", "homepage":"http://example.com/gitlab-org/gitlab-test", "url":"http://example.com/gitlab-org/gitlab-test.git", "ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "http_url":"http://example.com/gitlab-org/gitlab-test.git" }, "last_commit": { "id": "562e173be03b8ff2efb05345d12df18815438a4b", "message": "Merge branch 'another-branch' into 'master'\n\nCheck in this test\n", "timestamp": "2015-04-08T21: 00:25-07:00", "url": "http://example.com/gitlab-org/gitlab-test/commit/562e173be03b8ff2efb05345d12df18815438a4b", "author": { "name": "John Smith", "email": "john@example.com" } }, "work_in_progress": false, "assignee": { "name": "User1", "username": "user1", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" } } }
```
#### Comment on issue[](#comment-on-issue "Permalink")
**请求标头**:
```
X-Gitlab-Event: Note Hook
```
**要求正文:**
```
{ "object_kind": "note", "user": { "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" }, "project_id": 5, "project":{ "id": 5, "name":"Gitlab Test", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/gitlab-org/gitlab-test", "avatar_url":null, "git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "git_http_url":"http://example.com/gitlab-org/gitlab-test.git", "namespace":"Gitlab Org", "visibility_level":10, "path_with_namespace":"gitlab-org/gitlab-test", "default_branch":"master", "homepage":"http://example.com/gitlab-org/gitlab-test", "url":"http://example.com/gitlab-org/gitlab-test.git", "ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "http_url":"http://example.com/gitlab-org/gitlab-test.git" }, "repository":{ "name":"diaspora", "url":"git@example.com:mike/diaspora.git", "description":"", "homepage":"http://example.com/mike/diaspora" }, "object_attributes": { "id": 1241, "note": "Hello world", "noteable_type": "Issue", "author_id": 1, "created_at": "2015-05-17 17:06:40 UTC", "updated_at": "2015-05-17 17:06:40 UTC", "project_id": 5, "attachment": null, "line_code": null, "commit_id": "", "noteable_id": 92, "system": false, "st_diff": null, "url": "http://example.com/gitlab-org/gitlab-test/issues/17#note_1241" }, "issue": { "id": 92, "title": "test", "assignee_ids": [], "assignee_id": null, "author_id": 1, "project_id": 5, "created_at": "2015-04-12 14:53:17 UTC", "updated_at": "2015-04-26 08:28:42 UTC", "position": 0, "branch_name": null, "description": "test", "milestone_id": null, "state": "closed", "iid": 17, "labels": [ { "id": 25, "title": "Afterpod", "color": "#3e8068", "project_id": null, "created_at": "2019-06-05T14:32:20.211Z", "updated_at": "2019-06-05T14:32:20.211Z", "template": false, "description": null, "type": "GroupLabel", "group_id": 4 }, { "id": 86, "title": "Element", "color": "#231afe", "project_id": 4, "created_at": "2019-06-05T14:32:20.637Z", "updated_at": "2019-06-05T14:32:20.637Z", "template": false, "description": null, "type": "ProjectLabel", "group_id": null } ], } }
```
> **注意** :不建议使用`assignee_id`字段,现在仅显示第一个受让人.
#### Comment on code snippet[](#comment-on-code-snippet "Permalink")
**请求标头**:
```
X-Gitlab-Event: Note Hook
```
**要求正文:**
```
{ "object_kind": "note", "user": { "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" }, "project_id": 5, "project":{ "id": 5, "name":"Gitlab Test", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/gitlab-org/gitlab-test", "avatar_url":null, "git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "git_http_url":"http://example.com/gitlab-org/gitlab-test.git", "namespace":"Gitlab Org", "visibility_level":10, "path_with_namespace":"gitlab-org/gitlab-test", "default_branch":"master", "homepage":"http://example.com/gitlab-org/gitlab-test", "url":"http://example.com/gitlab-org/gitlab-test.git", "ssh_url":"git@example.com:gitlab-org/gitlab-test.git", "http_url":"http://example.com/gitlab-org/gitlab-test.git" }, "repository":{ "name":"Gitlab Test", "url":"http://example.com/gitlab-org/gitlab-test.git", "description":"Aut reprehenderit ut est.", "homepage":"http://example.com/gitlab-org/gitlab-test" }, "object_attributes": { "id": 1245, "note": "Is this snippet doing what it's supposed to be doing?", "noteable_type": "Snippet", "author_id": 1, "created_at": "2015-05-17 18:35:50 UTC", "updated_at": "2015-05-17 18:35:50 UTC", "project_id": 5, "attachment": null, "line_code": null, "commit_id": "", "noteable_id": 53, "system": false, "st_diff": null, "url": "http://example.com/gitlab-org/gitlab-test/snippets/53#note_1245" }, "snippet": { "id": 53, "title": "test", "content": "puts 'Hello world'", "author_id": 1, "project_id": 5, "created_at": "2015-04-09 02:40:38 UTC", "updated_at": "2015-04-09 02:40:38 UTC", "file_name": "test.rb", "expires_at": null, "type": "ProjectSnippet", "visibility_level": 0 } }
```
### Merge request events[](#merge-request-events "Permalink")
在创建新的合并请求,更新/合并/关闭现有合并请求或在源分支中添加提交时触发.
**请求标头**:
```
X-Gitlab-Event: Merge Request Hook
```
**要求正文:**
```
{ "object_kind": "merge_request", "user": { "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" }, "project": { "id": 1, "name":"Gitlab Test", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/gitlabhq/gitlab-test", "avatar_url":null, "git_ssh_url":"git@example.com:gitlabhq/gitlab-test.git", "git_http_url":"http://example.com/gitlabhq/gitlab-test.git", "namespace":"GitlabHQ", "visibility_level":20, "path_with_namespace":"gitlabhq/gitlab-test", "default_branch":"master", "homepage":"http://example.com/gitlabhq/gitlab-test", "url":"http://example.com/gitlabhq/gitlab-test.git", "ssh_url":"git@example.com:gitlabhq/gitlab-test.git", "http_url":"http://example.com/gitlabhq/gitlab-test.git" }, "repository": { "name": "Gitlab Test", "url": "http://example.com/gitlabhq/gitlab-test.git", "description": "Aut reprehenderit ut est.", "homepage": "http://example.com/gitlabhq/gitlab-test" }, "object_attributes": { "id": 99, "target_branch": "master", "source_branch": "ms-viewport", "source_project_id": 14, "author_id": 51, "assignee_id": 6, "title": "MS-Viewport", "created_at": "2013-12-03T17:23:34Z", "updated_at": "2013-12-03T17:23:34Z", "milestone_id": null, "state": "opened", "merge_status": "unchecked", "target_project_id": 14, "iid": 1, "description": "", "source": { "name":"Awesome Project", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/awesome_space/awesome_project", "avatar_url":null, "git_ssh_url":"git@example.com:awesome_space/awesome_project.git", "git_http_url":"http://example.com/awesome_space/awesome_project.git", "namespace":"Awesome Space", "visibility_level":20, "path_with_namespace":"awesome_space/awesome_project", "default_branch":"master", "homepage":"http://example.com/awesome_space/awesome_project", "url":"http://example.com/awesome_space/awesome_project.git", "ssh_url":"git@example.com:awesome_space/awesome_project.git", "http_url":"http://example.com/awesome_space/awesome_project.git" }, "target": { "name":"Awesome Project", "description":"Aut reprehenderit ut est.", "web_url":"http://example.com/awesome_space/awesome_project", "avatar_url":null, "git_ssh_url":"git@example.com:awesome_space/awesome_project.git", "git_http_url":"http://example.com/awesome_space/awesome_project.git", "namespace":"Awesome Space", "visibility_level":20, "path_with_namespace":"awesome_space/awesome_project", "default_branch":"master", "homepage":"http://example.com/awesome_space/awesome_project", "url":"http://example.com/awesome_space/awesome_project.git", "ssh_url":"git@example.com:awesome_space/awesome_project.git", "http_url":"http://example.com/awesome_space/awesome_project.git" }, "last_commit": { "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "message": "fixed readme", "timestamp": "2012-01-03T23:36:29+02:00", "url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "author": { "name": "GitLab dev user", "email": "gitlabdev@dv6700.(none)" } }, "work_in_progress": false, "url": "http://example.com/diaspora/merge_requests/1", "action": "open", "assignee": { "name": "User1", "username": "user1", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" } }, "labels": [{ "id": 206, "title": "API", "color": "#ffffff", "project_id": 14, "created_at": "2013-12-03T17:15:43Z", "updated_at": "2013-12-03T17:15:43Z", "template": false, "description": "API related issues", "type": "ProjectLabel", "group_id": 41 }], "changes": { "updated_by_id": { "previous": null, "current": 1 }, "updated_at": { "previous": "2017-09-15 16:50:55 UTC", "current":"2017-09-15 16:52:00 UTC" }, "labels": { "previous": [{ "id": 206, "title": "API", "color": "#ffffff", "project_id": 14, "created_at": "2013-12-03T17:15:43Z", "updated_at": "2013-12-03T17:15:43Z", "template": false, "description": "API related issues", "type": "ProjectLabel", "group_id": 41 }], "current": [{ "id": 205, "title": "Platform", "color": "#123123", "project_id": 14, "created_at": "2013-12-03T17:15:43Z", "updated_at": "2013-12-03T17:15:43Z", "template": false, "description": "Platform related issues", "type": "ProjectLabel", "group_id": 41 }] } } }
```
### Wiki Page events[](#wiki-page-events "Permalink")
在创建,更新或删除 Wiki 页面时触发.
**请求标题**:
```
X-Gitlab-Event: Wiki Page Hook
```
**请求正文**:
```
{ "object_kind": "wiki_page", "user": { "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon" }, "project": { "id": 1, "name": "awesome-project", "description": "This is awesome", "web_url": "http://example.com/root/awesome-project", "avatar_url": null, "git_ssh_url": "git@example.com:root/awesome-project.git", "git_http_url": "http://example.com/root/awesome-project.git", "namespace": "root", "visibility_level": 0, "path_with_namespace": "root/awesome-project", "default_branch": "master", "homepage": "http://example.com/root/awesome-project", "url": "git@example.com:root/awesome-project.git", "ssh_url": "git@example.com:root/awesome-project.git", "http_url": "http://example.com/root/awesome-project.git" }, "wiki": { "web_url": "http://example.com/root/awesome-project/-/wikis/home", "git_ssh_url": "git@example.com:root/awesome-project.wiki.git", "git_http_url": "http://example.com/root/awesome-project.wiki.git", "path_with_namespace": "root/awesome-project.wiki", "default_branch": "master" }, "object_attributes": { "title": "Awesome", "content": "awesome content goes here", "format": "markdown", "message": "adding an awesome page to the wiki", "slug": "awesome", "url": "http://example.com/root/awesome-project/-/wikis/awesome", "action": "create" } }
```
### Pipeline events[](#pipeline-events "Permalink")
在管道状态更改时触发.
**请求标题**:
```
X-Gitlab-Event: Pipeline Hook
```
**请求正文**:
```
{ "object_kind": "pipeline", "object_attributes":{ "id": 31, "ref": "master", "tag": false, "sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", "before_sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", "source": "merge_request_event", "status": "success", "stages":[ "build", "test", "deploy" ], "created_at": "2016-08-12 15:23:28 UTC", "finished_at": "2016-08-12 15:26:29 UTC", "duration": 63, "variables": [ { "key": "NESTOR_PROD_ENVIRONMENT", "value": "us-west-1" } ] }, "merge_request": { "id": 1, "iid": 1, "title": "Test", "source_branch": "test", "source_project_id": 1, "target_branch": "master", "target_project_id": 1, "state": "opened", "merge_status": "can_be_merged", "url": "http://192.168.64.1:3005/gitlab-org/gitlab-test/merge_requests/1" }, "user":{ "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", "email": "user_email@gitlab.com" }, "project":{ "id": 1, "name": "Gitlab Test", "description": "Atque in sunt eos similique dolores voluptatem.", "web_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test", "avatar_url": null, "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git", "git_http_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git", "namespace": "Gitlab Org", "visibility_level": 20, "path_with_namespace": "gitlab-org/gitlab-test", "default_branch": "master" }, "commit":{ "id": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", "message": "test\n", "timestamp": "2016-08-12T17:23:21+02:00", "url": "http://example.com/gitlab-org/gitlab-test/commit/bcbb5ec396a2c0f828686f14fac9b80b780504f2", "author":{ "name": "User", "email": "user@gitlab.com" } }, "builds":[ { "id": 380, "stage": "deploy", "name": "production", "status": "skipped", "created_at": "2016-08-12 15:23:28 UTC", "started_at": null, "finished_at": null, "when": "manual", "manual": true, "allow_failure": false, "user":{ "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon" }, "runner": null, "artifacts_file":{ "filename": null, "size": null } }, { "id": 377, "stage": "test", "name": "test-image", "status": "success", "created_at": "2016-08-12 15:23:28 UTC", "started_at": "2016-08-12 15:26:12 UTC", "finished_at": null, "when": "on_success", "manual": false, "allow_failure": false, "user":{ "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon" }, "runner": { "id":380987, "description":"shared-runners-manager-6.gitlab.com", "active":true, "is_shared":true }, "artifacts_file":{ "filename": null, "size": null } }, { "id": 378, "stage": "test", "name": "test-build", "status": "success", "created_at": "2016-08-12 15:23:28 UTC", "started_at": "2016-08-12 15:26:12 UTC", "finished_at": "2016-08-12 15:26:29 UTC", "when": "on_success", "manual": false, "allow_failure": false, "user":{ "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon" }, "runner": { "id":380987, "description":"shared-runners-manager-6.gitlab.com", "active":true, "is_shared":true }, "artifacts_file":{ "filename": null, "size": null } }, { "id": 376, "stage": "build", "name": "build-image", "status": "success", "created_at": "2016-08-12 15:23:28 UTC", "started_at": "2016-08-12 15:24:56 UTC", "finished_at": "2016-08-12 15:25:26 UTC", "when": "on_success", "manual": false, "allow_failure": false, "user":{ "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon" }, "runner": { "id":380987, "description":"shared-runners-manager-6.gitlab.com", "active":true, "is_shared":true }, "artifacts_file":{ "filename": null, "size": null } }, { "id": 379, "stage": "deploy", "name": "staging", "status": "created", "created_at": "2016-08-12 15:23:28 UTC", "started_at": null, "finished_at": null, "when": "on_success", "manual": false, "allow_failure": false, "user":{ "name": "Administrator", "username": "root", "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon" }, "runner": null, "artifacts_file":{ "filename": null, "size": null } } ] }
```
### Job events[](#job-events "Permalink")
在工作状态更改时触发.
**请求标题**:
```
X-Gitlab-Event: Job Hook
```
**请求正文**:
```
{ "object_kind": "build", "ref": "gitlab-script-trigger", "tag": false, "before_sha": "2293ada6b400935a1378653304eaf6221e0fdb8f", "sha": "2293ada6b400935a1378653304eaf6221e0fdb8f", "build_id": 1977, "build_name": "test", "build_stage": "test", "build_status": "created", "build_started_at": null, "build_finished_at": null, "build_duration": null, "build_allow_failure": false, "build_failure_reason": "script_failure", "pipeline_id": 2366, "project_id": 380, "project_name": "gitlab-org/gitlab-test", "user": { "id": 3, "name": "User", "email": "user@gitlab.com", "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon" }, "commit": { "id": 2366, "sha": "2293ada6b400935a1378653304eaf6221e0fdb8f", "message": "test\n", "author_name": "User", "author_email": "user@gitlab.com", "status": "created", "duration": null, "started_at": null, "finished_at": null }, "repository": { "name": "gitlab_test", "description": "Atque in sunt eos similique dolores voluptatem.", "homepage": "http://192.168.64.1:3005/gitlab-org/gitlab-test", "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git", "git_http_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git", "visibility_level": 20 }, "runner": { "active": true, "is_shared": false, "id": 380987, "description": "shared-runners-manager-6.gitlab.com" } }
```
请注意, `commit.id`是管道的 ID,而不是提交的 ID.
## Image URL rewriting[](#image-url-rewriting "Permalink")
从 GitLab 11.2 开始,简单的图像引用被重写为在 webhooks 中使用绝对 URL. 因此,如果图像,合并请求,评论或维基页面的描述中包含以下内容:
```
![image](/uploads/$sha/image.png)
```
它将显示在 webhook 主体中,如下所示(假设 GitLab 安装在`gitlab.example.com` ,并且该项目位于`example-group/example-project` ):
```
![image](https://gitlab.example.com/example-group/example-project/uploads/$sha/image.png)
```
这不会重写已经指向 HTTP,HTTPS 或协议相对 URL 的 URL. 它还不会使用链接标记之类的高级 Markdown 功能重写图像 URL.
## Testing webhooks[](#testing-webhooks "Permalink")
您可以手动触发 Webhook. 将使用项目中的样本数据. >例如:要触发" `Push Events`您的项目应至少提交一次.
[![Webhook testing](https://img.kancloud.cn/96/6c/966cd8b13ad6a901763deb14b46682ac_1906x812.png)](img/webhook_testing.png)
## Troubleshoot webhooks[](#troubleshoot-webhooks "Permalink")
manbetx 客户端打不开存储 webhook 的每个执行. 您可以在每个 Webhook 的编辑页面上的"最近发送"部分中找到最近 2 天的记录.
[![Recent deliveries](https://img.kancloud.cn/52/fb/52fb3114225ad69e3ba0c2a532e196cb_1628x472.png)](img/webhook_logs.png)
在本部分中,您可以看到 HTTP 状态代码(绿色表示 200-299 代码,红色表示其他代码,传递失败的`internal error` ),触发的事件,事件被调用的时间,请求的经过时间.
如果需要有关执行的更多信息,可以单击`View details`链接. 在此页面上,您可以查看 GitLab 发送的数据(请求标头和正文)和收到的数据(响应标头和正文).
在此页面上,您可以通过单击" `Resend Request`按钮以相同的数据重复`Resend Request` .
> **注意:**如果已更新 Webhook 的 URL 或秘密令牌,则数据将被传递到新地址.
### Receiving duplicate or multiple webhook requests triggered by one event[](#receiving-duplicate-or-multiple-webhook-requests-triggered-by-one-event "Permalink")
当 GitLab 发送一个 Webhook 时,它期望在 10 秒内响应(设置默认值). 如果没有收到,它将重试网络挂钩. 如果端点在这 10 秒钟内未发送 HTTP 响应,则 GitLab 可能会确定挂钩失败并重试.
如果接收到多个请求,可以通过取消注释或将以下设置添加到`/etc/gitlab/gitlab.rb`来尝试增加发送`/etc/gitlab/gitlab.rb`之后的默认值,以等待 HTTP 响应:
```
gitlab_rails['webhook_timeout'] = 10
```
### Troubleshooting: “Unable to get local issuer certificate”[](#troubleshooting-unable-to-get-local-issuer-certificate "Permalink")
启用 SSL 验证后,此错误表明 GitLab 无法验证 Webhook 端点的 SSL 证书. 通常,这是因为根证书不是由[CAcert.org](http://www.cacert.org/)确定的受信任的证书颁发机构[颁发的](http://www.cacert.org/) .
如果不是这种情况,请考虑使用[SSL Checker](https://www.sslshopper.com/ssl-checker.html)来识别故障. 缺少中间证书是验证失败的常见原因.
## Example webhook receiver[](#example-webhook-receiver "Permalink")
如果您希望通过测试了解 GitLab 的 webhooks,可以使用在控制台会话中运行的简单回显脚本. 为了使以下脚本正常工作,您需要安装 Ruby.
将以下文件另存为`print_http_body.rb` :
```
require 'webrick'
server = WEBrick::HTTPServer.new(:Port => ARGV.first)
server.mount_proc '/' do |req, res|
puts req.body
end
trap 'INT' do
server.shutdown
end
server.start
```
选择一个未使用的端口(例如 8000)并启动脚本: `ruby print_http_body.rb 8000` . 然后,将您的服务器作为 Webhook 接收器添加到 GitLab 中,作为`http://my.host:8000/` .
在 GitLab 中按"测试"时,您应该在控制台中看到以下内容:
```
{"before":"077a85dd266e6f3573ef7e9ef8ce3343ad659c4e","after":"95cd4a99e93bc4bbabacfa2cd10e6725b1403c60",<SNIP>}
example.com - - [14/May/2014:07:45:26 EDT] "POST / HTTP/1.1" 200 0
- -> /
```
**注意:**您可能需要[允许向本地网络](../../../security/webhooks.html)发送[请求,](../../../security/webhooks.html)以便添加此接收器.
- GitLab Docs
- Installation
- Requirements
- GitLab cloud native Helm Chart
- Install GitLab with Docker
- Installation from source
- Install GitLab on Microsoft Azure
- Installing GitLab on Google Cloud Platform
- Installing GitLab on Amazon Web Services (AWS)
- Analytics
- Code Review Analytics
- Productivity Analytics
- Value Stream Analytics
- Kubernetes clusters
- Adding and removing Kubernetes clusters
- Adding EKS clusters
- Adding GKE clusters
- Group-level Kubernetes clusters
- Instance-level Kubernetes clusters
- Canary Deployments
- Cluster Environments
- Deploy Boards
- GitLab Managed Apps
- Crossplane configuration
- Cluster management project (alpha)
- Kubernetes Logs
- Runbooks
- Serverless
- Deploying AWS Lambda function using GitLab CI/CD
- Securing your deployed applications
- Groups
- Contribution Analytics
- Custom group-level project templates
- Epics
- Manage epics
- Group Import/Export
- Insights
- Issues Analytics
- Iterations
- Public access
- SAML SSO for GitLab.com groups
- SCIM provisioning using SAML SSO for GitLab.com groups
- Subgroups
- Roadmap
- Projects
- GitLab Secure
- Security Configuration
- Container Scanning
- Dependency Scanning
- Dependency List
- Static Application Security Testing (SAST)
- Secret Detection
- Dynamic Application Security Testing (DAST)
- GitLab Security Dashboard
- Offline environments
- Standalone Vulnerability pages
- Security scanner integration
- Badges
- Bulk editing issues and merge requests at the project level
- Code Owners
- Compliance
- License Compliance
- Compliance Dashboard
- Create a project
- Description templates
- Deploy Keys
- Deploy Tokens
- File finder
- Project integrations
- Integrations
- Atlassian Bamboo CI Service
- Bugzilla Service
- Custom Issue Tracker service
- Discord Notifications service
- Enabling emails on push
- GitHub project integration
- Hangouts Chat service
- Atlassian HipChat
- Irker IRC Gateway
- GitLab Jira integration
- Mattermost Notifications Service
- Mattermost slash commands
- Microsoft Teams service
- Mock CI Service
- Prometheus integration
- Redmine Service
- Slack Notifications Service
- Slack slash commands
- GitLab Slack application
- Webhooks
- YouTrack Service
- Insights
- Issues
- Crosslinking Issues
- Design Management
- Confidential issues
- Due dates
- Issue Boards
- Issue Data and Actions
- Labels
- Managing issues
- Milestones
- Multiple Assignees for Issues
- Related issues
- Service Desk
- Sorting and ordering issue lists
- Issue weight
- Associate a Zoom meeting with an issue
- Merge requests
- Allow collaboration on merge requests across forks
- Merge Request Approvals
- Browser Performance Testing
- How to create a merge request
- Cherry-pick changes
- Code Quality
- Load Performance Testing
- Merge Request dependencies
- Fast-forward merge requests
- Merge when pipeline succeeds
- Merge request conflict resolution
- Reverting changes
- Reviewing and managing merge requests
- Squash and merge
- Merge requests versions
- Draft merge requests
- Members of a project
- Migrating projects to a GitLab instance
- Import your project from Bitbucket Cloud to GitLab
- Import your project from Bitbucket Server to GitLab
- Migrating from ClearCase
- Migrating from CVS
- Import your project from FogBugz to GitLab
- Gemnasium
- Import your project from GitHub to GitLab
- Project importing from GitLab.com to your private GitLab instance
- Import your project from Gitea to GitLab
- Import your Jira project issues to GitLab
- Migrating from Perforce Helix
- Import Phabricator tasks into a GitLab project
- Import multiple repositories by uploading a manifest file
- Import project from repo by URL
- Migrating from SVN to GitLab
- Migrating from TFVC to Git
- Push Options
- Releases
- Repository
- Branches
- Git Attributes
- File Locking
- Git file blame
- Git file history
- Repository mirroring
- Protected branches
- Protected tags
- Push Rules
- Reduce repository size
- Signing commits with GPG
- Syntax Highlighting
- GitLab Web Editor
- Web IDE
- Requirements Management
- Project settings
- Project import/export
- Project access tokens (Alpha)
- Share Projects with other Groups
- Snippets
- Static Site Editor
- Wiki
- Project operations
- Monitor metrics for your CI/CD environment
- Set up alerts for Prometheus metrics
- Embedding metric charts within GitLab-flavored Markdown
- Embedding Grafana charts
- Using the Metrics Dashboard
- Dashboard YAML properties
- Metrics dashboard settings
- Panel types for dashboards
- Using Variables
- Templating variables for metrics dashboards
- Prometheus Metrics library
- Monitoring AWS Resources
- Monitoring HAProxy
- Monitoring Kubernetes
- Monitoring NGINX
- Monitoring NGINX Ingress Controller
- Monitoring NGINX Ingress Controller with VTS metrics
- Alert Management
- Error Tracking
- Tracing
- Incident Management
- GitLab Status Page
- Feature Flags
- GitLab CI/CD
- GitLab CI/CD pipeline configuration reference
- GitLab CI/CD include examples
- Introduction to CI/CD with GitLab
- Getting started with GitLab CI/CD
- How to enable or disable GitLab CI/CD
- Using SSH keys with GitLab CI/CD
- Migrating from CircleCI
- Migrating from Jenkins
- Auto DevOps
- Getting started with Auto DevOps
- Requirements for Auto DevOps
- Customizing Auto DevOps
- Stages of Auto DevOps
- Upgrading PostgreSQL for Auto DevOps
- Cache dependencies in GitLab CI/CD
- GitLab ChatOps
- Cloud deployment
- Docker integration
- Building Docker images with GitLab CI/CD
- Using Docker images
- Building images with kaniko and GitLab CI/CD
- GitLab CI/CD environment variables
- Predefined environment variables reference
- Where variables can be used
- Deprecated GitLab CI/CD variables
- Environments and deployments
- Protected Environments
- GitLab CI/CD Examples
- Test a Clojure application with GitLab CI/CD
- Using Dpl as deployment tool
- Testing a Phoenix application with GitLab CI/CD
- End-to-end testing with GitLab CI/CD and WebdriverIO
- DevOps and Game Dev with GitLab CI/CD
- Deploy a Spring Boot application to Cloud Foundry with GitLab CI/CD
- How to deploy Maven projects to Artifactory with GitLab CI/CD
- Testing PHP projects
- Running Composer and NPM scripts with deployment via SCP in GitLab CI/CD
- Test and deploy Laravel applications with GitLab CI/CD and Envoy
- Test and deploy a Python application with GitLab CI/CD
- Test and deploy a Ruby application with GitLab CI/CD
- Test and deploy a Scala application to Heroku
- GitLab CI/CD for external repositories
- Using GitLab CI/CD with a Bitbucket Cloud repository
- Using GitLab CI/CD with a GitHub repository
- GitLab Pages
- GitLab Pages
- GitLab Pages domain names, URLs, and baseurls
- Create a GitLab Pages website from scratch
- Custom domains and SSL/TLS Certificates
- GitLab Pages integration with Let's Encrypt
- GitLab Pages Access Control
- Exploring GitLab Pages
- Incremental Rollouts with GitLab CI/CD
- Interactive Web Terminals
- Optimizing GitLab for large repositories
- Metrics Reports
- CI/CD pipelines
- Pipeline Architecture
- Directed Acyclic Graph
- Multi-project pipelines
- Parent-child pipelines
- Pipelines for Merge Requests
- Pipelines for Merged Results
- Merge Trains
- Job artifacts
- Pipeline schedules
- Pipeline settings
- Triggering pipelines through the API
- Review Apps
- Configuring GitLab Runners
- GitLab CI services examples
- Using MySQL
- Using PostgreSQL
- Using Redis
- Troubleshooting CI/CD
- GitLab Package Registry
- GitLab Container Registry
- Dependency Proxy
- GitLab Composer Repository
- GitLab Conan Repository
- GitLab Maven Repository
- GitLab NPM Registry
- GitLab NuGet Repository
- GitLab PyPi Repository
- API Docs
- API resources
- .gitignore API
- GitLab CI YMLs API
- Group and project access requests API
- Appearance API
- Applications API
- Audit Events API
- Avatar API
- Award Emoji API
- Project badges API
- Group badges API
- Branches API
- Broadcast Messages API
- Project clusters API
- Group clusters API
- Instance clusters API
- Commits API
- Container Registry API
- Custom Attributes API
- Dashboard annotations API
- Dependencies API
- Deploy Keys API
- Deployments API
- Discussions API
- Dockerfiles API
- Environments API
- Epics API
- Events
- Feature Flags API
- Feature flag user lists API
- Freeze Periods API
- Geo Nodes API
- Group Activity Analytics API
- Groups API
- Import API
- Issue Boards API
- Group Issue Boards API
- Issues API
- Epic Issues API
- Issues Statistics API
- Jobs API
- Keys API
- Labels API
- Group Labels API
- License
- Licenses API
- Issue links API
- Epic Links API
- Managed Licenses API
- Markdown API
- Group and project members API
- Merge request approvals API
- Merge requests API
- Project milestones API
- Group milestones API
- Namespaces API
- Notes API
- Notification settings API
- Packages API
- Pages domains API
- Pipeline schedules API
- Pipeline triggers API
- Pipelines API
- Project Aliases API
- Project import/export API
- Project repository storage moves API
- Project statistics API
- Project templates API
- Projects API
- Protected branches API
- Protected tags API
- Releases API
- Release links API
- Repositories API
- Repository files API
- Repository submodules API
- Resource label events API
- Resource milestone events API
- Resource weight events API
- Runners API
- SCIM API
- Search API
- Services API
- Application settings API
- Sidekiq Metrics API
- Snippets API
- Project snippets
- Application statistics API
- Suggest Changes API
- System hooks API
- Tags API
- Todos API
- Users API
- Project-level Variables API
- Group-level Variables API
- Version API
- Vulnerabilities API
- Vulnerability Findings API
- Wikis API
- GraphQL API
- Getting started with GitLab GraphQL API
- GraphQL API Resources
- API V3 to API V4
- Validate the .gitlab-ci.yml (API)
- User Docs
- Abuse reports
- User account
- Active sessions
- Deleting a User account
- Permissions
- Personal access tokens
- Profile preferences
- Threads
- GitLab and SSH keys
- GitLab integrations
- Git
- GitLab.com settings
- Infrastructure as code with Terraform and GitLab
- GitLab keyboard shortcuts
- GitLab Markdown
- AsciiDoc
- GitLab Notification Emails
- GitLab Quick Actions
- Autocomplete characters
- Reserved project and group names
- Search through GitLab
- Advanced Global Search
- Advanced Syntax Search
- Time Tracking
- GitLab To-Do List
- Administrator Docs
- Reference architectures
- Reference architecture: up to 1,000 users
- Reference architecture: up to 2,000 users
- Reference architecture: up to 3,000 users
- Reference architecture: up to 5,000 users
- Reference architecture: up to 10,000 users
- Reference architecture: up to 25,000 users
- Reference architecture: up to 50,000 users
- Troubleshooting a reference architecture set up
- Working with the bundled Consul service
- Configuring PostgreSQL for scaling
- Configuring GitLab application (Rails)
- Load Balancer for multi-node GitLab
- Configuring a Monitoring node for Scaling and High Availability
- NFS
- Working with the bundled PgBouncer service
- Configuring Redis for scaling
- Configuring Sidekiq
- Admin Area settings
- Continuous Integration and Deployment Admin settings
- Custom instance-level project templates
- Diff limits administration
- Enable and disable GitLab features deployed behind feature flags
- Geo nodes Admin Area
- GitLab Pages administration
- Health Check
- Job logs
- Labels administration
- Log system
- PlantUML & GitLab
- Repository checks
- Repository storage paths
- Repository storage types
- Account and limit settings
- Service templates
- System hooks
- Changing your time zone
- Uploads administration
- Abuse reports
- Activating and deactivating users
- Audit Events
- Blocking and unblocking users
- Broadcast Messages
- Elasticsearch integration
- Gitaly
- Gitaly Cluster
- Gitaly reference
- Monitoring GitLab
- Monitoring GitLab with Prometheus
- Performance Bar
- Usage statistics
- Object Storage
- Performing Operations in GitLab
- Cleaning up stale Redis sessions
- Fast lookup of authorized SSH keys in the database
- Filesystem Performance Benchmarking
- Moving repositories managed by GitLab
- Run multiple Sidekiq processes
- Sidekiq MemoryKiller
- Switching to Puma
- Understanding Unicorn and unicorn-worker-killer
- User lookup via OpenSSH's AuthorizedPrincipalsCommand
- GitLab Package Registry administration
- GitLab Container Registry administration
- Replication (Geo)
- Geo database replication
- Geo with external PostgreSQL instances
- Geo configuration
- Using a Geo Server
- Updating the Geo nodes
- Geo with Object storage
- Docker Registry for a secondary node
- Geo for multiple nodes
- Geo security review (Q&A)
- Location-aware Git remote URL with AWS Route53
- Tuning Geo
- Removing secondary Geo nodes
- Geo data types support
- Geo Frequently Asked Questions
- Geo Troubleshooting
- Geo validation tests
- Disaster Recovery (Geo)
- Disaster recovery for planned failover
- Bring a demoted primary node back online
- Automatic background verification
- Rake tasks
- Back up and restore GitLab
- Clean up
- Namespaces
- Maintenance Rake tasks
- Geo Rake Tasks
- GitHub import
- Import bare repositories
- Integrity check Rake task
- LDAP Rake tasks
- Listing repository directories
- Praefect Rake tasks
- Project import/export administration
- Repository storage Rake tasks
- Generate sample Prometheus data
- Uploads migrate Rake tasks
- Uploads sanitize Rake tasks
- User management
- Webhooks administration
- X.509 signatures
- Server hooks
- Static objects external storage
- Updating GitLab
- GitLab release and maintenance policy
- Security
- Password Storage
- Custom password length limits
- Restrict allowed SSH key technologies and minimum length
- Rate limits
- Webhooks and insecure internal web services
- Information exclusivity
- How to reset your root password
- How to unlock a locked user from the command line
- User File Uploads
- How we manage the TLS protocol CRIME vulnerability
- User email confirmation at sign-up
- Security of running jobs
- Proxying assets
- CI/CD Environment Variables
- Contributor and Development Docs
- Contribute to GitLab
- Community members & roles
- Implement design & UI elements
- Issues workflow
- Merge requests workflow
- Code Review Guidelines
- Style guides
- GitLab Architecture Overview
- CI/CD development documentation
- Database guides
- Database Review Guidelines
- Database Review Guidelines
- Migration Style Guide
- What requires downtime?
- Understanding EXPLAIN plans
- Rake tasks for developers
- Mass inserting Rails models
- GitLab Documentation guidelines
- Documentation Style Guide
- Documentation structure and template
- Documentation process
- Documentation site architecture
- Global navigation
- GitLab Docs monthly release process
- Telemetry Guide
- Usage Ping Guide
- Snowplow Guide
- Experiment Guide
- Feature flags in development of GitLab
- Feature flags process
- Developing with feature flags
- Feature flag controls
- Document features deployed behind feature flags
- Frontend Development Guidelines
- Accessibility & Readability
- Ajax
- Architecture
- Axios
- Design Patterns
- Frontend Development Process
- DropLab
- Emojis
- Filter
- Frontend FAQ
- GraphQL
- Icons and SVG Illustrations
- InputSetter
- Performance
- Principles
- Security
- Tooling
- Vuex
- Vue
- Geo (development)
- Geo self-service framework (alpha)
- Gitaly developers guide
- GitLab development style guides
- API style guide
- Go standards and style guidelines
- GraphQL API style guide
- Guidelines for shell commands in the GitLab codebase
- HTML style guide
- JavaScript style guide
- Migration Style Guide
- Newlines style guide
- Python Development Guidelines
- SCSS style guide
- Shell scripting standards and style guidelines
- Sidekiq debugging
- Sidekiq Style Guide
- SQL Query Guidelines
- Vue.js style guide
- Instrumenting Ruby code
- Testing standards and style guidelines
- Flaky tests
- Frontend testing standards and style guidelines
- GitLab tests in the Continuous Integration (CI) context
- Review Apps
- Smoke Tests
- Testing best practices
- Testing levels
- Testing Rails migrations at GitLab
- Testing Rake tasks
- End-to-end Testing
- Beginner's guide to writing end-to-end tests
- End-to-end testing Best Practices
- Dynamic Element Validation
- Flows in GitLab QA
- Page objects in GitLab QA
- Resource class in GitLab QA
- Style guide for writing end-to-end tests
- Testing with feature flags
- Translate GitLab to your language
- Internationalization for GitLab
- Translating GitLab
- Proofread Translations
- Merging translations from CrowdIn
- Value Stream Analytics development guide
- GitLab subscription
- Activate GitLab EE with a license