Commit c03ea3ad authored by Evan Read's avatar Evan Read Committed by Suzanne Selhorn

Apply CTRT principles to Server hooks page

parent b8851eb8
......@@ -10,143 +10,115 @@ disqus_identifier: 'https://docs.gitlab.com/ee/administration/custom_hooks.html'
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196051) in GitLab 12.8 replacing Custom Hooks.
Git supports hooks that are executed on different actions. These hooks run on the server and can be
used to enforce specific commit policies or perform other tasks based on the state of the
repository.
Server hooks run custom logic on the GitLab server. Users can use them to run Git-related tasks such as:
Git supports the following hooks:
- Enforcing specific commit policies.
- Performing tasks based on the state of the repository.
- `pre-receive`
- `post-receive`
- `update`
Server hooks use `pre-receive`, `post-receive`, and `update`
[Git server-side hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_server_side_hooks).
See [the Git documentation](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_server_side_hooks)
for more information about each hook type.
GitLab administrators configure server hooks on the file system of the GitLab server. If you don't have file system access,
alternatives to server hooks include:
Server-side Git hooks can be configured for:
- [Webhooks](../user/project/integrations/webhooks.md).
- [GitLab CI/CD](../ci/index.md).
- [Push rules](../push_rules/push_rules.md), for a user-configurable Git hook interface.
- [A single repository](#create-a-server-hook-for-a-repository).
- [All repositories](#create-a-global-server-hook-for-all-repositories).
[Geo](geo/index.md) doesn't replicate server hooks to secondary nodes.
Note the following about server hooks:
## Create a server hook for a single repository
- Server hooks must be configured on the file system of the GitLab server. Only GitLab server
administrators are able to complete these tasks. If you don't have file system access, see
possible alternatives such as:
- [Webhooks](../user/project/integrations/webhooks.md).
- [GitLab CI/CD](../ci/index.md).
- [Push Rules](../push_rules/push_rules.md), for a user-configurable Git hook
interface.
- Server hooks aren't replicated to [Geo](geo/index.md) secondary nodes.
To create a server hook for a single repository:
## Create a server hook for a repository
1. On the top bar, select **Menu > Admin**.
1. Go to **Overview > Projects** and select the project you want to add a server hook to.
1. On the page that appears, locate the value of **Gitaly relative path**. This path is where server hooks must be located.
- If you are using [hashed storage](repository_storage_types.md#hashed-storage), see
[Translate hashed storage paths](repository_storage_types.md#translate-hashed-storage-paths) for information on
interpreting the relative path.
- If you are not using [hashed storage](repository_storage_types.md#hashed-storage):
- For Omnibus GitLab installations, the path is usually `/var/opt/gitlab/git-data/repositories/<group>/<project>.git`.
- For an installation from source, the path is usually `/home/git/repositories/<group>/<project>.git`.
1. On the file system, create a new directory in the correct location called `custom_hooks`.
1. In the new `custom_hooks` directory, create a file with a name that matches the hook type. For example, for a
`pre-receive` server hook, the filename should be `pre-receive` with no extension.
1. Make the server hook file executable and ensure that it's owned by the Git user.
1. Write the code to make the server hook function as expected. Server hooks can be in any programming language. Ensure
the [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) at the top reflects the language type. For
example, if the script is in Ruby the shebang is probably `#!/usr/bin/env ruby`.
If you are not using [hashed storage](repository_storage_types.md#hashed-storage), the project's
repository directory might not exactly match the instructions below. In that case:
- For an installation from source, the path is usually
`/home/git/repositories/<group>/<project>.git`.
- For Omnibus GitLab installs, the path is usually
`/var/opt/gitlab/git-data/repositories/<group>/<project>.git`.
Follow the steps below to set up a server-side hook for a repository:
1. Go to **Admin area > Projects** and select the project you want to add a server hook to.
1. Locate the **Gitaly relative path** on the page that appears. This is where the server hook
must be implemented. For information on interpreting the relative path, see
[Translate hashed storage paths](repository_storage_types.md#translate-hashed-storage-paths).
1. On the file system, create a new directory in this location called `custom_hooks`.
1. Inside the new `custom_hooks` directory, create a file with a name matching the hook type. For
example, for a pre-receive hook the filename should be `pre-receive` with no extension.
1. Make the hook file executable and ensure that it's owned by the Git user.
1. Write the code to make the server hook function as expected. Hooks can be in any language. Ensure
the ["shebang"](https://en.wikipedia.org/wiki/Shebang_(Unix)) at the top properly reflects the
language type. For example, if the script is in Ruby the shebang is probably
`#!/usr/bin/env ruby`.
Assuming the hook code is properly implemented, the hook code is executed as appropriate.
If the server hook code is properly implemented, it should execute when the Git hook is next triggered.
## Create a global server hook for all repositories
To create a Git hook that applies to all of the repositories in your instance, set a global server
hook. The default global server hook directory is in the GitLab Shell directory. Any
hook added there applies to all repositories, including:
To create a Git hook that applies to all repositories, set a global server hook. The default global server hook directory
is in the GitLab Shell directory. Any server hook added there applies to all repositories, including:
- [Project and group wiki](../user/project/wiki/index.md) repositories. Their storage directory names are in the format
`<id>.wiki.git`.
- [Design management](../user/project/issues/design_management.md) repositories under a project. Their storage directory
names are in the format `<id>.design.git`.
- [Project and group wiki](../user/project/wiki/index.md) repositories,
whose storage directory names are in the format `<id>.wiki.git`.
- [Design management](../user/project/issues/design_management.md) repositories under a
project, whose storage directory names are in the format `<id>.design.git`.
### Choose a server hook directory
The default directory:
Before creating a global server hook, you must choose a directory for it. The default global server hook directory:
- For Omnibus GitLab installations is usually `/opt/gitlab/embedded/service/gitlab-shell/hooks`.
- For an installation from source is usually `/home/git/gitlab-shell/hooks`.
- For Omnibus GitLab installs is usually `/opt/gitlab/embedded/service/gitlab-shell/hooks`.
To use a different directory for global server hooks, set `custom_hooks_dir` in Gitaly
configuration:
To use a different directory for global server hooks, set `custom_hooks_dir` in Gitaly configuration:
- For Omnibus installations, this is set in `gitlab.rb`.
- For Omnibus installations, set in `gitlab.rb`.
- For source installations, the configuration location depends on the GitLab version. For:
- GitLab 13.0 and earlier, this is set in `gitlab-shell/config.yml`.
- GitLab 13.1 and later, this is set in `gitaly/config.toml` under the `[hooks]` section.
NOTE:
The `custom_hooks_dir` value in `gitlab-shell/config.yml` is still honored in GitLab 13.1 and later
if the value in `gitaly/config.toml` is blank or non-existent.
- GitLab 13.0 and earlier, set in `gitlab-shell/config.yml`.
- GitLab 13.1 and later, set in `gitaly/config.toml` under the `[hooks]` section. However, GitLab honors the
`custom_hooks_dir` value in `gitlab-shell/config.yml` if the value in `gitaly/config.toml` is blank or non-existent.
Follow the steps below to set up a global server hook for all repositories:
### Create the global server hook
1. On the GitLab server, navigate to the configured global server hook directory.
1. Create a new directory in this location. Depending on the type of hook, it can be either a
`pre-receive.d`, `post-receive.d`, or `update.d` directory.
1. Inside this new directory, add your hook. Hooks can be in any language. Ensure the
["shebang"](https://en.wikipedia.org/wiki/Shebang_(Unix)) at the top properly reflects the
language type. For example, if the script is in Ruby the shebang is probably
`#!/usr/bin/env ruby`.
1. Make the hook file executable and ensure that it's owned by the Git user.
To create a global server hook for all repositories:
Now test the hook to check whether it is functioning properly.
1. On the GitLab server, go to the configured global server hook directory.
1. Create a new directory in this location called `pre-receive.d`, `post-receive.d`, or `update.d`, depending on the type
of server hook. Any other names are ignored.
1. Inside this new directory, add your server hook. Server hooks can be in any programming language. Ensure the
[shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) at the top reflects the language type. For example, if the
script is in Ruby the shebang is probably `#!/usr/bin/env ruby`.
1. Make the hook file executable, ensure that it's owned by the Git user, and ensure it does not match the backup file
pattern (`*~`).
## Chained hooks
If the server hook code is properly implemented, it should execute when the Git hook is next triggered.
Server hooks set [per project](#create-a-server-hook-for-a-repository) or
[globally](#create-a-global-server-hook-for-all-repositories) can be executed in a chain.
## Chained server hooks
Server hooks are searched for and executed in the following order of priority:
GitLab can execute server hooks in a chain. GitLab searches for and executes server hooks in the following order:
- Built-in GitLab server hooks. These are not user-customizable.
- `<project>.git/custom_hooks/<hook_name>`: Per-project hooks. This was kept for backwards
compatibility.
- Built-in GitLab server hooks. These server hooks are not customizable by users.
- `<project>.git/custom_hooks/<hook_name>`: Per-project hooks. This location is kept for backwards compatibility.
- `<project>.git/custom_hooks/<hook_name>.d/*`: Location for per-project hooks.
- `<custom_hooks_dir>/<hook_name>.d/*`: Location for all executable global hook files
except editor backup files.
- `<custom_hooks_dir>/<hook_name>.d/*`: Location for all executable global hook files except editor backup files.
Within a directory, server hooks:
Within a server hooks directory, hooks:
- Are executed in alphabetical order.
- Stop executing when a hook exits with a non-zero value.
`<hook_name>.d` must be either `pre-receive.d`, `post-receive.d`, or `update.d` to work properly.
Any other names are ignored.
## Environment variables available to server hooks
Files in `.d` directories must be executable and not match the backup file pattern (`*~`).
You can pass any environment variable to server hooks, but you should only rely on supported environment variables.
For `<project>.git` you need to [translate](repository_storage_types.md#translate-hashed-storage-paths)
your project name into the hashed storage format that GitLab uses.
## Environment Variables
The following set of environment variables are available to server hooks.
The following GitLab environment variables are supported for all server hooks:
| Environment variable | Description |
|:---------------------|:----------------------------------------------------------------------------|
| `GL_ID` | GitLab identifier of user that initiated the push. For example, `user-2234` |
| `GL_PROJECT_PATH` | (GitLab 13.2 and later) GitLab project path |
| `GL_PROTOCOL` | (GitLab 13.2 and later) Protocol used for this change. One of: `http` (Git Push using HTTP), `ssh` (Git Push using SSH), or `web` (all other actions). |
| `GL_REPOSITORY` | `project-<id>` where `id` is the ID of the project |
| `GL_USERNAME` | GitLab username of the user that initiated the push |
|:---------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| `GL_ID` | GitLab identifier of user that initiated the push. For example, `user-2234`. |
| `GL_PROJECT_PATH` | (GitLab 13.2 and later) GitLab project path. |
| `GL_PROTOCOL` | (GitLab 13.2 and later) Protocol used for this change. One of: `http` (Git `push` using HTTP), `ssh` (Git `push` using SSH), or `web` (all other actions). |
| `GL_REPOSITORY` | `project-<id>` where `id` is the ID of the project. |
| `GL_USERNAME` | GitLab username of the user that initiated the push. |
Pre-receive and post-receive server hooks can also access the following Git environment variables.
The following Git environment variables are supported for `pre-receive` and `post-receive` server hooks:
| Environment variable | Description |
|:-----------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
......@@ -155,26 +127,18 @@ Pre-receive and post-receive server hooks can also access the following Git envi
| `GIT_PUSH_OPTION_COUNT` | Number of push options. See [Git `pre-receive` documentation](https://git-scm.com/docs/githooks#pre-receive). |
| `GIT_PUSH_OPTION_<i>` | Value of push options where `i` is from `0` to `GIT_PUSH_OPTION_COUNT - 1`. See [Git `pre-receive` documentation](https://git-scm.com/docs/githooks#pre-receive). |
NOTE:
While other environment variables can be passed to server hooks, your application should not rely on
them as they can change.
## Custom error messages
To have custom error messages appear in the GitLab UI when a commit is declined or an error occurs
during the Git hook, your script should:
You can have custom error messages appear in the GitLab UI when a commit is declined or an error occurs during the Git
hook. To display a custom error message, your script must:
- Send the custom error messages to either the script's `stdout` or `stderr`.
- Prefix each message with `GL-HOOK-ERR:` with no characters appearing before the prefix.
### Example custom error message
This hook script written in Bash generates the following message in the GitLab UI:
For example:
```shell
#!/bin/sh
echo "GL-HOOK-ERR: My custom error message.";
exit 1
```
![Custom message from custom Git hook](img/custom_hooks_error_msg.png)
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