Commit 7039d523 authored by Mike Greiling's avatar Mike Greiling

Merge branch 'master' into go-go-gadget-webpack

* master:
  Change window size before visiting page, to get correct scroll position
  Fix slash commands spec error
  Move project services to new location under Integrations
  Move webhooks to new a location under Integrations
  Fixed eslint test failure
  Fixed redirection from http://someproject.git to http://someproject
  Add traits for the different Event types to the Event factory
  prevent nonewline type diff lines from containing unfolding link
  ensure linenumber data attribute is correct for the last line in a diff chunk
  ensure last line in diff block is contained within a table row element
  ensure click event is bound only once
parents 04dc2b76 aa9e77b7
...@@ -4,6 +4,7 @@ require('./lib/utils/url_utility'); ...@@ -4,6 +4,7 @@ require('./lib/utils/url_utility');
(() => { (() => {
const UNFOLD_COUNT = 20; const UNFOLD_COUNT = 20;
let isBound = false;
class Diff { class Diff {
constructor() { constructor() {
...@@ -17,10 +18,12 @@ require('./lib/utils/url_utility'); ...@@ -17,10 +18,12 @@ require('./lib/utils/url_utility');
$('.content-wrapper .container-fluid').removeClass('container-limited'); $('.content-wrapper .container-fluid').removeClass('container-limited');
} }
$(document) if (!isBound) {
.off('click', '.js-unfold, .diff-line-num a') $(document)
.on('click', '.js-unfold', this.handleClickUnfold.bind(this)) .on('click', '.js-unfold', this.handleClickUnfold.bind(this))
.on('click', '.diff-line-num a', this.handleClickLineNum.bind(this)); .on('click', '.diff-line-num a', this.handleClickLineNum.bind(this));
isBound = true;
}
this.openAnchoredDiff(); this.openAnchoredDiff();
} }
......
...@@ -57,8 +57,8 @@ ...@@ -57,8 +57,8 @@
}; };
Project.prototype.initRefSwitcher = function() { Project.prototype.initRefSwitcher = function() {
var refListItem = document.createElement('li'), var refListItem = document.createElement('li');
refLink = document.createElement('a'); var refLink = document.createElement('a');
refLink.href = '#'; refLink.href = '#';
......
...@@ -18,7 +18,7 @@ class Projects::ApplicationController < ApplicationController ...@@ -18,7 +18,7 @@ class Projects::ApplicationController < ApplicationController
# to # to
# localhost/group/project # localhost/group/project
# #
if id =~ /\.git\Z/ if params[:format] == 'git'
redirect_to request.original_url.gsub(/\.git\/?\Z/, '') redirect_to request.original_url.gsub(/\.git\/?\Z/, '')
return return
end end
......
...@@ -56,7 +56,7 @@ module SearchHelper ...@@ -56,7 +56,7 @@ module SearchHelper
{ category: "Help", label: "Rake Tasks Help", url: help_page_path("raketasks/README") }, { category: "Help", label: "Rake Tasks Help", url: help_page_path("raketasks/README") },
{ category: "Help", label: "SSH Keys Help", url: help_page_path("ssh/README") }, { category: "Help", label: "SSH Keys Help", url: help_page_path("ssh/README") },
{ category: "Help", label: "System Hooks Help", url: help_page_path("system_hooks/system_hooks") }, { category: "Help", label: "System Hooks Help", url: help_page_path("system_hooks/system_hooks") },
{ category: "Help", label: "Webhooks Help", url: help_page_path("web_hooks/web_hooks") }, { category: "Help", label: "Webhooks Help", url: help_page_path("user/project/integrations/webhooks") },
{ category: "Help", label: "Workflow Help", url: help_page_path("workflow/README") }, { category: "Help", label: "Workflow Help", url: help_page_path("workflow/README") },
] ]
end end
......
...@@ -27,4 +27,4 @@ ...@@ -27,4 +27,4 @@
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc - if @form.unfold? && @form.bottom? && @form.to < @blob.loc
%tr.line_holder{ id: @form.to, class: line_class } %tr.line_holder{ id: @form.to, class: line_class }
= diff_match_line @form.to, @form.to, text: @match_line, view: diff_view, bottom: true = diff_match_line @form.to - @form.offset, @form.to, text: @match_line, view: diff_view, bottom: true
/ Side-by-side diff view / Side-by-side diff view
.text-file.diff-wrap-lines.code.js-syntax-highlight{ data: diff_view_data } .text-file.diff-wrap-lines.code.js-syntax-highlight{ data: diff_view_data }
%table %table
- last_line = 0
- diff_file.parallel_diff_lines.each do |line| - diff_file.parallel_diff_lines.each do |line|
- left = line[:left] - left = line[:left]
- right = line[:right] - right = line[:right]
- last_line = right.new_pos if right
%tr.line_holder.parallel %tr.line_holder.parallel
- if left - if left
- if left.meta? - case left.type
- when 'match'
= diff_match_line left.old_pos, nil, text: left.text, view: :parallel = diff_match_line left.old_pos, nil, text: left.text, view: :parallel
- when 'nonewline'
%td.old_line.diff-line-num
%td.line_content.match= left.text
- else - else
- left_line_code = diff_file.line_code(left) - left_line_code = diff_file.line_code(left)
- left_position = diff_file.position(left) - left_position = diff_file.position(left)
...@@ -21,8 +23,12 @@ ...@@ -21,8 +23,12 @@
%td.line_content.parallel %td.line_content.parallel
- if right - if right
- if right.meta? - case right.type
- when 'match'
= diff_match_line nil, right.new_pos, text: left.text, view: :parallel = diff_match_line nil, right.new_pos, text: left.text, view: :parallel
- when 'nonewline'
%td.new_line.diff-line-num
%td.line_content.match= right.text
- else - else
- right_line_code = diff_file.line_code(right) - right_line_code = diff_file.line_code(right)
- right_position = diff_file.position(right) - right_position = diff_file.position(right)
...@@ -37,5 +43,7 @@ ...@@ -37,5 +43,7 @@
- discussion_left, discussion_right = parallel_diff_discussions(left, right, diff_file) - discussion_left, discussion_right = parallel_diff_discussions(left, right, diff_file)
- if discussion_left || discussion_right - if discussion_left || discussion_right
= render "discussions/parallel_diff_discussion", discussion_left: discussion_left, discussion_right: discussion_right = render "discussions/parallel_diff_discussion", discussion_left: discussion_left, discussion_right: discussion_right
- if !diff_file.new_file && last_line > 0 - if !diff_file.new_file && diff_file.diff_lines.any?
= diff_match_line last_line, last_line, bottom: true, view: :parallel - last_line = diff_file.diff_lines.last
%tr.line_holder.parallel
= diff_match_line last_line.old_pos, last_line.new_pos, bottom: true, view: :parallel
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
%a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show. %a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show.
%table.text-file.code.js-syntax-highlight{ data: diff_view_data, class: too_big ? 'hide' : '' } %table.text-file.code.js-syntax-highlight{ data: diff_view_data, class: too_big ? 'hide' : '' }
- last_line = 0
- discussions = @grouped_diff_discussions unless @diff_notes_disabled - discussions = @grouped_diff_discussions unless @diff_notes_disabled
= render partial: "projects/diffs/line", = render partial: "projects/diffs/line",
collection: diff_file.highlighted_diff_lines, collection: diff_file.highlighted_diff_lines,
as: :line, as: :line,
locals: { diff_file: diff_file, discussions: discussions } locals: { diff_file: diff_file, discussions: discussions }
- last_line = diff_file.highlighted_diff_lines.last.new_pos - if !diff_file.new_file && diff_file.highlighted_diff_lines.any?
- if !diff_file.new_file && last_line > 0 - last_line = diff_file.highlighted_diff_lines.last
= diff_match_line last_line, last_line, bottom: true %tr.line_holder
= diff_match_line last_line.old_pos, last_line.new_pos, bottom: true
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
%h4.prepend-top-0 %h4.prepend-top-0
= page_title = page_title
%p %p
#{link_to "Webhooks", help_page_path("web_hooks/web_hooks")} can be #{link_to "Webhooks", help_page_path("user/project/integrations/webhooks")} can be
used for binding events when something is happening within the project. used for binding events when something is happening within the project.
.col-lg-9.append-bottom-default .col-lg-9.append-bottom-default
= form_for hook, as: :hook, url: polymorphic_path(url_components + [:hooks]) do |f| = form_for hook, as: :hook, url: polymorphic_path(url_components + [:hooks]) do |f|
......
---
title: Change rspec test to guarantee window is resized before visiting page
merge_request:
author:
---
title: Redirect http://someproject.git to http://someproject
merge_request:
author: blackst0ne
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
- [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab. - [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab.
- [Permissions](user/permissions.md) Learn what each role in a project (external/guest/reporter/developer/master/owner) can do. - [Permissions](user/permissions.md) Learn what each role in a project (external/guest/reporter/developer/master/owner) can do.
- [Profile Settings](profile/README.md) - [Profile Settings](profile/README.md)
- [Project Services](project_services/project_services.md) Integrate a project with external services, such as CI and chat. - [Project Services](user/project/integrations//project_services.md) Integrate a project with external services, such as CI and chat.
- [Public access](public_access/public_access.md) Learn how you can allow public and internal access to projects. - [Public access](public_access/public_access.md) Learn how you can allow public and internal access to projects.
- [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects. - [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects.
- [Webhooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project. - [Webhooks](user/project/integrations/webhooks.md) Let GitLab notify you when new code has been pushed to your project.
- [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN. - [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN.
- [Git Attributes](user/project/git_attributes.md) Managing Git attributes using a `.gitattributes` file. - [Git Attributes](user/project/git_attributes.md) Managing Git attributes using a `.gitattributes` file.
- [Git cheatsheet](https://gitlab.com/gitlab-com/marketing/raw/master/design/print/git-cheatsheet/print-pdf/git-cheatsheet.pdf) Download a PDF describing the most used Git operations. - [Git cheatsheet](https://gitlab.com/gitlab-com/marketing/raw/master/design/print/git-cheatsheet/print-pdf/git-cheatsheet.pdf) Download a PDF describing the most used Git operations.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
> >
**Note:** Custom Git hooks must be configured on the filesystem of the GitLab **Note:** Custom Git hooks must be configured on the filesystem of the GitLab
server. Only GitLab server administrators will be able to complete these tasks. server. Only GitLab server administrators will be able to complete these tasks.
Please explore [webhooks](../web_hooks/web_hooks.md) as an option if you do not Please explore [webhooks] as an option if you do not
have filesystem access. For a user configurable Git hook interface, please see have filesystem access. For a user configurable Git hook interface, please see
[GitLab Enterprise Edition Git Hooks](http://docs.gitlab.com/ee/git_hooks/git_hooks.html). [GitLab Enterprise Edition Git Hooks](http://docs.gitlab.com/ee/git_hooks/git_hooks.html).
...@@ -80,5 +80,6 @@ STDERR takes precedence over STDOUT. ...@@ -80,5 +80,6 @@ STDERR takes precedence over STDOUT.
![Custom message from custom Git hook](img/custom_hooks_error_msg.png) ![Custom message from custom Git hook](img/custom_hooks_error_msg.png)
[hooks]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#Server-Side-Hooks [hooks]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#Server-Side-Hooks
[webhooks]: ../user/project/integrations/webhooks.md
[5073]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5073 [5073]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5073
[93]: https://gitlab.com/gitlab-org/gitlab-shell/merge_requests/93 [93]: https://gitlab.com/gitlab-org/gitlab-shell/merge_requests/93
# Web terminals # Web terminals
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7690) > [Introduced][ce-7690] in GitLab 8.15. Only project masters and owners can
in GitLab 8.15. Only project masters and owners can access web terminals. access web terminals.
With the introduction of the [Kubernetes](../../project_services/kubernetes.md) With the introduction of the [Kubernetes project service][kubservice], GitLab
project service, GitLab gained the ability to store and use credentials for a gained the ability to store and use credentials for a Kubernetes cluster. One
Kubernetes cluster. One of the things it uses these credentials for is providing of the things it uses these credentials for is providing access to
access to [web terminals](../../ci/environments.html#web-terminals) [web terminals](../../ci/environments.html#web-terminals) for environments.
for environments.
## How it works ## How it works
...@@ -71,3 +70,6 @@ by the above guides. ...@@ -71,3 +70,6 @@ by the above guides.
When these headers are not passed through, Workhorse will return a When these headers are not passed through, Workhorse will return a
`400 Bad Request` response to users attempting to use a web terminal. In turn, `400 Bad Request` response to users attempting to use a web terminal. In turn,
they will receive a `Connection failed` message. they will receive a `Connection failed` message.
[ce-7690]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7690
[kubservice]: ../../user/project/integrations/kubernetes.md)
...@@ -808,5 +808,5 @@ Get JetBrains TeamCity CI service settings for a project. ...@@ -808,5 +808,5 @@ Get JetBrains TeamCity CI service settings for a project.
GET /projects/:id/services/teamcity GET /projects/:id/services/teamcity
``` ```
[jira-doc]: ../project_services/jira.md [jira-doc]: ../user/project/integrations/jira.md
[old-jira-api]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-13-stable/doc/api/services.md#jira [old-jira-api]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-13-stable/doc/api/services.md#jira
...@@ -34,8 +34,8 @@ created automatically for you. ...@@ -34,8 +34,8 @@ created automatically for you.
[mr-8135]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8135 [mr-8135]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8135
[project-settings]: https://docs.gitlab.com/ce/public_access/public_access.html [project-settings]: https://docs.gitlab.com/ce/public_access/public_access.html
[project-services]: ../../project_services/project_services.md [project-services]: ../../user/project/integrations/project_services.md
[auto-deploy-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml/tree/master/autodeploy [auto-deploy-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml/tree/master/autodeploy
[kubernetes-service]: ../../project_services/kubernetes.md [kubernetes-service]: ../../user/project/integrations/kubernetes.md
[docker-in-docker]: ../docker/using_docker_build.md#use-docker-in-docker-executor [docker-in-docker]: ../docker/using_docker_build.md#use-docker-in-docker-executor
[review-app]: ../review_apps/index.md [review-app]: ../review_apps/index.md
# Introduction to environments and deployments # Introduction to environments and deployments
>**Note:** > Introduced in GitLab 8.9.
Introduced in GitLab 8.9.
During the development of software, there can be many stages until it's ready During the development of software, there can be many stages until it's ready
for public consumption. You sure want to first test your code and then deploy it for public consumption. You sure want to first test your code and then deploy it
...@@ -242,7 +241,7 @@ Web terminals were added in GitLab 8.15 and are only available to project ...@@ -242,7 +241,7 @@ Web terminals were added in GitLab 8.15 and are only available to project
masters and owners. masters and owners.
If you deploy to your environments with the help of a deployment service (e.g., If you deploy to your environments with the help of a deployment service (e.g.,
the [Kubernetes](../project_services/kubernetes.md) service), GitLab can open the [Kubernetes service][kubernetes-service], GitLab can open
a terminal session to your environment! This is a very powerful feature that a terminal session to your environment! This is a very powerful feature that
allows you to debug issues without leaving the comfort of your web browser. To allows you to debug issues without leaving the comfort of your web browser. To
enable it, just follow the instructions given in the service documentation. enable it, just follow the instructions given in the service documentation.
...@@ -566,7 +565,7 @@ Below are some links you may find interesting: ...@@ -566,7 +565,7 @@ Below are some links you may find interesting:
[Pipelines]: pipelines.md [Pipelines]: pipelines.md
[jobs]: yaml/README.md#jobs [jobs]: yaml/README.md#jobs
[yaml]: yaml/README.md [yaml]: yaml/README.md
[kubernetes-service]: ../project_services/kubernetes.md] [kubernetes-service]: ../user/project/integrations/kubernetes.md
[environments]: #environments [environments]: #environments
[deployments]: #deployments [deployments]: #deployments
[permissions]: ../user/permissions.md [permissions]: ../user/permissions.md
......
...@@ -217,7 +217,7 @@ builds, you should explicitly enable the **Builds Emails** service under your ...@@ -217,7 +217,7 @@ builds, you should explicitly enable the **Builds Emails** service under your
project's settings. project's settings.
For more information read the For more information read the
[Builds emails service documentation](../../project_services/builds_emails.md). [Builds emails service documentation](../../user/project/integrations/builds_emails.md).
## Examples ## Examples
......
...@@ -157,14 +157,14 @@ Once you set them, they will be available for all subsequent builds. ...@@ -157,14 +157,14 @@ Once you set them, they will be available for all subsequent builds.
>**Note:** >**Note:**
This feature requires GitLab CI 8.15 or higher. This feature requires GitLab CI 8.15 or higher.
[Project services](../../project_services/project_services.md) that are [Project services](../../user/project/integrations/project_services.md) that are
responsible for deployment configuration may define their own variables that responsible for deployment configuration may define their own variables that
are set in the build environment. These variables are only defined for are set in the build environment. These variables are only defined for
[deployment builds](../environments.md). Please consult the documentation of [deployment builds](../environments.md). Please consult the documentation of
the project services that you are using to learn which variables they define. the project services that you are using to learn which variables they define.
An example project service that defines deployment variables is An example project service that defines deployment variables is
[Kubernetes Service](../../project_services/kubernetes.md). [Kubernetes Service](../../user/project/integrations/kubernetes.md).
## Debug tracing ## Debug tracing
......
...@@ -5,7 +5,7 @@ trackers and external authentication. ...@@ -5,7 +5,7 @@ trackers and external authentication.
See the documentation below for details on how to configure these services. See the documentation below for details on how to configure these services.
- [JIRA](../project_services/jira.md) Integrate with the JIRA issue tracker - [JIRA](../user/project/integrations/jira.md) Integrate with the JIRA issue tracker
- [External issue tracker](external-issue-tracker.md) Redmine, JIRA, etc. - [External issue tracker](external-issue-tracker.md) Redmine, JIRA, etc.
- [LDAP](ldap.md) Set up sign in via LDAP - [LDAP](ldap.md) Set up sign in via LDAP
- [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab.com, Google, Bitbucket, Facebook, Shibboleth, SAML, Crowd, Azure and Authentiq ID - [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab.com, Google, Bitbucket, Facebook, Shibboleth, SAML, Crowd, Azure and Authentiq ID
...@@ -18,17 +18,14 @@ See the documentation below for details on how to configure these services. ...@@ -18,17 +18,14 @@ See the documentation below for details on how to configure these services.
- [Koding](../administration/integration/koding.md) Configure Koding to use IDE integration - [Koding](../administration/integration/koding.md) Configure Koding to use IDE integration
- [PlantUML](../administration/integration/plantuml.md) Configure PlantUML to use diagrams in AsciiDoc documents. - [PlantUML](../administration/integration/plantuml.md) Configure PlantUML to use diagrams in AsciiDoc documents.
GitLab Enterprise Edition contains [advanced Jenkins support][jenkins]. > GitLab Enterprise Edition contains [advanced Jenkins support][jenkins].
[jenkins]: http://docs.gitlab.com/ee/integration/jenkins.html
## Project services ## Project services
Integration with services such as Campfire, Flowdock, Gemnasium, HipChat, Integration with services such as Campfire, Flowdock, Gemnasium, HipChat,
Pivotal Tracker, and Slack are available in the form of a [Project Service][]. Pivotal Tracker, and Slack are available in the form of a [Project Service][].
[Project Service]: ../project_services/project_services.md [Project Service]: ../user/project/integrations/project_services.md
## SSL certificate errors ## SSL certificate errors
...@@ -64,3 +61,5 @@ After that restart GitLab with: ...@@ -64,3 +61,5 @@ After that restart GitLab with:
```bash ```bash
sudo gitlab-ctl restart sudo gitlab-ctl restart
``` ```
[jenkins]: http://docs.gitlab.com/ee/integration/jenkins.html
...@@ -18,9 +18,9 @@ The configuration is done via a project's **Services**. ...@@ -18,9 +18,9 @@ The configuration is done via a project's **Services**.
To enable an external issue tracker you must configure the appropriate **Service**. To enable an external issue tracker you must configure the appropriate **Service**.
Visit the links below for details: Visit the links below for details:
- [Redmine](../project_services/redmine.md) - [Redmine](../user/project/integrations/redmine.md)
- [Jira](../project_services/jira.md) - [Jira](../user/project/integrations/jira.md)
- [Bugzilla](../project_services/bugzilla.md) - [Bugzilla](../user/project/integrations/bugzilla.md)
### Service Template ### Service Template
...@@ -28,4 +28,4 @@ To save you the hassle from configuring each project's service individually, ...@@ -28,4 +28,4 @@ To save you the hassle from configuring each project's service individually,
GitLab provides the ability to set Service Templates which can then be GitLab provides the ability to set Service Templates which can then be
overridden in each project's settings. overridden in each project's settings.
Read more on [Services Templates](../project_services/services_templates.md). Read more on [Services Templates](../user/project/integrations/services_templates.md).
# GitLab JIRA integration This document was moved to [integrations/jira](../user/project/integrations/jira.md).
This document was moved to [project_services/jira](../project_services/jira.md).
# Atlassian Bamboo CI Service This document was moved to [user/project/integrations/bamboo.md](../user/project/integrations/bamboo.md).
GitLab provides integration with Atlassian Bamboo for continuous integration.
When configured, pushes to a project will trigger a build in Bamboo automatically.
Merge requests will also display CI status showing whether the build is pending,
failed, or completed successfully. It also provides a link to the Bamboo build
page for more information.
Bamboo doesn't quite provide the same features as a traditional build system when
it comes to accepting webhooks and commit data. There are a few things that
need to be configured in a Bamboo build plan before GitLab can integrate.
## Setup
### Complete these steps in Bamboo:
1. Navigate to a Bamboo build plan and choose 'Configure plan' from the 'Actions'
dropdown.
1. Select the 'Triggers' tab.
1. Click 'Add trigger'.
1. Enter a description such as 'GitLab trigger'
1. Choose 'Repository triggers the build when changes are committed'
1. Check one or more repositories checkboxes
1. Enter the GitLab IP address in the 'Trigger IP addresses' box. This is a
whitelist of IP addresses that are allowed to trigger Bamboo builds.
1. Save the trigger.
1. In the left pane, select a build stage. If you have multiple build stages
you want to select the last stage that contains the git checkout task.
1. Select the 'Miscellaneous' tab.
1. Under 'Pattern Match Labelling' put '${bamboo.repository.revision.number}'
in the 'Labels' box.
1. Save
Bamboo is now ready to accept triggers from GitLab. Next, set up the Bamboo
service in GitLab
### Complete these steps in GitLab:
1. Navigate to the project you want to configure to trigger builds.
1. Select 'Settings' in the top navigation.
1. Select 'Services' in the left navigation.
1. Click 'Atlassian Bamboo CI'
1. Select the 'Active' checkbox.
1. Enter the base URL of your Bamboo server. 'https://bamboo.example.com'
1. Enter the build key from your Bamboo build plan. Build keys are a short,
all capital letter, identifier that is unique. It will be something like PR-BLD
1. If necessary, enter username and password for a Bamboo user that has
access to trigger the build plan. Leave these fields blank if you do not require
authentication.
1. Save or optionally click 'Test Settings'. Please note that 'Test Settings'
will actually trigger a build in Bamboo.
## Troubleshooting
If builds are not triggered, these are a couple of things to keep in mind.
1. Ensure you entered the right GitLab IP address in Bamboo under 'Trigger
IP addresses'.
1. Remember that GitLab only triggers builds on push events. A commit via the
web interface will not trigger CI currently.
# Bugzilla Service This document was moved to [user/project/integrations/bugzilla.md](../user/project/integrations/bugzilla.md).
Go to your project's **Settings > Services > Bugzilla** and fill in the required
details as described in the table below.
| Field | Description |
| ----- | ----------- |
| `description` | A name for the issue tracker (to differentiate between instances, for example) |
| `project_url` | The URL to the project in Bugzilla which is being linked to this GitLab project. Note that the `project_url` requires PRODUCT_NAME to be updated with the product/project name in Bugzilla. |
| `issues_url` | The URL to the issue in Bugzilla project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. |
| `new_issue_url` | This is the URL to create a new issue in Bugzilla for the project linked to this GitLab project. Note that the `new_issue_url` requires PRODUCT_NAME to be updated with the product/project name in Bugzilla. |
Once you have configured and enabled Bugzilla:
- the **Issues** link on the GitLab project pages takes you to the appropriate
Bugzilla product page
- clicking **New issue** on the project dashboard takes you to Bugzilla for entering a new issue
## Enabling build emails This document was moved to [user/project/integrations/builds_emails.md](../user/project/integrations/builds_emails.md).
To receive e-mail notifications about the result status of your builds, visit
your project's **Settings > Services > Builds emails** and activate the service.
In the _Recipients_ area, provide a list of e-mails separated by comma.
Check the _Add pusher_ checkbox if you want the committer to also receive
e-mail notifications about each build's status.
If you enable the _Notify only broken builds_ option, e-mail notifications will
be sent only for failed builds.
---
![Builds emails service settings](img/builds_emails_service.png)
## Enabling emails on push This document was moved to [user/project/integrations/emails_on_push.md](../user/project/integrations/emails_on_push.md).
To receive email notifications for every change that is pushed to the project, visit
your project's **Settings > Services > Emails on push** and activate the service.
In the _Recipients_ area, provide a list of emails separated by commas.
You can configure any of the following settings depending on your preference.
+ **Push events** - Email will be triggered when a push event is recieved
+ **Tag push events** - Email will be triggered when a tag is created and pushed
+ **Send from committer** - Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. `user@gitlab.com`).
+ **Disable code diffs** - Don't include possibly sensitive code diffs in notification body.
---
![Email on push service settings](img/emails_on_push_service.png)
# Atlassian HipChat This document was moved to [user/project/integrations/hipchat.md](../user/project/integrations/hipchat.md).
GitLab provides a way to send HipChat notifications upon a number of events,
such as when a user pushes code, creates a branch or tag, adds a comment, and
creates a merge request.
## Setup
GitLab requires the use of a HipChat v2 API token to work. v1 tokens are
not supported at this time. Note the differences between v1 and v2 tokens:
HipChat v1 API (legacy) supports "API Auth Tokens" in the Group API menu. A v1
token is allowed to send messages to *any* room.
HipChat v2 API has tokens that are can be created using the Integrations tab
in the Group or Room admin page. By design, these are lightweight tokens that
allow GitLab to send messages only to *one* room.
### Complete these steps in HipChat:
1. Go to: https://admin.hipchat.com/admin
1. Click on "Group Admin" -> "Integrations".
1. Find "Build Your Own!" and click "Create".
1. Select the desired room, name the integration "GitLab", and click "Create".
1. In the "Send messages to this room by posting this URL" column, you should
see a URL in the format:
```
https://api.hipchat.com/v2/room/<room>/notification?auth_token=<token>
```
HipChat is now ready to accept messages from GitLab. Next, set up the HipChat
service in GitLab.
### Complete these steps in GitLab:
1. Navigate to the project you want to configure for notifications.
1. Select "Settings" in the top navigation.
1. Select "Services" in the left navigation.
1. Click "HipChat".
1. Select the "Active" checkbox.
1. Insert the `token` field from the URL into the `Token` field on the Web page.
1. Insert the `room` field from the URL into the `Room` field on the Web page.
1. Save or optionally click "Test Settings".
## Troubleshooting
If you do not see notifications, make sure you are using a HipChat v2 API
token, not a v1 token.
Note that the v2 token is tied to a specific room. If you want to be able to
specify arbitrary rooms, you can create an API token for a specific user in
HipChat under "Account settings" and "API access". Use the `XXX` value under
`auth_token=XXX`.
# Irker IRC Gateway This document was moved to [user/project/integrations/irker.md](../user/project/integrations/irker.md).
GitLab provides a way to push update messages to an Irker server. When
configured, pushes to a project will trigger the service to send data directly
to the Irker server.
See the project homepage for further info: https://gitlab.com/esr/irker
## Needed setup
You will first need an Irker daemon. You can download the Irker code from its
repository on https://gitlab.com/esr/irker:
```
git clone https://gitlab.com/esr/irker.git
```
Once you have downloaded the code, you can run the python script named `irkerd`.
This script is the gateway script, it acts both as an IRC client, for sending
messages to an IRC server obviously, and as a TCP server, for receiving messages
from the GitLab service.
If the Irker server runs on the same machine, you are done. If not, you will
need to follow the firsts steps of the next section.
## Complete these steps in GitLab:
1. Navigate to the project you want to configure for notifications.
1. Select "Settings" in the top navigation.
1. Select "Services" in the left navigation.
1. Click "Irker".
1. Select the "Active" checkbox.
1. Enter the server host address where `irkerd` runs (defaults to `localhost`)
in the `Server host` field on the Web page
1. Enter the server port of `irkerd` (e.g. defaults to 6659) in the
`Server port` field on the Web page.
1. Optional: if `Default IRC URI` is set, it has to be in the format
`irc[s]://domain.name` and will be prepend to each and every channel provided
by the user which is not a full URI.
1. Specify the recipients (e.g. #channel1, user1, etc.)
1. Save or optionally click "Test Settings".
## Note on Irker recipients
Irker accepts channel names of the form `chan` and `#chan`, both for the
`#chan` channel. If you want to send messages in query, you will need to add
`,isnick` after the channel name, in this form: `Aorimn,isnick`. In this latter
case, `Aorimn` is treated as a nick and no more as a channel name.
Irker can also join password-protected channels. Users need to append
`?key=thesecretpassword` to the chan name.
# GitLab JIRA integration This document was moved to [user/project/integrations/jira.md](../user/project/integrations/jira.md).
GitLab can be configured to interact with JIRA. Configuration happens via
user name and password. Connecting to a JIRA server via CAS is not possible.
Each project can be configured to connect to a different JIRA instance, see the
[configuration](#configuration) section. If you have one JIRA instance you can
pre-fill the settings page with a default template. To configure the template
see the [Services Templates][services-templates] document.
Once the project is connected to JIRA, you can reference and close the issues
in JIRA directly from GitLab.
## Configuration
In order to enable the JIRA service in GitLab, you need to first configure the
project in JIRA and then enter the correct values in GitLab.
### Configuring JIRA
We need to create a user in JIRA which will have access to all projects that
need to integrate with GitLab. Login to your JIRA instance as admin and under
Administration go to User Management and create a new user.
As an example, we'll create a user named `gitlab` and add it to `JIRA-developers`
group.
**It is important that the user `GitLab` has write-access to projects in JIRA**
We have split this stage in steps so it is easier to follow.
---
1. Login to your JIRA instance as an administrator and under **Administration**
go to **User Management** to create a new user.
![JIRA user management link](img/jira_user_management_link.png)
---
1. The next step is to create a new user (e.g., `gitlab`) who has write access
to projects in JIRA. Enter the user's name and a _valid_ e-mail address
since JIRA sends a verification e-mail to set-up the password.
_**Note:** JIRA creates the username automatically by using the e-mail
prefix. You can change it later if you want._
![JIRA create new user](img/jira_create_new_user.png)
---
1. Now, let's create a `gitlab-developers` group which will have write access
to projects in JIRA. Go to the **Groups** tab and select **Create group**.
![JIRA create new user](img/jira_create_new_group.png)
---
Give it an optional description and hit **Create group**.
![jira create new group](img/jira_create_new_group_name.png)
---
1. Give the newly-created group write access by going to
**Application access ➔ View configuration** and adding the `gitlab-developers`
group to JIRA Core.
![JIRA group access](img/jira_group_access.png)
---
1. Add the `gitlab` user to the `gitlab-developers` group by going to
**Users ➔ GitLab user ➔ Add group** and selecting the `gitlab-developers`
group from the dropdown menu. Notice that the group says _Access_ which is
what we aim for.
![JIRA add user to group](img/jira_add_user_to_group.png)
---
The JIRA configuration is over. Write down the new JIRA username and its
password as they will be needed when configuring GitLab in the next section.
### Configuring GitLab
>**Notes:**
- The currently supported JIRA versions are `v6.x` and `v7.x.`. GitLab 7.8 or
higher is required.
- GitLab 8.14 introduced a new way to integrate with JIRA which greatly simplified
the configuration options you have to enter. If you are using an older version,
[follow this documentation][jira-repo-docs].
To enable JIRA integration in a project, navigate to your project's
**Services ➔ JIRA** and fill in the required details on the page as described
in the table below.
| Field | Description |
| ----- | ----------- |
| `URL` | The base URL to the JIRA project which is being linked to this GitLab project. E.g., `https://jira.example.com`. |
| `Project key` | The short identifier for your JIRA project, all uppercase, e.g., `PROJ`. |
| `Username` | The user name created in [configuring JIRA step](#configuring-jira). |
| `Password` |The password of the user created in [configuring JIRA step](#configuring-jira). |
| `JIRA issue transition` | This is the ID of a transition that moves issues to a closed state. You can find this number under JIRA workflow administration ([see screenshot](img/jira_workflow_screenshot.png)). |
After saving the configuration, your GitLab project will be able to interact
with the linked JIRA project.
![JIRA service page](img/jira_service_page.png)
---
## JIRA issues
By now you should have [configured JIRA](#configuring-jira) and enabled the
[JIRA service in GitLab](#configuring-gitlab). If everything is set up correctly
you should be able to reference and close JIRA issues by just mentioning their
ID in GitLab commits and merge requests.
### Referencing JIRA Issues
When GitLab project has JIRA issue tracker configured and enabled, mentioning
JIRA issue in GitLab will automatically add a comment in JIRA issue with the
link back to GitLab. This means that in comments in merge requests and commits
referencing an issue, e.g., `PROJECT-7`, will add a comment in JIRA issue in the
format:
```
USER mentioned this issue in RESOURCE_NAME of [PROJECT_NAME|LINK_TO_COMMENT]:
ENTITY_TITLE
```
* `USER` A user that mentioned the issue. This is the link to the user profile in GitLab.
* `LINK_TO_THE_COMMENT` Link to the origin of mention with a name of the entity where JIRA issue was mentioned.
* `RESOURCE_NAME` Kind of resource which referenced the issue. Can be a commit or merge request.
* `PROJECT_NAME` GitLab project name.
* `ENTITY_TITLE` Merge request title or commit message first line.
![example of mentioning or closing the JIRA issue](img/jira_issue_reference.png)
---
### Closing JIRA Issues
JIRA issues can be closed directly from GitLab by using trigger words in
commits and merge requests. When a commit which contains the trigger word
followed by the JIRA issue ID in the commit message is pushed, GitLab will
add a comment in the mentioned JIRA issue and immediately close it (provided
the transition ID was set up correctly).
There are currently three trigger words, and you can use either one to achieve
the same goal:
- `Resolves PROJECT-1`
- `Closes PROJECT-1`
- `Fixes PROJECT-1`
where `PROJECT-1` is the issue ID of the JIRA project.
### JIRA issue closing example
Let's consider the following example:
1. For the project named `PROJECT` in JIRA, we implemented a new feature
and created a merge request in GitLab.
1. This feature was requested in JIRA issue `PROJECT-7` and the merge request
in GitLab contains the improvement
1. In the merge request description we use the issue closing trigger
`Closes PROJECT-7`.
1. Once the merge request is merged, the JIRA issue will be automatically closed
with a comment and an associated link to the commit that resolved the issue.
---
In the following screenshot you can see what the link references to the JIRA
issue look like.
![A Git commit that causes the JIRA issue to be closed](img/jira_merge_request_close.png)
---
Once this merge request is merged, the JIRA issue will be automatically closed
with a link to the commit that resolved the issue.
![The GitLab integration closes JIRA issue](img/jira_service_close_issue.png)
---
![The GitLab integration creates a comment and a link on JIRA issue.](img/jira_service_close_comment.png)
## Troubleshooting
If things don't work as expected that's usually because you have configured
incorrectly the JIRA-GitLab integration.
### GitLab is unable to comment on a ticket
Make sure that the user you set up for GitLab to communicate with JIRA has the
correct access permission to post comments on a ticket and to also transition
the ticket, if you'd like GitLab to also take care of closing them.
JIRA issue references and update comments will not work if the GitLab issue tracker is disabled.
### GitLab is unable to close a ticket
Make sure the `Transition ID` you set within the JIRA settings matches the one
your project needs to close a ticket.
[services-templates]: ../project_services/services_templates.md
[jira-repo-docs]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-13-stable/doc/project_services/jira.md
# GitLab Kubernetes / OpenShift integration This document was moved to [user/project/integrations/kubernetes.md](../user/project/integrations/kubernetes.md).
GitLab can be configured to interact with Kubernetes, or other systems using the
Kubernetes API (such as OpenShift).
Each project can be configured to connect to a different Kubernetes cluster, see
the [configuration](#configuration) section.
If you have a single cluster that you want to use for all your projects,
you can pre-fill the settings page with a default template. To configure the
template, see the [Services Templates](services_templates.md) document.
## Configuration
![Kubernetes configuration settings](img/kubernetes_configuration.png)
The Kubernetes service takes the following arguments:
1. Kubernetes namespace
1. API URL
1. Service token
1. Custom CA bundle
The API URL is the URL that GitLab uses to access the Kubernetes API. Kubernetes
exposes several APIs - we want the "base" URL that is common to all of them,
e.g., `https://kubernetes.example.com` rather than `https://kubernetes.example.com/api/v1`.
GitLab authenticates against Kubernetes using service tokens, which are
scoped to a particular `namespace`. If you don't have a service token yet,
you can follow the
[Kubernetes documentation](http://kubernetes.io/docs/user-guide/service-accounts/)
to create one. You can also view or create service tokens in the
[Kubernetes dashboard](http://kubernetes.io/docs/user-guide/ui/) - visit
`Config -> Secrets`.
Fill in the service token and namespace according to the values you just got.
If the API is using a self-signed TLS certificate, you'll also need to include
the `ca.crt` contents as the `Custom CA bundle`.
## Deployment variables
The Kubernetes service exposes following
[deployment variables](../ci/variables/README.md#deployment-variables) in the
GitLab CI build environment:
- `KUBE_URL` - equal to the API URL
- `KUBE_TOKEN`
- `KUBE_NAMESPACE`
- `KUBE_CA_PEM` - only if a custom CA bundle was specified
## Web terminals
>**NOTE:**
Added in GitLab 8.15. You must be the project owner or have `master` permissions
to use terminals. Support is currently limited to the first container in the
first pod of your environment.
When enabled, the Kubernetes service adds [web terminal](../ci/environments.md#web-terminals)
support to your environments. This is based on the `exec` functionality found in
Docker and Kubernetes, so you get a new shell session within your existing
containers. To use this integration, you should deploy to Kubernetes using
the deployment variables above, ensuring any pods you create are labelled with
`app=$CI_ENVIRONMENT_SLUG`. GitLab will do the rest!
# Mattermost Notifications Service This document was moved to [user/project/integrations/mattermost.md](../user/project/integrations/mattermost.md).
## On Mattermost
To enable Mattermost integration you must create an incoming webhook integration:
1. Sign in to your Mattermost instance
1. Visit incoming webhooks, that will be something like: https://mattermost.example/your_team_name/integrations/incoming_webhooks/add
1. Choose a display name, description and channel, those can be overridden on GitLab
1. Save it, copy the **Webhook URL**, we'll need this later for GitLab.
There might be some cases that Incoming Webhooks are blocked by admin, ask your mattermost admin to enable
it on https://mattermost.example/admin_console/integrations/custom.
Display name override is not enabled by default, you need to ask your admin to enable it on that same section.
## On GitLab
After you set up Mattermost, it's time to set up GitLab.
Go to your project's **Settings > Services > Mattermost Notifications** and you will see a
checkbox with the following events that can be triggered:
- Push
- Issue
- Merge request
- Note
- Tag push
- Build
- Wiki page
Bellow each of these event checkboxes, you will have an input field to insert
which Mattermost channel you want to send that event message, with `#town-square`
being the default. The hash sign is optional.
At the end, fill in your Mattermost details:
| Field | Description |
| ----- | ----------- |
| **Webhook** | The incoming webhooks which you have to setup on Mattermost, it will be something like: http://mattermost.example/hooks/5xo... |
| **Username** | Optional username which can be on messages sent to Mattermost. Fill this in if you want to change the username of the bot. |
| **Notify only broken builds** | If you choose to enable the **Build** event and you want to be only notified about failed builds. |
![Mattermost configuration](img/mattermost_configuration.png)
# Mattermost slash commands This document was moved to [user/project/integrations/mattermost_slash_commands.md](../user/project/integrations/mattermost_slash_commands.md).
> Introduced in GitLab 8.14
Mattermost commands give users an extra interface to perform common operations
from the chat environment. This allows one to, for example, create an issue as
soon as the idea was discussed in Mattermost.
## Prerequisites
Mattermost 3.4 and up is required.
If you have the Omnibus GitLab package installed, Mattermost is already bundled
in it. All you have to do is configure it. Read more in the
[Omnibus GitLab Mattermost documentation][omnimmdocs].
## Automated Configuration
If Mattermost is installed on the same server as GitLab, the configuration process can be
done for you by GitLab.
Go to the Mattermost Slash Command service on your project and click the 'Add to Mattermost' button.
## Manual Configuration
The configuration consists of two parts. First you need to enable the slash
commands in Mattermost and then enable the service in GitLab.
### Step 1. Enable custom slash commands in Mattermost
This step is only required when using a source install, omnibus installs will be
preconfigured with the right settings.
The first thing to do in Mattermost is to enable custom slash commands from
the administrator console.
1. Log in with an account that has admin privileges and navigate to the system
console.
![Mattermost go to console](img/mattermost_goto_console.png)
---
1. Click **Custom integrations** and set **Enable Custom Slash Commands**,
**Enable custom integrations to override usernames**, and **Override
custom integrations to override profile picture icons** to true
![Mattermost console](img/mattermost_console_integrations.png)
---
1. Click **Save** at the bottom to save the changes.
### Step 2. Open the Mattermost slash commands service in GitLab
1. Open a new tab for GitLab and go to your project's settings
**Services ➔ Mattermost command**. A screen will appear with all the values you
need to copy in Mattermost as described in the next step. Leave the window open.
>**Note:**
GitLab will propose some values for the Mattermost settings. The only one
required to copy-paste as-is is the **Request URL**, all the others are just
suggestions.
![Mattermost setup instructions](img/mattermost_config_help.png)
---
1. Proceed to the next step and create a slash command in Mattermost with the
above values.
### Step 3. Create a new custom slash command in Mattermost
Now that you have enabled custom slash commands in Mattermost and opened
the Mattermost slash commands service in GitLab, it's time to copy these values
in a new slash command.
1. Back to Mattermost, under your team page settings, you should see the
**Integrations** option.
![Mattermost team integrations](img/mattermost_team_integrations.png)
---
1. Go to the **Slash Commands** integration and add a new one by clicking the
**Add Slash Command** button.
![Mattermost add command](img/mattermost_add_slash_command.png)
---
1. Fill in the options for the custom command as described in
[step 2](#step-2-open-the-mattermost-slash-commands-service-in-gitlab).
>**Note:**
If you plan on connecting multiple projects, pick a slash command trigger
word that relates to your projects such as `/gitlab-project-name` or even
just `/project-name`. Only use `/gitlab` if you will only connect a single
project to your Mattermost team.
![Mattermost add command configuration](img/mattermost_slash_command_configuration.png)
1. After you setup all the values, copy the token (we will use it below) and
click **Done**.
![Mattermost slash command token](img/mattermost_slash_command_token.png)
### Step 4. Copy the Mattermost token into the Mattermost slash command service
1. In GitLab, paste the Mattermost token you copied in the previous step and
check the **Active** checkbox.
![Mattermost copy token to GitLab](img/mattermost_gitlab_token.png)
1. Click **Save changes** for the changes to take effect.
---
You are now set to start using slash commands in Mattermost that talk to the
GitLab project you configured.
## Authorizing Mattermost to interact with GitLab
The first time a user will interact with the newly created slash commands,
Mattermost will trigger an authorization process.
![Mattermost bot authorize](img/mattermost_bot_auth.png)
This will connect your Mattermost user with your GitLab user. You can
see all authorized chat accounts in your profile's page under **Chat**.
When the authorization process is complete, you can start interacting with
GitLab using the Mattermost commands.
## Available slash commands
The available slash commands are:
| Command | Description | Example |
| ------- | ----------- | ------- |
| <kbd>/&lt;trigger&gt; issue new &lt;title&gt; <kbd>⇧ Shift</kbd>+<kbd>↵ Enter</kbd> &lt;description&gt;</kbd> | Create a new issue in the project that `<trigger>` is tied to. `<description>` is optional. | <samp>/gitlab issue new We need to change the homepage</samp> |
| <kbd>/&lt;trigger&gt; issue show &lt;issue-number&gt;</kbd> | Show the issue with ID `<issue-number>` from the project that `<trigger>` is tied to. | <samp>/gitlab issue show 42</samp> |
| <kbd>/&lt;trigger&gt; deploy &lt;environment&gt; to &lt;environment&gt;</kbd> | Start the CI job that deploys from one environment to another, for example `staging` to `production`. CI/CD must be [properly configured][ciyaml]. | <samp>/gitlab deploy staging to production</samp> |
To see a list of available commands to interact with GitLab, type the
trigger word followed by <kbd>help</kbd>. Example: <samp>/gitlab help</samp>
![Mattermost bot available commands](img/mattermost_bot_available_commands.png)
## Permissions
The permissions to run the [available commands](#available-commands) derive from
the [permissions you have on the project](../user/permissions.md#project).
## Further reading
- [Mattermost slash commands documentation][mmslashdocs]
- [Omnibus GitLab Mattermost][omnimmdocs]
[omnimmdocs]: https://docs.gitlab.com/omnibus/gitlab-mattermost/
[mmslashdocs]: https://docs.mattermost.com/developer/slash-commands.html
[ciyaml]: ../ci/yaml/README.md
# Project Services This document was moved to [user/project/integrations/project_services.md](../user/project/integrations/project_services.md).
Project services allow you to integrate GitLab with other applications. Below
is list of the currently supported ones.
You can find these within GitLab in the Services page under Project Settings if
you are at least a master on the project.
Project Services are a bit like plugins in that they allow a lot of freedom in
adding functionality to GitLab. For example there is also a service that can
send an email every time someone pushes new commits.
Because GitLab is open source we can ship with the code and tests for all
plugins. This allows the community to keep the plugins up to date so that they
always work in newer GitLab versions.
For an overview of what projects services are available without logging in,
please see the [project_services directory][projects-code].
[projects-code]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/models/project_services
Click on the service links to see
further configuration instructions and details. Contributions are welcome.
## Services
| Service | Description |
| ------- | ----------- |
| Asana | Asana - Teamwork without email |
| Assembla | Project Management Software (Source Commits Endpoint) |
| [Atlassian Bamboo CI](bamboo.md) | A continuous integration and build server |
| Buildkite | Continuous integration and deployments |
| [Builds emails](builds_emails.md) | Email the builds status to a list of recipients |
| [Bugzilla](bugzilla.md) | Bugzilla issue tracker |
| Campfire | Simple web-based real-time group chat |
| Custom Issue Tracker | Custom issue tracker |
| Drone CI | Continuous Integration platform built on Docker, written in Go |
| [Emails on push](emails_on_push.md) | Email the commits and diff of each push to a list of recipients |
| External Wiki | Replaces the link to the internal wiki with a link to an external wiki |
| Flowdock | Flowdock is a collaboration web app for technical teams |
| Gemnasium | Gemnasium monitors your project dependencies and alerts you about updates and security vulnerabilities |
| [HipChat](hipchat.md) | Private group chat and IM |
| [Irker (IRC gateway)](irker.md) | Send IRC messages, on update, to a list of recipients through an Irker gateway |
| [JIRA](jira.md) | JIRA issue tracker |
| JetBrains TeamCity CI | A continuous integration and build server |
| [Kubernetes](kubernetes.md) | A containerized deployment service |
| [Mattermost slash commands](mattermost_slash_commands.md) | Mattermost chat and ChatOps slash commands |
| [Mattermost Notifications](mattermost.md) | Receive event notifications in Mattermost |
| [Slack Notifications](slack.md) | Receive event notifications in Slack |
| [Slack slash commands](slack_slash_commands.md) | Slack chat and ChatOps slash commands |
| PivotalTracker | Project Management Software (Source Commits Endpoint) |
| Pushover | Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop |
| [Redmine](redmine.md) | Redmine issue tracker |
## Services Templates
Services templates is a way to set some predefined values in the Service of
your liking which will then be pre-filled on each project's Service.
Read more about [Services Templates in this document](services_templates.md).
# Redmine Service This document was moved to [user/project/integrations/redmine.md](../user/project/integrations/redmine.md).
Go to your project's **Settings > Services > Redmine** and fill in the required
details as described in the table below.
| Field | Description |
| ----- | ----------- |
| `description` | A name for the issue tracker (to differentiate between instances, for example) |
| `project_url` | The URL to the project in Redmine which is being linked to this GitLab project |
| `issues_url` | The URL to the issue in Redmine project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. |
| `new_issue_url` | This is the URL to create a new issue in Redmine for the project linked to this GitLab project |
Once you have configured and enabled Redmine:
- the **Issues** link on the GitLab project pages takes you to the appropriate
Redmine issue index
- clicking **New issue** on the project dashboard creates a new Redmine issue
As an example, below is a configuration for a project named gitlab-ci.
![Redmine configuration](img/redmine_configuration.png)
# Services Templates This document was moved to [user/project/integrations/services_templates.md](../user/project/integrations/services_templates.md).
A GitLab administrator can add a service template that sets a default for each
project. This makes it much easier to configure individual projects.
After the template is created, the template details will be pre-filled on a
project's Service page.
## Enable a Service template
In GitLab's Admin area, navigate to **Service Templates** and choose the
service template you wish to create.
For example, in the image below you can see Redmine.
![Redmine service template](img/services_templates_redmine_example.png)
---
**NOTE:** For each project, you will still need to configure the issue tracking
URLs by replacing `:issues_tracker_id` in the above screenshot with the ID used
by your external issue tracker. Prior to GitLab v7.8, this ID was configured in
the project settings, and GitLab would automatically update the URL configured
in `gitlab.yml`. This behavior is now deprecated and all issue tracker URLs
must be configured directly within the project's **Services** settings.
# Slack Notifications Service This document was moved to [user/project/integrations/slack.md](../user/project/integrations/slack.md).
## On Slack
To enable Slack integration you must create an incoming webhook integration on
Slack:
1. [Sign in to Slack](https://slack.com/signin)
1. Visit [Incoming WebHooks](https://my.slack.com/services/new/incoming-webhook/)
1. Choose the channel name you want to send notifications to.
1. Click **Add Incoming WebHooks Integration**
1. Copy the **Webhook URL**, we'll need this later for GitLab.
## On GitLab
After you set up Slack, it's time to set up GitLab.
Go to your project's **Settings > Integrations > Slack Notifications** and you will see a
checkbox with the following events that can be triggered:
- Push
- Issue
- Merge request
- Note
- Tag push
- Build
- Wiki page
Bellow each of these event checkboxes, you will have an input field to insert
which Slack channel you want to send that event message, with `#general`
being the default. Enter your preferred channel **without** the hash sign (`#`).
At the end, fill in your Slack details:
| Field | Description |
| ----- | ----------- |
| **Webhook** | The [incoming webhook URL][slackhook] which you have to setup on Slack. |
| **Username** | Optional username which can be on messages sent to slack. Fill this in if you want to change the username of the bot. |
| **Notify only broken builds** | If you choose to enable the **Build** event and you want to be only notified about failed builds. |
After you are all done, click **Save changes** for the changes to take effect.
>**Note:**
You can set "branch,pushed,Compare changes" as highlight words on your Slack
profile settings, so that you can be aware of new commits when somebody pushes
them.
![Slack configuration](img/slack_configuration.png)
[slackhook]: https://my.slack.com/services/new/incoming-webhook
# Slack slash commands This document was moved to [user/project/integrations/slack_slash_commands.md](../user/project/integrations/slack_slash_commands.md).
> Introduced in GitLab 8.15
Slack commands give users an extra interface to perform common operations
from the chat environment. This allows one to, for example, create an issue as
soon as the idea was discussed in chat.
For all available commands try the help subcommand, for example: `/gitlab help`,
all review the [full list of commands](../integration/chat_commands.md).
## Prerequisites
A [team](https://get.slack.help/hc/en-us/articles/217608418-Creating-a-team) in Slack should be created beforehand, GitLab cannot create it for you.
## Configuration
First, navigate to the Slack Slash commands service page, found at your project's
**Settings** > **Services**, and you find the instructions there:
![Slack setup instructions](img/slack_setup.png)
Once you've followed the instructions, mark the service as active and insert the token
you've received from Slack. After saving the service you are good to go!
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
If you have non-GitLab web services running on your GitLab server or within its local network, these may be vulnerable to exploitation via Webhooks. If you have non-GitLab web services running on your GitLab server or within its local network, these may be vulnerable to exploitation via Webhooks.
With [Webhooks](../web_hooks/web_hooks.md), you and your project masters and owners can set up URLs to be triggered when specific things happen to projects. Normally, these requests are sent to external web services specifically set up for this purpose, that process the request and its attached data in some appropriate way. With [Webhooks](../user/project/integrations/webhooks.md), you and your project masters and owners can set up URLs to be triggered when specific things happen to projects. Normally, these requests are sent to external web services specifically set up for this purpose, that process the request and its attached data in some appropriate way.
Things get hairy, however, when a Webhook is set up with a URL that doesn't point to an external, but to an internal service, that may do something completely unintended when the webhook is triggered and the POST request is sent. Things get hairy, however, when a Webhook is set up with a URL that doesn't point to an external, but to an internal service, that may do something completely unintended when the webhook is triggered and the POST request is sent.
...@@ -10,4 +10,4 @@ Because Webhook requests are made by the GitLab server itself, these have comple ...@@ -10,4 +10,4 @@ Because Webhook requests are made by the GitLab server itself, these have comple
If a web service does not require authentication, Webhooks can be used to trigger destructive commands by getting the GitLab server to make POST requests to endpoints like "http://localhost:123/some-resource/delete". If a web service does not require authentication, Webhooks can be used to trigger destructive commands by getting the GitLab server to make POST requests to endpoints like "http://localhost:123/some-resource/delete".
To prevent this type of exploitation from happening, make sure that you are aware of every web service GitLab could potentially have access to, and that all of these are set up to require authentication for every potentially destructive command. Enabling authentication but leaving a default password is not enough. To prevent this type of exploitation from happening, make sure that you are aware of every web service GitLab could potentially have access to, and that all of these are set up to require authentication for every potentially destructive command. Enabling authentication but leaving a default password is not enough.
\ No newline at end of file
...@@ -189,10 +189,10 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project ...@@ -189,10 +189,10 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
#### 3.9. Integrations #### 3.9. Integrations
1. [How to Integrate JIRA and Jenkins with GitLab - Video](https://gitlabmeetings.webex.com/gitlabmeetings/ldr.php?RCID=44b548147a67ab4d8a62274047146415) 1. [How to Integrate JIRA and Jenkins with GitLab - Video](https://gitlabmeetings.webex.com/gitlabmeetings/ldr.php?RCID=44b548147a67ab4d8a62274047146415)
1. [How to Integrate Jira with GitLab](https://docs.gitlab.com/ee/integration/jira.html) 1. [How to Integrate Jira with GitLab](https://docs.gitlab.com/ce/user/project/integrations/jira.html)
1. [How to Integrate Jenkins with GitLab](https://docs.gitlab.com/ee/integration/jenkins.html) 1. [How to Integrate Jenkins with GitLab](https://docs.gitlab.com/ee/integration/jenkins.html)
1. [How to Integrate Bamboo with GitLab](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/project_services/bamboo.md) 1. [How to Integrate Bamboo with GitLab](https://docs.gitlab.com/ce/user/project/integrations/bamboo.html)
1. [How to Integrate Slack with GitLab](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/slack.md) 1. [How to Integrate Slack with GitLab](https://docs.gitlab.com/ce/user/project/integrations/slack.html)
1. [How to Integrate Convox with GitLab](https://about.gitlab.com/2016/06/09/continuous-delivery-with-gitlab-and-convox/) 1. [How to Integrate Convox with GitLab](https://about.gitlab.com/2016/06/09/continuous-delivery-with-gitlab-and-convox/)
1. [Getting Started with GitLab and Shippable CI](https://about.gitlab.com/2016/05/05/getting-started-gitlab-and-shippable/) 1. [Getting Started with GitLab and Shippable CI](https://about.gitlab.com/2016/05/05/getting-started-gitlab-and-shippable/)
......
...@@ -573,7 +573,7 @@ A [model](http://www.umsl.edu/~hugheyd/is6840/waterfall.html) of building softwa ...@@ -573,7 +573,7 @@ A [model](http://www.umsl.edu/~hugheyd/is6840/waterfall.html) of building softwa
### Webhooks ### Webhooks
A way for for an app to [provide](https://docs.gitlab.com/ce/web_hooks/web_hooks.html) other applications with real-time information (e.g., send a message to a slack channel when a commit is pushed.) Read about setting up [custom git hooks](https://gitlab.com/help/administration/custom_hooks.md) for when webhooks are insufficient. A way for for an app to [provide](https://docs.gitlab.com/ce/user/project/integrations/webhooks.html) other applications with real-time information (e.g., send a message to a slack channel when a commit is pushed.) Read about setting up [custom git hooks](https://gitlab.com/help/administration/custom_hooks.md) for when webhooks are insufficient.
### Wiki ### Wiki
......
# Atlassian Bamboo CI Service
GitLab provides integration with Atlassian Bamboo for continuous integration.
When configured, pushes to a project will trigger a build in Bamboo automatically.
Merge requests will also display CI status showing whether the build is pending,
failed, or completed successfully. It also provides a link to the Bamboo build
page for more information.
Bamboo doesn't quite provide the same features as a traditional build system when
it comes to accepting webhooks and commit data. There are a few things that
need to be configured in a Bamboo build plan before GitLab can integrate.
## Setup
### Complete these steps in Bamboo:
1. Navigate to a Bamboo build plan and choose 'Configure plan' from the 'Actions'
dropdown.
1. Select the 'Triggers' tab.
1. Click 'Add trigger'.
1. Enter a description such as 'GitLab trigger'
1. Choose 'Repository triggers the build when changes are committed'
1. Check one or more repositories checkboxes
1. Enter the GitLab IP address in the 'Trigger IP addresses' box. This is a
whitelist of IP addresses that are allowed to trigger Bamboo builds.
1. Save the trigger.
1. In the left pane, select a build stage. If you have multiple build stages
you want to select the last stage that contains the git checkout task.
1. Select the 'Miscellaneous' tab.
1. Under 'Pattern Match Labelling' put '${bamboo.repository.revision.number}'
in the 'Labels' box.
1. Save
Bamboo is now ready to accept triggers from GitLab. Next, set up the Bamboo
service in GitLab
### Complete these steps in GitLab:
1. Navigate to the project you want to configure to trigger builds.
1. Select 'Settings' in the top navigation.
1. Select 'Services' in the left navigation.
1. Click 'Atlassian Bamboo CI'
1. Select the 'Active' checkbox.
1. Enter the base URL of your Bamboo server. 'https://bamboo.example.com'
1. Enter the build key from your Bamboo build plan. Build keys are a short,
all capital letter, identifier that is unique. It will be something like PR-BLD
1. If necessary, enter username and password for a Bamboo user that has
access to trigger the build plan. Leave these fields blank if you do not require
authentication.
1. Save or optionally click 'Test Settings'. Please note that 'Test Settings'
will actually trigger a build in Bamboo.
## Troubleshooting
If builds are not triggered, these are a couple of things to keep in mind.
1. Ensure you entered the right GitLab IP address in Bamboo under 'Trigger
IP addresses'.
1. Remember that GitLab only triggers builds on push events. A commit via the
web interface will not trigger CI currently.
# Bugzilla Service
Go to your project's **Settings > Services > Bugzilla** and fill in the required
details as described in the table below.
| Field | Description |
| ----- | ----------- |
| `description` | A name for the issue tracker (to differentiate between instances, for example) |
| `project_url` | The URL to the project in Bugzilla which is being linked to this GitLab project. Note that the `project_url` requires PRODUCT_NAME to be updated with the product/project name in Bugzilla. |
| `issues_url` | The URL to the issue in Bugzilla project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. |
| `new_issue_url` | This is the URL to create a new issue in Bugzilla for the project linked to this GitLab project. Note that the `new_issue_url` requires PRODUCT_NAME to be updated with the product/project name in Bugzilla. |
Once you have configured and enabled Bugzilla:
- the **Issues** link on the GitLab project pages takes you to the appropriate
Bugzilla product page
- clicking **New issue** on the project dashboard takes you to Bugzilla for entering a new issue
## Enabling build emails
To receive e-mail notifications about the result status of your builds, visit
your project's **Settings > Services > Builds emails** and activate the service.
In the _Recipients_ area, provide a list of e-mails separated by comma.
Check the _Add pusher_ checkbox if you want the committer to also receive
e-mail notifications about each build's status.
If you enable the _Notify only broken builds_ option, e-mail notifications will
be sent only for failed builds.
---
![Builds emails service settings](img/builds_emails_service.png)
## Enabling emails on push
To receive email notifications for every change that is pushed to the project, visit
your project's **Settings > Services > Emails on push** and activate the service.
In the _Recipients_ area, provide a list of emails separated by commas.
You can configure any of the following settings depending on your preference.
+ **Push events** - Email will be triggered when a push event is recieved
+ **Tag push events** - Email will be triggered when a tag is created and pushed
+ **Send from committer** - Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. `user@gitlab.com`).
+ **Disable code diffs** - Don't include possibly sensitive code diffs in notification body.
---
![Email on push service settings](img/emails_on_push_service.png)
# Atlassian HipChat
GitLab provides a way to send HipChat notifications upon a number of events,
such as when a user pushes code, creates a branch or tag, adds a comment, and
creates a merge request.
## Setup
GitLab requires the use of a HipChat v2 API token to work. v1 tokens are
not supported at this time. Note the differences between v1 and v2 tokens:
HipChat v1 API (legacy) supports "API Auth Tokens" in the Group API menu. A v1
token is allowed to send messages to *any* room.
HipChat v2 API has tokens that are can be created using the Integrations tab
in the Group or Room admin page. By design, these are lightweight tokens that
allow GitLab to send messages only to *one* room.
### Complete these steps in HipChat:
1. Go to: https://admin.hipchat.com/admin
1. Click on "Group Admin" -> "Integrations".
1. Find "Build Your Own!" and click "Create".
1. Select the desired room, name the integration "GitLab", and click "Create".
1. In the "Send messages to this room by posting this URL" column, you should
see a URL in the format:
```
https://api.hipchat.com/v2/room/<room>/notification?auth_token=<token>
```
HipChat is now ready to accept messages from GitLab. Next, set up the HipChat
service in GitLab.
### Complete these steps in GitLab:
1. Navigate to the project you want to configure for notifications.
1. Select "Settings" in the top navigation.
1. Select "Services" in the left navigation.
1. Click "HipChat".
1. Select the "Active" checkbox.
1. Insert the `token` field from the URL into the `Token` field on the Web page.
1. Insert the `room` field from the URL into the `Room` field on the Web page.
1. Save or optionally click "Test Settings".
## Troubleshooting
If you do not see notifications, make sure you are using a HipChat v2 API
token, not a v1 token.
Note that the v2 token is tied to a specific room. If you want to be able to
specify arbitrary rooms, you can create an API token for a specific user in
HipChat under "Account settings" and "API access". Use the `XXX` value under
`auth_token=XXX`.
# Project integrations
## Project services
Project services allow you to integrate GitLab with other applications.
They are a bit like plugins in that they allow a lot of freedom in
adding functionality to GitLab.
[Learn more about project services.](project_services.md)
## Webhooks
Project webhooks allow you to trigger a URL if for example new code is pushed or
a new issue is created. You can configure webhooks to listen for specific events
like pushes, issues or merge requests. GitLab will send a POST request with data
to the webhook URL.
[Learn more about webhooks.](webhooks.md)
# Irker IRC Gateway
GitLab provides a way to push update messages to an Irker server. When
configured, pushes to a project will trigger the service to send data directly
to the Irker server.
See the project homepage for further info: https://gitlab.com/esr/irker
## Needed setup
You will first need an Irker daemon. You can download the Irker code from its
repository on https://gitlab.com/esr/irker:
```
git clone https://gitlab.com/esr/irker.git
```
Once you have downloaded the code, you can run the python script named `irkerd`.
This script is the gateway script, it acts both as an IRC client, for sending
messages to an IRC server obviously, and as a TCP server, for receiving messages
from the GitLab service.
If the Irker server runs on the same machine, you are done. If not, you will
need to follow the firsts steps of the next section.
## Complete these steps in GitLab:
1. Navigate to the project you want to configure for notifications.
1. Select "Settings" in the top navigation.
1. Select "Services" in the left navigation.
1. Click "Irker".
1. Select the "Active" checkbox.
1. Enter the server host address where `irkerd` runs (defaults to `localhost`)
in the `Server host` field on the Web page
1. Enter the server port of `irkerd` (e.g. defaults to 6659) in the
`Server port` field on the Web page.
1. Optional: if `Default IRC URI` is set, it has to be in the format
`irc[s]://domain.name` and will be prepend to each and every channel provided
by the user which is not a full URI.
1. Specify the recipients (e.g. #channel1, user1, etc.)
1. Save or optionally click "Test Settings".
## Note on Irker recipients
Irker accepts channel names of the form `chan` and `#chan`, both for the
`#chan` channel. If you want to send messages in query, you will need to add
`,isnick` after the channel name, in this form: `Aorimn,isnick`. In this latter
case, `Aorimn` is treated as a nick and no more as a channel name.
Irker can also join password-protected channels. Users need to append
`?key=thesecretpassword` to the chan name.
# GitLab JIRA integration
GitLab can be configured to interact with JIRA. Configuration happens via
user name and password. Connecting to a JIRA server via CAS is not possible.
Each project can be configured to connect to a different JIRA instance, see the
[configuration](#configuration) section. If you have one JIRA instance you can
pre-fill the settings page with a default template. To configure the template
see the [Services Templates][services-templates] document.
Once the project is connected to JIRA, you can reference and close the issues
in JIRA directly from GitLab.
## Configuration
In order to enable the JIRA service in GitLab, you need to first configure the
project in JIRA and then enter the correct values in GitLab.
### Configuring JIRA
We need to create a user in JIRA which will have access to all projects that
need to integrate with GitLab. Login to your JIRA instance as admin and under
Administration go to User Management and create a new user.
As an example, we'll create a user named `gitlab` and add it to `JIRA-developers`
group.
**It is important that the user `GitLab` has write-access to projects in JIRA**
We have split this stage in steps so it is easier to follow.
---
1. Login to your JIRA instance as an administrator and under **Administration**
go to **User Management** to create a new user.
![JIRA user management link](img/jira_user_management_link.png)
---
1. The next step is to create a new user (e.g., `gitlab`) who has write access
to projects in JIRA. Enter the user's name and a _valid_ e-mail address
since JIRA sends a verification e-mail to set-up the password.
_**Note:** JIRA creates the username automatically by using the e-mail
prefix. You can change it later if you want._
![JIRA create new user](img/jira_create_new_user.png)
---
1. Now, let's create a `gitlab-developers` group which will have write access
to projects in JIRA. Go to the **Groups** tab and select **Create group**.
![JIRA create new user](img/jira_create_new_group.png)
---
Give it an optional description and hit **Create group**.
![jira create new group](img/jira_create_new_group_name.png)
---
1. Give the newly-created group write access by going to
**Application access ➔ View configuration** and adding the `gitlab-developers`
group to JIRA Core.
![JIRA group access](img/jira_group_access.png)
---
1. Add the `gitlab` user to the `gitlab-developers` group by going to
**Users ➔ GitLab user ➔ Add group** and selecting the `gitlab-developers`
group from the dropdown menu. Notice that the group says _Access_ which is
what we aim for.
![JIRA add user to group](img/jira_add_user_to_group.png)
---
The JIRA configuration is over. Write down the new JIRA username and its
password as they will be needed when configuring GitLab in the next section.
### Configuring GitLab
>**Notes:**
- The currently supported JIRA versions are `v6.x` and `v7.x.`. GitLab 7.8 or
higher is required.
- GitLab 8.14 introduced a new way to integrate with JIRA which greatly simplified
the configuration options you have to enter. If you are using an older version,
[follow this documentation][jira-repo-old-docs].
To enable JIRA integration in a project, navigate to your project's
**Services ➔ JIRA** and fill in the required details on the page as described
in the table below.
| Field | Description |
| ----- | ----------- |
| `URL` | The base URL to the JIRA project which is being linked to this GitLab project. E.g., `https://jira.example.com`. |
| `Project key` | The short identifier for your JIRA project, all uppercase, e.g., `PROJ`. |
| `Username` | The user name created in [configuring JIRA step](#configuring-jira). |
| `Password` |The password of the user created in [configuring JIRA step](#configuring-jira). |
| `JIRA issue transition` | This is the ID of a transition that moves issues to a closed state. You can find this number under JIRA workflow administration ([see screenshot](img/jira_workflow_screenshot.png)). |
After saving the configuration, your GitLab project will be able to interact
with the linked JIRA project.
![JIRA service page](img/jira_service_page.png)
---
## JIRA issues
By now you should have [configured JIRA](#configuring-jira) and enabled the
[JIRA service in GitLab](#configuring-gitlab). If everything is set up correctly
you should be able to reference and close JIRA issues by just mentioning their
ID in GitLab commits and merge requests.
### Referencing JIRA Issues
When GitLab project has JIRA issue tracker configured and enabled, mentioning
JIRA issue in GitLab will automatically add a comment in JIRA issue with the
link back to GitLab. This means that in comments in merge requests and commits
referencing an issue, e.g., `PROJECT-7`, will add a comment in JIRA issue in the
format:
```
USER mentioned this issue in RESOURCE_NAME of [PROJECT_NAME|LINK_TO_COMMENT]:
ENTITY_TITLE
```
* `USER` A user that mentioned the issue. This is the link to the user profile in GitLab.
* `LINK_TO_THE_COMMENT` Link to the origin of mention with a name of the entity where JIRA issue was mentioned.
* `RESOURCE_NAME` Kind of resource which referenced the issue. Can be a commit or merge request.
* `PROJECT_NAME` GitLab project name.
* `ENTITY_TITLE` Merge request title or commit message first line.
![example of mentioning or closing the JIRA issue](img/jira_issue_reference.png)
---
### Closing JIRA Issues
JIRA issues can be closed directly from GitLab by using trigger words in
commits and merge requests. When a commit which contains the trigger word
followed by the JIRA issue ID in the commit message is pushed, GitLab will
add a comment in the mentioned JIRA issue and immediately close it (provided
the transition ID was set up correctly).
There are currently three trigger words, and you can use either one to achieve
the same goal:
- `Resolves PROJECT-1`
- `Closes PROJECT-1`
- `Fixes PROJECT-1`
where `PROJECT-1` is the issue ID of the JIRA project.
### JIRA issue closing example
Let's consider the following example:
1. For the project named `PROJECT` in JIRA, we implemented a new feature
and created a merge request in GitLab.
1. This feature was requested in JIRA issue `PROJECT-7` and the merge request
in GitLab contains the improvement
1. In the merge request description we use the issue closing trigger
`Closes PROJECT-7`.
1. Once the merge request is merged, the JIRA issue will be automatically closed
with a comment and an associated link to the commit that resolved the issue.
---
In the following screenshot you can see what the link references to the JIRA
issue look like.
![A Git commit that causes the JIRA issue to be closed](img/jira_merge_request_close.png)
---
Once this merge request is merged, the JIRA issue will be automatically closed
with a link to the commit that resolved the issue.
![The GitLab integration closes JIRA issue](img/jira_service_close_issue.png)
---
![The GitLab integration creates a comment and a link on JIRA issue.](img/jira_service_close_comment.png)
## Troubleshooting
If things don't work as expected that's usually because you have configured
incorrectly the JIRA-GitLab integration.
### GitLab is unable to comment on a ticket
Make sure that the user you set up for GitLab to communicate with JIRA has the
correct access permission to post comments on a ticket and to also transition
the ticket, if you'd like GitLab to also take care of closing them.
JIRA issue references and update comments will not work if the GitLab issue tracker is disabled.
### GitLab is unable to close a ticket
Make sure the `Transition ID` you set within the JIRA settings matches the one
your project needs to close a ticket.
[services-templates]: services_templates.md
[jira-repo-old-docs]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-13-stable/doc/project_services/jira.md
# GitLab Kubernetes / OpenShift integration
GitLab can be configured to interact with Kubernetes, or other systems using the
Kubernetes API (such as OpenShift).
Each project can be configured to connect to a different Kubernetes cluster, see
the [configuration](#configuration) section.
If you have a single cluster that you want to use for all your projects,
you can pre-fill the settings page with a default template. To configure the
template, see the [Services Templates](services_templates.md) document.
## Configuration
![Kubernetes configuration settings](img/kubernetes_configuration.png)
The Kubernetes service takes the following arguments:
1. Kubernetes namespace
1. API URL
1. Service token
1. Custom CA bundle
The API URL is the URL that GitLab uses to access the Kubernetes API. Kubernetes
exposes several APIs - we want the "base" URL that is common to all of them,
e.g., `https://kubernetes.example.com` rather than `https://kubernetes.example.com/api/v1`.
GitLab authenticates against Kubernetes using service tokens, which are
scoped to a particular `namespace`. If you don't have a service token yet,
you can follow the
[Kubernetes documentation](http://kubernetes.io/docs/user-guide/service-accounts/)
to create one. You can also view or create service tokens in the
[Kubernetes dashboard](http://kubernetes.io/docs/user-guide/ui/) - visit
`Config -> Secrets`.
Fill in the service token and namespace according to the values you just got.
If the API is using a self-signed TLS certificate, you'll also need to include
the `ca.crt` contents as the `Custom CA bundle`.
## Deployment variables
The Kubernetes service exposes following
[deployment variables](../ci/variables/README.md#deployment-variables) in the
GitLab CI build environment:
- `KUBE_URL` - equal to the API URL
- `KUBE_TOKEN`
- `KUBE_NAMESPACE`
- `KUBE_CA_PEM` - only if a custom CA bundle was specified
## Web terminals
>**NOTE:**
Added in GitLab 8.15. You must be the project owner or have `master` permissions
to use terminals. Support is currently limited to the first container in the
first pod of your environment.
When enabled, the Kubernetes service adds [web terminal](../ci/environments.md#web-terminals)
support to your environments. This is based on the `exec` functionality found in
Docker and Kubernetes, so you get a new shell session within your existing
containers. To use this integration, you should deploy to Kubernetes using
the deployment variables above, ensuring any pods you create are labelled with
`app=$CI_ENVIRONMENT_SLUG`. GitLab will do the rest!
# Mattermost Notifications Service
## On Mattermost
To enable Mattermost integration you must create an incoming webhook integration:
1. Sign in to your Mattermost instance
1. Visit incoming webhooks, that will be something like: https://mattermost.example/your_team_name/integrations/incoming_webhooks/add
1. Choose a display name, description and channel, those can be overridden on GitLab
1. Save it, copy the **Webhook URL**, we'll need this later for GitLab.
There might be some cases that Incoming Webhooks are blocked by admin, ask your mattermost admin to enable
it on https://mattermost.example/admin_console/integrations/custom.
Display name override is not enabled by default, you need to ask your admin to enable it on that same section.
## On GitLab
After you set up Mattermost, it's time to set up GitLab.
Go to your project's **Settings > Services > Mattermost Notifications** and you will see a
checkbox with the following events that can be triggered:
- Push
- Issue
- Merge request
- Note
- Tag push
- Build
- Wiki page
Bellow each of these event checkboxes, you will have an input field to insert
which Mattermost channel you want to send that event message, with `#town-square`
being the default. The hash sign is optional.
At the end, fill in your Mattermost details:
| Field | Description |
| ----- | ----------- |
| **Webhook** | The incoming webhooks which you have to setup on Mattermost, it will be something like: http://mattermost.example/hooks/5xo... |
| **Username** | Optional username which can be on messages sent to Mattermost. Fill this in if you want to change the username of the bot. |
| **Notify only broken builds** | If you choose to enable the **Build** event and you want to be only notified about failed builds. |
![Mattermost configuration](img/mattermost_configuration.png)
# Mattermost slash commands
> Introduced in GitLab 8.14
Mattermost commands give users an extra interface to perform common operations
from the chat environment. This allows one to, for example, create an issue as
soon as the idea was discussed in Mattermost.
## Prerequisites
Mattermost 3.4 and up is required.
If you have the Omnibus GitLab package installed, Mattermost is already bundled
in it. All you have to do is configure it. Read more in the
[Omnibus GitLab Mattermost documentation][omnimmdocs].
## Automated Configuration
If Mattermost is installed on the same server as GitLab, the configuration process can be
done for you by GitLab.
Go to the Mattermost Slash Command service on your project and click the 'Add to Mattermost' button.
## Manual Configuration
The configuration consists of two parts. First you need to enable the slash
commands in Mattermost and then enable the service in GitLab.
### Step 1. Enable custom slash commands in Mattermost
This step is only required when using a source install, omnibus installs will be
preconfigured with the right settings.
The first thing to do in Mattermost is to enable custom slash commands from
the administrator console.
1. Log in with an account that has admin privileges and navigate to the system
console.
![Mattermost go to console](img/mattermost_goto_console.png)
---
1. Click **Custom integrations** and set **Enable Custom Slash Commands**,
**Enable custom integrations to override usernames**, and **Override
custom integrations to override profile picture icons** to true
![Mattermost console](img/mattermost_console_integrations.png)
---
1. Click **Save** at the bottom to save the changes.
### Step 2. Open the Mattermost slash commands service in GitLab
1. Open a new tab for GitLab and go to your project's settings
**Services ➔ Mattermost command**. A screen will appear with all the values you
need to copy in Mattermost as described in the next step. Leave the window open.
>**Note:**
GitLab will propose some values for the Mattermost settings. The only one
required to copy-paste as-is is the **Request URL**, all the others are just
suggestions.
![Mattermost setup instructions](img/mattermost_config_help.png)
---
1. Proceed to the next step and create a slash command in Mattermost with the
above values.
### Step 3. Create a new custom slash command in Mattermost
Now that you have enabled custom slash commands in Mattermost and opened
the Mattermost slash commands service in GitLab, it's time to copy these values
in a new slash command.
1. Back to Mattermost, under your team page settings, you should see the
**Integrations** option.
![Mattermost team integrations](img/mattermost_team_integrations.png)
---
1. Go to the **Slash Commands** integration and add a new one by clicking the
**Add Slash Command** button.
![Mattermost add command](img/mattermost_add_slash_command.png)
---
1. Fill in the options for the custom command as described in
[step 2](#step-2-open-the-mattermost-slash-commands-service-in-gitlab).
>**Note:**
If you plan on connecting multiple projects, pick a slash command trigger
word that relates to your projects such as `/gitlab-project-name` or even
just `/project-name`. Only use `/gitlab` if you will only connect a single
project to your Mattermost team.
![Mattermost add command configuration](img/mattermost_slash_command_configuration.png)
1. After you setup all the values, copy the token (we will use it below) and
click **Done**.
![Mattermost slash command token](img/mattermost_slash_command_token.png)
### Step 4. Copy the Mattermost token into the Mattermost slash command service
1. In GitLab, paste the Mattermost token you copied in the previous step and
check the **Active** checkbox.
![Mattermost copy token to GitLab](img/mattermost_gitlab_token.png)
1. Click **Save changes** for the changes to take effect.
---
You are now set to start using slash commands in Mattermost that talk to the
GitLab project you configured.
## Authorizing Mattermost to interact with GitLab
The first time a user will interact with the newly created slash commands,
Mattermost will trigger an authorization process.
![Mattermost bot authorize](img/mattermost_bot_auth.png)
This will connect your Mattermost user with your GitLab user. You can
see all authorized chat accounts in your profile's page under **Chat**.
When the authorization process is complete, you can start interacting with
GitLab using the Mattermost commands.
## Available slash commands
The available slash commands are:
| Command | Description | Example |
| ------- | ----------- | ------- |
| <kbd>/&lt;trigger&gt; issue new &lt;title&gt; <kbd>⇧ Shift</kbd>+<kbd>↵ Enter</kbd> &lt;description&gt;</kbd> | Create a new issue in the project that `<trigger>` is tied to. `<description>` is optional. | <samp>/gitlab issue new We need to change the homepage</samp> |
| <kbd>/&lt;trigger&gt; issue show &lt;issue-number&gt;</kbd> | Show the issue with ID `<issue-number>` from the project that `<trigger>` is tied to. | <samp>/gitlab issue show 42</samp> |
| <kbd>/&lt;trigger&gt; deploy &lt;environment&gt; to &lt;environment&gt;</kbd> | Start the CI job that deploys from one environment to another, for example `staging` to `production`. CI/CD must be [properly configured][ciyaml]. | <samp>/gitlab deploy staging to production</samp> |
To see a list of available commands to interact with GitLab, type the
trigger word followed by <kbd>help</kbd>. Example: <samp>/gitlab help</samp>
![Mattermost bot available commands](img/mattermost_bot_available_commands.png)
## Permissions
The permissions to run the [available commands](#available-commands) derive from
the [permissions you have on the project](../user/permissions.md#project).
## Further reading
- [Mattermost slash commands documentation][mmslashdocs]
- [Omnibus GitLab Mattermost][omnimmdocs]
[omnimmdocs]: https://docs.gitlab.com/omnibus/gitlab-mattermost/
[mmslashdocs]: https://docs.mattermost.com/developer/slash-commands.html
[ciyaml]: ../ci/yaml/README.md
# Project Services
Project services allow you to integrate GitLab with other applications. Below
is list of the currently supported ones.
You can find these within GitLab in the Services page under Project Settings if
you are at least a master on the project.
Project Services are a bit like plugins in that they allow a lot of freedom in
adding functionality to GitLab. For example there is also a service that can
send an email every time someone pushes new commits.
Because GitLab is open source we can ship with the code and tests for all
plugins. This allows the community to keep the plugins up to date so that they
always work in newer GitLab versions.
For an overview of what projects services are available without logging in,
please see the [project_services directory][projects-code].
[projects-code]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/models/project_services
Click on the service links to see
further configuration instructions and details. Contributions are welcome.
## Services
| Service | Description |
| ------- | ----------- |
| Asana | Asana - Teamwork without email |
| Assembla | Project Management Software (Source Commits Endpoint) |
| [Atlassian Bamboo CI](bamboo.md) | A continuous integration and build server |
| Buildkite | Continuous integration and deployments |
| [Builds emails](builds_emails.md) | Email the builds status to a list of recipients |
| [Bugzilla](bugzilla.md) | Bugzilla issue tracker |
| Campfire | Simple web-based real-time group chat |
| Custom Issue Tracker | Custom issue tracker |
| Drone CI | Continuous Integration platform built on Docker, written in Go |
| [Emails on push](emails_on_push.md) | Email the commits and diff of each push to a list of recipients |
| External Wiki | Replaces the link to the internal wiki with a link to an external wiki |
| Flowdock | Flowdock is a collaboration web app for technical teams |
| Gemnasium | Gemnasium monitors your project dependencies and alerts you about updates and security vulnerabilities |
| [HipChat](hipchat.md) | Private group chat and IM |
| [Irker (IRC gateway)](irker.md) | Send IRC messages, on update, to a list of recipients through an Irker gateway |
| [JIRA](jira.md) | JIRA issue tracker |
| JetBrains TeamCity CI | A continuous integration and build server |
| [Kubernetes](kubernetes.md) | A containerized deployment service |
| [Mattermost slash commands](mattermost_slash_commands.md) | Mattermost chat and ChatOps slash commands |
| [Mattermost Notifications](mattermost.md) | Receive event notifications in Mattermost |
| [Slack Notifications](slack.md) | Receive event notifications in Slack |
| [Slack slash commands](slack_slash_commands.md) | Slack chat and ChatOps slash commands |
| PivotalTracker | Project Management Software (Source Commits Endpoint) |
| Pushover | Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop |
| [Redmine](redmine.md) | Redmine issue tracker |
## Services Templates
Services templates is a way to set some predefined values in the Service of
your liking which will then be pre-filled on each project's Service.
Read more about [Services Templates in this document](services_templates.md).
# Redmine Service
Go to your project's **Settings > Services > Redmine** and fill in the required
details as described in the table below.
| Field | Description |
| ----- | ----------- |
| `description` | A name for the issue tracker (to differentiate between instances, for example) |
| `project_url` | The URL to the project in Redmine which is being linked to this GitLab project |
| `issues_url` | The URL to the issue in Redmine project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. |
| `new_issue_url` | This is the URL to create a new issue in Redmine for the project linked to this GitLab project |
Once you have configured and enabled Redmine:
- the **Issues** link on the GitLab project pages takes you to the appropriate
Redmine issue index
- clicking **New issue** on the project dashboard creates a new Redmine issue
As an example, below is a configuration for a project named gitlab-ci.
![Redmine configuration](img/redmine_configuration.png)
# Services Templates
A GitLab administrator can add a service template that sets a default for each
project. This makes it much easier to configure individual projects.
After the template is created, the template details will be pre-filled on a
project's Service page.
## Enable a Service template
In GitLab's Admin area, navigate to **Service Templates** and choose the
service template you wish to create.
For example, in the image below you can see Redmine.
![Redmine service template](img/services_templates_redmine_example.png)
---
**NOTE:** For each project, you will still need to configure the issue tracking
URLs by replacing `:issues_tracker_id` in the above screenshot with the ID used
by your external issue tracker. Prior to GitLab v7.8, this ID was configured in
the project settings, and GitLab would automatically update the URL configured
in `gitlab.yml`. This behavior is now deprecated and all issue tracker URLs
must be configured directly within the project's **Services** settings.
# Slack Notifications Service
## On Slack
To enable Slack integration you must create an incoming webhook integration on
Slack:
1. [Sign in to Slack](https://slack.com/signin)
1. Visit [Incoming WebHooks](https://my.slack.com/services/new/incoming-webhook/)
1. Choose the channel name you want to send notifications to.
1. Click **Add Incoming WebHooks Integration**
1. Copy the **Webhook URL**, we'll need this later for GitLab.
## On GitLab
After you set up Slack, it's time to set up GitLab.
Go to your project's **Settings > Integrations > Slack Notifications** and you will see a
checkbox with the following events that can be triggered:
- Push
- Issue
- Merge request
- Note
- Tag push
- Build
- Wiki page
Bellow each of these event checkboxes, you will have an input field to insert
which Slack channel you want to send that event message, with `#general`
being the default. Enter your preferred channel **without** the hash sign (`#`).
At the end, fill in your Slack details:
| Field | Description |
| ----- | ----------- |
| **Webhook** | The [incoming webhook URL][slackhook] which you have to setup on Slack. |
| **Username** | Optional username which can be on messages sent to slack. Fill this in if you want to change the username of the bot. |
| **Notify only broken builds** | If you choose to enable the **Build** event and you want to be only notified about failed builds. |
After you are all done, click **Save changes** for the changes to take effect.
>**Note:**
You can set "branch,pushed,Compare changes" as highlight words on your Slack
profile settings, so that you can be aware of new commits when somebody pushes
them.
![Slack configuration](img/slack_configuration.png)
[slackhook]: https://my.slack.com/services/new/incoming-webhook
# Slack slash commands
> Introduced in GitLab 8.15
Slack commands give users an extra interface to perform common operations
from the chat environment. This allows one to, for example, create an issue as
soon as the idea was discussed in chat.
For all available commands try the help subcommand, for example: `/gitlab help`,
all review the [full list of commands](../integration/chat_commands.md).
## Prerequisites
A [team](https://get.slack.help/hc/en-us/articles/217608418-Creating-a-team) in Slack should be created beforehand, GitLab cannot create it for you.
## Configuration
First, navigate to the Slack Slash commands service page, found at your project's
**Settings** > **Services**, and you find the instructions there:
![Slack setup instructions](img/slack_setup.png)
Once you've followed the instructions, mark the service as active and insert the token
you've received from Slack. After saving the service you are good to go!
# Webhooks
>**Note:**
Starting from GitLab 8.5:
- the `repository` key is deprecated in favor of the `project` key
- the `project.ssh_url` key is deprecated in favor of the `project.git_ssh_url` key
- the `project.http_url` key is deprecated in favor of the `project.git_http_url` key
Project webhooks allow you to trigger a URL if for example new code is pushed or
a new issue is created. You can configure webhooks to listen for specific events
like pushes, issues or merge requests. GitLab will send a POST request with data
to the webhook URL.
Webhooks can be used to update an external issue tracker, trigger CI builds,
update a backup mirror, or even deploy to your production server.
Navigate to the webhooks page by choosing **Webhooks** from your project's
settings which can be found under the wheel icon in the upper right corner.
## Webhook endpoint tips
If you are writing your own endpoint (web server) that will receive
GitLab webhooks keep in mind the following things:
- Your endpoint should send its HTTP response as fast as possible. If
you wait too long, GitLab may decide the hook failed and retry it.
- Your endpoint should ALWAYS return a valid HTTP response. If you do
not do this then GitLab will think the hook failed and retry it.
Most HTTP libraries take care of this for you automatically but if
you are writing a low-level hook this is important to remember.
- GitLab ignores the HTTP status code returned by your endpoint.
## Secret token
If you specify a secret token, it will be sent with the hook request in the
`X-Gitlab-Token` HTTP header. Your webhook endpoint can check that to verify
that the request is legitimate.
## SSL verification
By default, the SSL certificate of the webhook endpoint is verified based on
an internal list of Certificate Authorities, which means the certificate cannot
be self-signed.
You can turn this off in the webhook settings in your GitLab projects.
![SSL Verification](img/webhooks_ssl.png)
## Events
Below are described the supported events.
### Push events
Triggered when you push to the repository except when pushing tags.
**Request header**:
```
X-Gitlab-Event: Push Hook
```
**Request body:**
```json
{
"object_kind": "push",
"before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
"after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"ref": "refs/heads/master",
"checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"user_id": 4,
"user_name": "John Smith",
"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":{
"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.",
"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",
"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
Triggered when you create (or delete) tags to the repository.
**Request header**:
```
X-Gitlab-Event: Tag Push Hook
```
**Request body:**
```json
{
"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":{
"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
}
```
### Issues events
Triggered when a new issue is created or an existing issue was updated/closed/reopened.
**Request header**:
```
X-Gitlab-Event: Issue Hook
```
**Request body:**
```json
{
"object_kind": "issue",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project":{
"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": 301,
"title": "New API: create/update/delete file",
"assignee_id": 51,
"author_id": 51,
"project_id": 14,
"created_at": "2013-12-03T17:15:43Z",
"updated_at": "2013-12-03T17:15:43Z",
"position": 0,
"branch_name": null,
"description": "Create new API for manipulations with repository",
"milestone_id": null,
"state": "opened",
"iid": 23,
"url": "http://example.com/diaspora/issues/23",
"action": "open"
},
"assignee": {
"name": "User1",
"username": "user1",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
}
}
```
### Comment events
Triggered when a new comment is made on commits, merge requests, issues, and code snippets.
The note data will be stored in `object_attributes` (e.g. `note`, `noteable_type`). The
payload will also include information about the target of the comment. For example,
a comment on a issue will include the specific issue information under the `issue` key.
Valid target types:
1. `commit`
2. `merge_request`
3. `issue`
4. `snippet`
#### Comment on commit
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"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: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n",
"timestamp": "2014-02-27T10:06:20+02:00",
"url": "http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
"author": {
"name": "Dmitriy Zaporozhets",
"email": "dmitriy.zaporozhets@gmail.com"
}
}
}
```
#### Comment on merge request
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"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,
"locked_at": null,
"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
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"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_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
}
}
```
#### Comment on code snippet
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"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
Triggered when a new merge request is created, an existing merge request was updated/merged/closed or a commit is added in the source branch.
**Request header**:
```
X-Gitlab-Event: Merge Request Hook
```
**Request body:**
```json
{
"object_kind": "merge_request",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"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",
"st_commits": null,
"st_diffs": null,
"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"
}
}
}
```
### Wiki Page events
Triggered when a wiki page is created or edited.
**Request Header**:
```
X-Gitlab-Event: Wiki Page Hook
```
**Request Body**:
```json
{
"object_kind": "wiki_page",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon"
},
"project": {
"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
Triggered on status change of Pipeline.
**Request Header**:
```
X-Gitlab-Event: Pipeline Hook
```
**Request Body**:
```json
{
"object_kind": "pipeline",
"object_attributes":{
"id": 31,
"ref": "master",
"tag": false,
"sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2",
"before_sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2",
"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
},
"user":{
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon"
},
"project":{
"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,
"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,
"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": 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,
"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": 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,
"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": 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,
"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
}
}
]
}
```
### Build events
Triggered on status change of a Build.
**Request Header**:
```
X-Gitlab-Event: Build Hook
```
**Request Body**:
```json
{
"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,
"project_id": 380,
"project_name": "gitlab-org/gitlab-test",
"user": {
"id": 3,
"name": "User",
"email": "user@gitlab.com"
},
"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",
"git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git",
"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
}
}
```
## Example webhook receiver
If you want to see GitLab's webhooks in action for testing purposes you can use
a simple echo script running in a console session. For the following script to
work you need to have Ruby installed.
Save the following file as `print_http_body.rb`:
```ruby
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
```
Pick an unused port (e.g. 8000) and start the script: `ruby print_http_body.rb
8000`. Then add your server as a webhook receiver in GitLab as
`http://my.host:8000/`.
When you press 'Test Hook' in GitLab, you should see something like this in the
console:
```
{"before":"077a85dd266e6f3573ef7e9ef8ce3343ad659c4e","after":"95cd4a99e93bc4bbabacfa2cd10e6725b1403c60",<SNIP>}
example.com - - [14/May/2014:07:45:26 EDT] "POST / HTTP/1.1" 200 0
- -> /
```
# Webhooks This document was moved to [project/integrations/webhooks](../user/project/integrations/webhooks.md).
>**Note:**
Starting from GitLab 8.5:
- the `repository` key is deprecated in favor of the `project` key
- the `project.ssh_url` key is deprecated in favor of the `project.git_ssh_url` key
- the `project.http_url` key is deprecated in favor of the `project.git_http_url` key
Project webhooks allow you to trigger a URL if for example new code is pushed or
a new issue is created. You can configure webhooks to listen for specific events
like pushes, issues or merge requests. GitLab will send a POST request with data
to the webhook URL.
Webhooks can be used to update an external issue tracker, trigger CI builds,
update a backup mirror, or even deploy to your production server.
Navigate to the webhooks page by choosing **Webhooks** from your project's
settings which can be found under the wheel icon in the upper right corner.
## Webhook endpoint tips
If you are writing your own endpoint (web server) that will receive
GitLab webhooks keep in mind the following things:
- Your endpoint should send its HTTP response as fast as possible. If
you wait too long, GitLab may decide the hook failed and retry it.
- Your endpoint should ALWAYS return a valid HTTP response. If you do
not do this then GitLab will think the hook failed and retry it.
Most HTTP libraries take care of this for you automatically but if
you are writing a low-level hook this is important to remember.
- GitLab ignores the HTTP status code returned by your endpoint.
## Secret token
If you specify a secret token, it will be sent with the hook request in the
`X-Gitlab-Token` HTTP header. Your webhook endpoint can check that to verify
that the request is legitimate.
## SSL verification
By default, the SSL certificate of the webhook endpoint is verified based on
an internal list of Certificate Authorities, which means the certificate cannot
be self-signed.
You can turn this off in the webhook settings in your GitLab projects.
![SSL Verification](ssl.png)
## Events
Below are described the supported events.
### Push events
Triggered when you push to the repository except when pushing tags.
**Request header**:
```
X-Gitlab-Event: Push Hook
```
**Request body:**
```json
{
"object_kind": "push",
"before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
"after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"ref": "refs/heads/master",
"checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"user_id": 4,
"user_name": "John Smith",
"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":{
"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.",
"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",
"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
Triggered when you create (or delete) tags to the repository.
**Request header**:
```
X-Gitlab-Event: Tag Push Hook
```
**Request body:**
```json
{
"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":{
"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
}
```
### Issues events
Triggered when a new issue is created or an existing issue was updated/closed/reopened.
**Request header**:
```
X-Gitlab-Event: Issue Hook
```
**Request body:**
```json
{
"object_kind": "issue",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project":{
"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": 301,
"title": "New API: create/update/delete file",
"assignee_id": 51,
"author_id": 51,
"project_id": 14,
"created_at": "2013-12-03T17:15:43Z",
"updated_at": "2013-12-03T17:15:43Z",
"position": 0,
"branch_name": null,
"description": "Create new API for manipulations with repository",
"milestone_id": null,
"state": "opened",
"iid": 23,
"url": "http://example.com/diaspora/issues/23",
"action": "open"
},
"assignee": {
"name": "User1",
"username": "user1",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
}
}
```
### Comment events
Triggered when a new comment is made on commits, merge requests, issues, and code snippets.
The note data will be stored in `object_attributes` (e.g. `note`, `noteable_type`). The
payload will also include information about the target of the comment. For example,
a comment on a issue will include the specific issue information under the `issue` key.
Valid target types:
1. `commit`
2. `merge_request`
3. `issue`
4. `snippet`
#### Comment on commit
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"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: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n",
"timestamp": "2014-02-27T10:06:20+02:00",
"url": "http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
"author": {
"name": "Dmitriy Zaporozhets",
"email": "dmitriy.zaporozhets@gmail.com"
}
}
}
```
#### Comment on merge request
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"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,
"locked_at": null,
"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
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"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_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
}
}
```
#### Comment on code snippet
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"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
Triggered when a new merge request is created, an existing merge request was updated/merged/closed or a commit is added in the source branch.
**Request header**:
```
X-Gitlab-Event: Merge Request Hook
```
**Request body:**
```json
{
"object_kind": "merge_request",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"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",
"st_commits": null,
"st_diffs": null,
"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"
}
}
}
```
### Wiki Page events
Triggered when a wiki page is created or edited.
**Request Header**:
```
X-Gitlab-Event: Wiki Page Hook
```
**Request Body**:
```json
{
"object_kind": "wiki_page",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon"
},
"project": {
"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
Triggered on status change of Pipeline.
**Request Header**:
```
X-Gitlab-Event: Pipeline Hook
```
**Request Body**:
```json
{
"object_kind": "pipeline",
"object_attributes":{
"id": 31,
"ref": "master",
"tag": false,
"sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2",
"before_sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2",
"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
},
"user":{
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon"
},
"project":{
"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,
"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,
"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": 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,
"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": 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,
"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": 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,
"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
}
}
]
}
```
### Build events
Triggered on status change of a Build.
**Request Header**:
```
X-Gitlab-Event: Build Hook
```
**Request Body**:
```json
{
"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,
"project_id": 380,
"project_name": "gitlab-org/gitlab-test",
"user": {
"id": 3,
"name": "User",
"email": "user@gitlab.com"
},
"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",
"git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git",
"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
}
}
```
## Example webhook receiver
If you want to see GitLab's webhooks in action for testing purposes you can use
a simple echo script running in a console session. For the following script to
work you need to have Ruby installed.
Save the following file as `print_http_body.rb`:
```ruby
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
```
Pick an unused port (e.g. 8000) and start the script: `ruby print_http_body.rb
8000`. Then add your server as a webhook receiver in GitLab as
`http://my.host:8000/`.
When you press 'Test Hook' in GitLab, you should see something like this in the
console:
```
{"before":"077a85dd266e6f3573ef7e9ef8ce3343ad659c4e","after":"95cd4a99e93bc4bbabacfa2cd10e6725b1403c60",<SNIP>}
example.com - - [14/May/2014:07:45:26 EDT] "POST / HTTP/1.1" 200 0
- -> /
```
...@@ -213,6 +213,17 @@ describe ProjectsController do ...@@ -213,6 +213,17 @@ describe ProjectsController do
expect(response.status).to eq 404 expect(response.status).to eq 404
end end
end end
context "redirection from http://someproject.git" do
it 'redirects to project page (format.html)' do
project = create(:project, :public)
get :show, namespace_id: project.namespace.path, id: project.path, format: :git
expect(response).to have_http_status(302)
expect(response).to redirect_to(namespace_project_path)
end
end
end end
describe "#update" do describe "#update" do
......
...@@ -3,6 +3,18 @@ FactoryGirl.define do ...@@ -3,6 +3,18 @@ FactoryGirl.define do
project factory: :empty_project project factory: :empty_project
author factory: :user author factory: :user
trait(:created) { action Event::CREATED }
trait(:updated) { action Event::UPDATED }
trait(:closed) { action Event::CLOSED }
trait(:reopened) { action Event::REOPENED }
trait(:pushed) { action Event::PUSHED }
trait(:commented) { action Event::COMMENTED }
trait(:merged) { action Event::MERGED }
trait(:joined) { action Event::JOINED }
trait(:left) { action Event::LEFT }
trait(:destroyed) { action Event::DESTROYED }
trait(:expired) { action Event::EXPIRED }
factory :closed_issue_event do factory :closed_issue_event do
action { Event::CLOSED } action { Event::CLOSED }
target factory: :closed_issue target factory: :closed_issue
......
...@@ -10,8 +10,8 @@ feature 'toggler_behavior', js: true, feature: true do ...@@ -10,8 +10,8 @@ feature 'toggler_behavior', js: true, feature: true do
before do before do
login_as :admin login_as :admin
project = merge_request.source_project project = merge_request.source_project
visit "#{namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment_id}"
page.current_window.resize_to(1000, 300) page.current_window.resize_to(1000, 300)
visit "#{namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment_id}"
end end
describe 'scroll position' do describe 'scroll position' do
......
...@@ -133,6 +133,8 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do ...@@ -133,6 +133,8 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
it 'changes target_branch in new merge_request' do it 'changes target_branch in new merge_request' do
visit new_namespace_project_merge_request_path(another_project.namespace, another_project, new_url_opts) visit new_namespace_project_merge_request_path(another_project.namespace, another_project, new_url_opts)
click_button "Compare branches and continue"
fill_in "merge_request_title", with: 'My brand new feature' fill_in "merge_request_title", with: 'My brand new feature'
fill_in "merge_request_description", with: "le feature \n/target_branch fix\nFeature description:" fill_in "merge_request_description", with: "le feature \n/target_branch fix\nFeature description:"
click_button "Submit merge request" click_button "Submit merge request"
......
...@@ -10,15 +10,12 @@ describe ContributedProjectsFinder do ...@@ -10,15 +10,12 @@ describe ContributedProjectsFinder do
let!(:private_project) { create(:empty_project, :private) } let!(:private_project) { create(:empty_project, :private) }
before do before do
private_project.team << [source_user, Gitlab::Access::MASTER] private_project.add_master(source_user)
private_project.team << [current_user, Gitlab::Access::DEVELOPER] private_project.add_developer(current_user)
public_project.team << [source_user, Gitlab::Access::MASTER] public_project.add_master(source_user)
create(:event, action: Event::PUSHED, project: public_project, create(:event, :pushed, project: public_project, target: public_project, author: source_user)
target: public_project, author: source_user) create(:event, :pushed, project: private_project, target: private_project, author: source_user)
create(:event, action: Event::PUSHED, project: private_project,
target: private_project, author: source_user)
end end
describe 'without a current user' do describe 'without a current user' do
......
...@@ -5,15 +5,15 @@ describe EventFilter, lib: true do ...@@ -5,15 +5,15 @@ describe EventFilter, lib: true do
let(:source_user) { create(:user) } let(:source_user) { create(:user) }
let!(:public_project) { create(:empty_project, :public) } let!(:public_project) { create(:empty_project, :public) }
let!(:push_event) { create(:event, action: Event::PUSHED, project: public_project, target: public_project, author: source_user) } let!(:push_event) { create(:event, :pushed, project: public_project, target: public_project, author: source_user) }
let!(:merged_event) { create(:event, action: Event::MERGED, project: public_project, target: public_project, author: source_user) } let!(:merged_event) { create(:event, :merged, project: public_project, target: public_project, author: source_user) }
let!(:created_event) { create(:event, action: Event::CREATED, project: public_project, target: public_project, author: source_user) } let!(:created_event) { create(:event, :created, project: public_project, target: public_project, author: source_user) }
let!(:updated_event) { create(:event, action: Event::UPDATED, project: public_project, target: public_project, author: source_user) } let!(:updated_event) { create(:event, :updated, project: public_project, target: public_project, author: source_user) }
let!(:closed_event) { create(:event, action: Event::CLOSED, project: public_project, target: public_project, author: source_user) } let!(:closed_event) { create(:event, :closed, project: public_project, target: public_project, author: source_user) }
let!(:reopened_event) { create(:event, action: Event::REOPENED, project: public_project, target: public_project, author: source_user) } let!(:reopened_event) { create(:event, :reopened, project: public_project, target: public_project, author: source_user) }
let!(:comments_event) { create(:event, action: Event::COMMENTED, project: public_project, target: public_project, author: source_user) } let!(:comments_event) { create(:event, :commented, project: public_project, target: public_project, author: source_user) }
let!(:joined_event) { create(:event, action: Event::JOINED, project: public_project, target: public_project, author: source_user) } let!(:joined_event) { create(:event, :joined, project: public_project, target: public_project, author: source_user) }
let!(:left_event) { create(:event, action: Event::LEFT, project: public_project, target: public_project, author: source_user) } let!(:left_event) { create(:event, :left, project: public_project, target: public_project, author: source_user) }
it 'applies push filter' do it 'applies push filter' do
events = EventFilter.new(EventFilter.push).apply_filter(Event.all) events = EventFilter.new(EventFilter.push).apply_filter(Event.all)
......
...@@ -182,7 +182,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do ...@@ -182,7 +182,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
project: project, project: project,
commit_id: ci_pipeline.sha) commit_id: ci_pipeline.sha)
create(:event, target: milestone, project: project, action: Event::CREATED, author: user) create(:event, :created, target: milestone, project: project, author: user)
create(:service, project: project, type: 'CustomIssueTrackerService', category: 'issue_tracker') create(:service, project: project, type: 'CustomIssueTrackerService', category: 'issue_tracker')
project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED) project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED)
......
...@@ -19,7 +19,7 @@ describe Event, models: true do ...@@ -19,7 +19,7 @@ describe Event, models: true do
let(:project) { create(:empty_project) } let(:project) { create(:empty_project) }
it 'calls the reset_project_activity method' do it 'calls the reset_project_activity method' do
expect_any_instance_of(Event).to receive(:reset_project_activity) expect_any_instance_of(described_class).to receive(:reset_project_activity)
create_event(project, project.owner) create_event(project, project.owner)
end end
...@@ -43,33 +43,33 @@ describe Event, models: true do ...@@ -43,33 +43,33 @@ describe Event, models: true do
describe '#membership_changed?' do describe '#membership_changed?' do
context "created" do context "created" do
subject { build(:event, action: Event::CREATED).membership_changed? } subject { build(:event, :created).membership_changed? }
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
context "updated" do context "updated" do
subject { build(:event, action: Event::UPDATED).membership_changed? } subject { build(:event, :updated).membership_changed? }
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
context "expired" do context "expired" do
subject { build(:event, action: Event::EXPIRED).membership_changed? } subject { build(:event, :expired).membership_changed? }
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
end end
context "left" do context "left" do
subject { build(:event, action: Event::LEFT).membership_changed? } subject { build(:event, :left).membership_changed? }
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
end end
context "joined" do context "joined" do
subject { build(:event, action: Event::JOINED).membership_changed? } subject { build(:event, :joined).membership_changed? }
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
end end
end end
describe '#note?' do describe '#note?' do
subject { Event.new(project: target.project, target: target) } subject { described_class.new(project: target.project, target: target) }
context 'issue note event' do context 'issue note event' do
let(:target) { create(:note_on_issue) } let(:target) { create(:note_on_issue) }
...@@ -97,7 +97,7 @@ describe Event, models: true do ...@@ -97,7 +97,7 @@ describe Event, models: true do
let(:note_on_commit) { create(:note_on_commit, project: project) } let(:note_on_commit) { create(:note_on_commit, project: project) }
let(:note_on_issue) { create(:note_on_issue, noteable: issue, project: project) } let(:note_on_issue) { create(:note_on_issue, noteable: issue, project: project) }
let(:note_on_confidential_issue) { create(:note_on_issue, noteable: confidential_issue, project: project) } let(:note_on_confidential_issue) { create(:note_on_issue, noteable: confidential_issue, project: project) }
let(:event) { Event.new(project: project, target: target, author_id: author.id) } let(:event) { described_class.new(project: project, target: target, author_id: author.id) }
before do before do
project.team << [member, :developer] project.team << [member, :developer]
...@@ -221,13 +221,13 @@ describe Event, models: true do ...@@ -221,13 +221,13 @@ describe Event, models: true do
let!(:event2) { create(:closed_issue_event) } let!(:event2) { create(:closed_issue_event) }
describe 'without an explicit limit' do describe 'without an explicit limit' do
subject { Event.limit_recent } subject { described_class.limit_recent }
it { is_expected.to eq([event2, event1]) } it { is_expected.to eq([event2, event1]) }
end end
describe 'with an explicit limit' do describe 'with an explicit limit' do
subject { Event.limit_recent(1) } subject { described_class.limit_recent(1) }
it { is_expected.to eq([event2]) } it { is_expected.to eq([event2]) }
end end
...@@ -294,9 +294,9 @@ describe Event, models: true do ...@@ -294,9 +294,9 @@ describe Event, models: true do
} }
} }
Event.create({ described_class.create({
project: project, project: project,
action: Event::PUSHED, action: described_class::PUSHED,
data: data, data: data,
author_id: user.id author_id: user.id
}.merge!(attrs)) }.merge!(attrs))
......
...@@ -1013,8 +1013,8 @@ describe User, models: true do ...@@ -1013,8 +1013,8 @@ describe User, models: true do
let!(:project2) { create(:empty_project, forked_from_project: project3) } let!(:project2) { create(:empty_project, forked_from_project: project3) }
let!(:project3) { create(:empty_project) } let!(:project3) { create(:empty_project) }
let!(:merge_request) { create(:merge_request, source_project: project2, target_project: project3, author: subject) } let!(:merge_request) { create(:merge_request, source_project: project2, target_project: project3, author: subject) }
let!(:push_event) { create(:event, action: Event::PUSHED, project: project1, target: project1, author: subject) } let!(:push_event) { create(:event, :pushed, project: project1, target: project1, author: subject) }
let!(:merge_event) { create(:event, action: Event::CREATED, project: project3, target: merge_request, author: subject) } let!(:merge_event) { create(:event, :created, project: project3, target: merge_request, author: subject) }
before do before do
project1.team << [subject, :master] project1.team << [subject, :master]
...@@ -1058,7 +1058,7 @@ describe User, models: true do ...@@ -1058,7 +1058,7 @@ describe User, models: true do
let!(:push_data) do let!(:push_data) do
Gitlab::DataBuilder::Push.build_sample(project2, subject) Gitlab::DataBuilder::Push.build_sample(project2, subject)
end end
let!(:push_event) { create(:event, action: Event::PUSHED, project: project2, target: project1, author: subject, data: push_data) } let!(:push_event) { create(:event, :pushed, project: project2, target: project1, author: subject, data: push_data) }
before do before do
project1.team << [subject, :master] project1.team << [subject, :master]
...@@ -1086,7 +1086,7 @@ describe User, models: true do ...@@ -1086,7 +1086,7 @@ describe User, models: true do
expect(subject.recent_push(project2)).to eq(push_event) expect(subject.recent_push(project2)).to eq(push_event)
push_data1 = Gitlab::DataBuilder::Push.build_sample(project1, subject) push_data1 = Gitlab::DataBuilder::Push.build_sample(project1, subject)
push_event1 = create(:event, action: Event::PUSHED, project: project1, target: project1, author: subject, data: push_data1) push_event1 = create(:event, :pushed, project: project1, target: project1, author: subject, data: push_data1)
expect(subject.recent_push([project1, project2])).to eq(push_event1) # Newest expect(subject.recent_push([project1, project2])).to eq(push_event1) # Newest
end end
......
...@@ -35,7 +35,7 @@ module ExportFileHelper ...@@ -35,7 +35,7 @@ module ExportFileHelper
project: project, project: project,
commit_id: ci_pipeline.sha) commit_id: ci_pipeline.sha)
create(:event, target: milestone, project: project, action: Event::CREATED, author: user) create(:event, :created, target: milestone, project: project, author: user)
create(:project_member, :master, user: user, project: project) create(:project_member, :master, user: user, project: project)
create(:ci_variable, project: project) create(:ci_variable, project: project)
create(:ci_trigger, project: project) create(:ci_trigger, project: project)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment