diff options
Diffstat (limited to 'doc/administration/server_hooks.md')
-rw-r--r-- | doc/administration/server_hooks.md | 237 |
1 files changed, 145 insertions, 92 deletions
diff --git a/doc/administration/server_hooks.md b/doc/administration/server_hooks.md index 6df0f187a42..2fea000b799 100644 --- a/doc/administration/server_hooks.md +++ b/doc/administration/server_hooks.md @@ -8,130 +8,183 @@ disqus_identifier: 'https://docs.gitlab.com/ee/administration/custom_hooks.html' # Server hooks **(CORE ONLY)** -> **Notes:** -> -> - Server hooks were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196051) in GitLab 12.8 replacing Custom Hooks. -> - Server hooks must be configured on the filesystem of the GitLab server. Only GitLab server administrators will be able to complete these tasks. Please explore [webhooks](../user/project/integrations/webhooks.md) and [GitLab CI/CD](../ci/README.md) as an option if you do not have filesystem access. For a user-configurable Git hook interface, see [Push Rules](../push_rules/push_rules.md), available in GitLab Starter **(STARTER)**. -> - Server hooks won't be replicated to secondary nodes if you use [GitLab Geo](geo/replication/index.md). - -Git natively 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. - -Examples of server-side Git hooks include `pre-receive`, `post-receive`, and `update`. -See [Git SCM Server-Side Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#Server-Side-Hooks) +> [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. + +Git supports the following hooks: + +- `pre-receive` +- `post-receive` +- `update` + +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. -## Create a server hook for a repository +Server-side Git hooks can be configured for: -Server-side Git hooks are typically placed in the repository's `hooks` -subdirectory. In GitLab, hook directories are symlinked to the GitLab Shell -`hooks` directory for ease of maintenance between GitLab Shell upgrades. -Server hooks are implemented differently, but the behavior is exactly the same -once the hook is created. +- [A single repository](#create-a-server-hook-for-a-repository). +- [All repositories](#create-a-global-server-hook-for-all-repositories). + +Note the following about server hooks: + +- 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/README.md). + - [Push Rules](../push_rules/push_rules.md), for a user-configurable Git hook + interface. **(STARTER)** +- Server hooks aren't replicated to [Geo](geo/replication/index.md) secondary nodes. + +## Create a server hook for a repository -NOTE: **Note:** 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 installs the path is usually `/var/opt/gitlab/git-data/repositories/<group>/<project>.git`. - -Follow the steps below to set up a server hook for a -repository: - -1. Find that project's path on the GitLab server, by navigating to the - **Admin area > Projects**. From there, select the project for which you - would like to add a hook. You can find the path to the project's repository - under **Gitaly relative path** on that page. -1. 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 a pre-receive hook the file name should be `pre-receive` - with no extension. -1. Make the hook file executable and make sure it's owned by Git. -1. Write the code to make the server hook function as expected. Hooks can be - in any language. Ensure the 'shebang' at the top properly reflects the language - type. For example, if the script is in Ruby the shebang will probably be +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. Navigate to **Admin area > Projects** and click on 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 + [Translating hashed storage paths](repository_storage_types.md#translating-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 will run as appropriate. - -## Set a global server hook for all repositories - -To create a Git hook that applies to all of your repositories in -your instance, set a global server hook. Since GitLab will look inside the GitLab Shell -`hooks` directory for global hooks, adding any hook there will apply it to all repositories. -Follow the steps below to properly set up a server hook for all repositories: - -1. On the GitLab server, navigate to the configured custom hook directory. The - default is in the GitLab Shell directory. The GitLab Shell `hook` directory - for an installation from source the path is usually - `/home/git/gitlab-shell/hooks`. For Omnibus installs the path is usually - `/opt/gitlab/embedded/service/gitlab-shell/hooks`. - To look in a different directory for the global custom hooks, - set `custom_hooks_dir` in the Gitaly config. For Omnibus installations, this is 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: **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. - -1. Create a new directory in this location. Depending on your hook, it will 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' at the top properly reflects the language - type. For example, if the script is in Ruby the shebang will probably be +Assuming the hook code is properly implemented, the hook code is executed as appropriate. + +## 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. + +The default directory: + +- 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: + +- For Omnibus installations, this is 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: **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. + +Follow the steps below to set up a global server hook for all repositories: + +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 make sure it's owned by Git. +1. Make the hook file executable and ensure that it's owned by the Git user. Now test the hook to check whether it is functioning properly. -## Chained hooks support +## Chained hooks > [Introduced](https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/93) in GitLab Shell 4.1.0 and GitLab 8.15. -Hooks can be also global or be set per project directories and support a chained -execution of the hooks. +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. -NOTE: **Note:** -`<hook_name>.d` would need to be either `pre-receive.d`, -`post-receive.d`, or `update.d` to work properly. Any other names will be ignored. +Server hooks are searched for and executed in the following order of priority: + +- 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. +- `<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. + +Within a directory, server hooks: + +- Are executed in alphabetical order. +- Stop executing when a hook exits with a non-zero value. + +Note: + +- `<hook_name>.d` must be either `pre-receive.d`, `post-receive.d`, or `update.d` to work properly. + Any other names are ignored. +- Files in `.d` directories must be executable and not match the backup file pattern (`*~`). +- For `<project>.git` you need to [translate](repository_storage_types.md#translating-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. + +| 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 with push | +| `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. + +| Environment variable | Description | +|:-----------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `GIT_ALTERNATE_OBJECT_DIRECTORIES` | Alternate object directories in the quarantine environment. See [Git `receive-pack` documentation](https://git-scm.com/docs/git-receive-pack#_quarantine_environment). | +| `GIT_OBJECT_DIRECTORY` | GitLab project path in the quarantine environment. See [Git `receive-pack` documentation](https://git-scm.com/docs/git-receive-pack#_quarantine_environment). | +| `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: **Note:** -Files in `.d` directories need to be executable and not match the backup file -pattern (`*~`). +While other environment variables can be passed to server hooks, your application should not rely on +them as they can change. -The hooks are searched and executed in this order: +## Transition to Go -1. Built-in GitLab server hooks (not user-customizable). -1. `<project>.git/custom_hooks/<hook_name>` - per-project hook (this was kept as the already existing behavior). -1. `<project>.git/custom_hooks/<hook_name>.d/*` - per-project hooks. -1. `<custom_hooks_dir>/<hook_name>.d/*` - global hooks: all executable files (except editor backup files). +> Introduced in GitLab 13.2 using feature flags. -The hooks of the same type are executed in order and execution stops on the -first script exiting with a non-zero value. +The following server hooks have been re-implemented in Go: -For `<project>.git` you'll need to -[translate your project name into the hashed storage format](repository_storage_types.md#translating-hashed-storage-paths) -that GitLab uses. +- `pre-receive`, with the Go implementation used by default. To use the Ruby implementation instead, + [disable](../operations/feature_flags.md#enable-or-disable-feature-flag-strategies) the + `:gitaly_go_preceive_hook` feature flag. +- `update`, with the Go implementation used by default. To use the Ruby implementation instead, + [disable](../operations/feature_flags.md#enable-or-disable-feature-flag-strategies) the + `:gitaly_go_update_hook` feature flag. +- `post-receive`, however the Ruby implementation is used by default. To use the Go implementation + instead, [enable](../operations/feature_flags.md#enable-or-disable-feature-flag-strategies) the + `:gitaly_go_postreceive_hook` feature flag. ## Custom error messages > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5073) in GitLab 8.10. -To have custom error messages appear in GitLab's UI when the commit is -declined or an error occurs during the Git hook, your script should: +To have custom error messages appear in GitLab's UI when a commit is declined or an error occurs +during the Git hook, your script should: - 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 will generate the following message in GitLab's UI: +This hook script written in Bash generates the following message in GitLab's UI: ```shell #!/bin/sh |