2019-05-27 15:53:21 -04:00
---
2020-05-29 14:08:26 -04:00
stage: Verify
group: Continuous Integration
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
2019-05-27 15:53:21 -04:00
type: reference
---
2016-11-30 14:40:53 -05:00
# Using Git submodules with GitLab CI
> **Notes:**
2018-09-06 12:52:18 -04:00
>
2020-04-01 05:07:45 -04:00
> - GitLab 8.12 introduced a new [CI job permissions model](../user/project/new_ci_build_permissions_model.md) and you
2018-09-06 12:52:18 -04:00
> are encouraged to upgrade your GitLab instance if you haven't done already.
> If you are **not** using GitLab 8.12 or higher, you would need to work your way
> around submodules in order to access the sources of e.g., `gitlab.com/group/project`
> with the use of [SSH keys](ssh_keys/README.md).
> - With GitLab 8.12 onward, your permissions are used to evaluate what a CI job
> can access. More information about how this system works can be found in the
> [Jobs permissions model](../user/permissions.md#job-permissions).
2020-03-30 02:07:59 -04:00
> - The HTTP(S) Git protocol [must be enabled](../user/admin_area/settings/visibility_and_access_controls.md#enabled-git-access-protocols) in your GitLab instance.
2016-11-30 14:40:53 -05:00
## Configuring the `.gitmodules` file
2020-03-30 02:07:59 -04:00
If dealing with [Git submodules ](https://git-scm.com/book/en/v2/Git-Tools-Submodules ), your project will probably have a file
2016-11-30 14:40:53 -05:00
named `.gitmodules` .
Let's consider the following example:
1. Your project is located at `https://gitlab.com/secret-group/my-project` .
1. To checkout your sources you usually use an SSH address like
`git@gitlab.com:secret-group/my-project.git` .
1. Your project depends on `https://gitlab.com/group/project` , which you want
to include as a submodule.
If you are using GitLab 8.12+ and your submodule is on the same GitLab server,
you must update your `.gitmodules` file to use **relative URLs** .
Since Git allows the usage of relative URLs for your `.gitmodules` configuration,
2017-02-13 11:59:57 -05:00
this easily allows you to use HTTP(S) for cloning all your CI jobs and SSH
2016-11-30 14:40:53 -05:00
for all your local checkouts. The `.gitmodules` would look like:
```ini
[submodule "project"]
path = project
url = ../../group/project.git
```
The above configuration will instruct Git to automatically deduce the URL that
should be used when cloning sources. Whether you use HTTP(S) or SSH, Git will use
2017-02-13 11:59:57 -05:00
that same channel and it will allow to make all your CI jobs use HTTP(S)
2020-03-26 23:07:56 -04:00
(because GitLab CI/CD only uses HTTP(S) for cloning your sources), and all your local
2016-11-30 14:40:53 -05:00
clones will continue using SSH.
For all other submodules not located on the same GitLab server, use the full
HTTP(S) protocol URL:
```ini
[submodule "project-x"]
path = project-x
url = https://gitserver.com/group/project-x.git
```
Once `.gitmodules` is correctly configured, you can move on to
[configuring your `.gitlab-ci.yml` ](#using-git-submodules-in-your-ci-jobs ).
## Using Git submodules in your CI jobs
There are a few steps you need to take in order to make submodules work
2017-02-13 11:59:57 -05:00
correctly with your CI jobs:
2016-11-30 14:40:53 -05:00
1. First, make sure you have used [relative URLs ](#configuring-the-gitmodules-file )
for the submodules located in the same GitLab server.
2017-10-31 05:20:40 -04:00
1. Next, if you are using `gitlab-runner` v1.10+, you can set the
2017-01-15 18:20:07 -05:00
`GIT_SUBMODULE_STRATEGY` variable to either `normal` or `recursive` to tell
2017-02-13 11:59:57 -05:00
the runner to fetch your submodules before the job:
2019-07-12 04:09:23 -04:00
```yaml
variables:
GIT_SUBMODULE_STRATEGY: recursive
```
See the [`.gitlab-ci.yml` reference ](yaml/README.md#git-submodule-strategy )
for more details about `GIT_SUBMODULE_STRATEGY` .
2017-01-15 18:20:07 -05:00
2017-10-31 05:20:40 -04:00
1. If you are using an older version of `gitlab-runner` , then use
2017-01-15 18:20:07 -05:00
`git submodule sync/update` in `before_script` :
2016-11-30 14:40:53 -05:00
2019-07-09 03:16:17 -04:00
```yaml
before_script:
- git submodule sync --recursive
- git submodule update --init --recursive
```
`--recursive` should be used in either both or none (`sync/update`) depending on
whether you have recursive submodules.
2016-11-30 14:40:53 -05:00
The rationale to set the `sync` and `update` in `before_script` is because of
2020-09-12 05:09:53 -04:00
the way Git submodules work. On a fresh runner workspace, Git will set the
2016-11-30 14:40:53 -05:00
submodule URL including the token in `.git/config`
(or `.git/modules/<submodule>/config` ) based on `.gitmodules` and the current
2020-09-12 05:09:53 -04:00
remote URL. On subsequent jobs on the same runner, `.git/config` is cached
2016-11-30 14:40:53 -05:00
and already contains a full URL for the submodule, corresponding to the previous
2017-02-13 11:59:57 -05:00
job, and to **a token from a previous job** . `sync` allows to force updating
2016-11-30 14:40:53 -05:00
the full URL.