1---
2stage: Create
3group: Source Code
4info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
5type: reference
6---
7
8# File hooks **(FREE SELF)**
9
10> Renamed feature from Plugins to File hooks in GitLab 12.8.
11
12With custom file hooks, GitLab administrators can introduce custom integrations
13without modifying the GitLab source code.
14
15A file hook runs on each event. You can filter events or projects
16in a file hook's code, and create many file hooks as you need. Each file hook is
17triggered by GitLab asynchronously in case of an event. For a list of events
18see the [system hooks](../system_hooks/system_hooks.md) documentation.
19
20NOTE:
21File hooks must be configured on the file system of the GitLab server. Only GitLab
22server administrators can complete these tasks. Explore
23[system hooks](../system_hooks/system_hooks.md) or [webhooks](../user/project/integrations/webhooks.md)
24as an option if you do not have file system access.
25
26Instead of writing and supporting your own file hook, you can also make changes
27directly to the GitLab source code and contribute back upstream. In this way, we can
28ensure functionality is preserved across versions and covered by tests.
29
30## Setup
31
32The file hooks must be placed directly into the `file_hooks` directory, subdirectories
33are ignored. There is an
34[`example` directory inside `file_hooks`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/file_hooks/examples)
35where you can find some basic examples.
36
37Follow the steps below to set up a custom hook:
38
391. On the GitLab server, navigate to the plugin directory.
40   For an installation from source the path is usually
41   `/home/git/gitlab/file_hooks/`. For Omnibus installs the path is
42   usually `/opt/gitlab/embedded/service/gitlab-rails/file_hooks`.
43
44    For [configurations with multiple servers](reference_architectures/index.md),
45    your hook file should exist on each application server.
46
471. Inside the `file_hooks` directory, create a file with a name of your choice,
48   without spaces or special characters.
491. Make the hook file executable and make sure it's owned by the Git user.
501. Write the code to make the file hook function as expected. That can be
51   in any language, and ensure the 'shebang' at the top properly reflects the
52   language type. For example, if the script is in Ruby the shebang will
53   probably be `#!/usr/bin/env ruby`.
541. The data to the file hook is provided as JSON on STDIN. It is exactly the
55   same as for [system hooks](../system_hooks/system_hooks.md).
56
57That's it! Assuming the file hook code is properly implemented, the hook fires
58as appropriate. The file hooks file list is updated for each event, there is no
59need to restart GitLab to apply a new file hook.
60
61If a file hook executes with non-zero exit code or GitLab fails to execute it, a
62message is logged to:
63
64- `gitlab-rails/file_hook.log` in an Omnibus installation.
65- `log/file_hook.log` in a source installation.
66
67NOTE:
68In GitLab 13.12 and earlier, the filename was `plugin.log`
69
70## Creating file hooks
71
72This example responds only on the event `project_create`, and
73the GitLab instance informs the administrators that a new project has been created.
74
75```ruby
76#!/opt/gitlab/embedded/bin/ruby
77# By using the embedded ruby version we eliminate the possibility that our chosen language
78# would be unavailable from
79require 'json'
80require 'mail'
81
82# The incoming variables are in JSON format so we need to parse it first.
83ARGS = JSON.parse($stdin.read)
84
85# We only want to trigger this file hook on the event project_create
86return unless ARGS['event_name'] == 'project_create'
87
88# We will inform our admins of our gitlab instance that a new project is created
89Mail.deliver do
90  from    'info@gitlab_instance.com'
91  to      'admin@gitlab_instance.com'
92  subject "new project " + ARGS['name']
93  body    ARGS['owner_name'] + 'created project ' + ARGS['name']
94end
95```
96
97## Validation
98
99Writing your own file hook can be tricky and it's easier if you can check it
100without altering the system. A Rake task is provided so that you can use it
101in a staging environment to test your file hook before using it in production.
102The Rake task uses a sample data and execute each of file hook. The output
103should be enough to determine if the system sees your file hook and if it was
104executed without errors.
105
106```shell
107# Omnibus installations
108sudo gitlab-rake file_hooks:validate
109
110# Installations from source
111cd /home/git/gitlab
112bundle exec rake file_hooks:validate RAILS_ENV=production
113```
114
115Example of output:
116
117```plaintext
118Validating file hooks from /file_hooks directory
119* /home/git/gitlab/file_hooks/save_to_file.clj succeed (zero exit code)
120* /home/git/gitlab/file_hooks/save_to_file.rb failure (non-zero exit code)
121```
122