2019-05-27 15:53:21 -04:00
---
2020-05-29 14:08:26 -04:00
stage: Verify
group: Continuous Integration
2020-11-26 01:09:20 -05:00
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/#assignments
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-11-18 13:09:08 -05:00
If dealing with [Git submodules ](https://git-scm.com/book/en/v2/Git-Tools-Submodules ), your project probably has 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
```
2020-11-18 13:09:08 -05:00
The above configuration instructs Git to automatically deduce the URL that
should be used when cloning sources. Whether you use HTTP(S) or SSH, Git uses
that same channel and it makes all your CI jobs use HTTP(S).
GitLab CI/CD only uses HTTP(S) for cloning your sources, and all your local
clones continue using SSH.
2016-11-30 14:40:53 -05:00
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
```
2020-11-09 22:09:04 -05:00
See the [GitLab Runner documentation ](runners/README.md#git-submodule-strategy )
2019-07-12 04:09:23 -04:00
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-11-18 13:09:08 -05:00
the way Git submodules work. On a fresh runner workspace, Git sets 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.