Cannot fetch private submodules on GitLab SaaS using absolute URLs
Summary
On GitLab.com SaaS, runner attempts to fetch submodules before the job seem to fail if absolute URLs are used. The submodule fetch will error with fatal: could not read Username for 'https://gitlab.com': No such device or address
.
Example scenario
Tested on GitLab Enterprise Edition 16.5.0-pre 21bad30927a
using SaaS shared runners 16.3.0~beta.108.g2b6048b4 (2b6048b4)
-
Create a new private project, for example -
project-a
. -
Create a new private project, for example -
project-b
. -
Clone
project-a
locally. -
Add a submodule using the absolute URL of
project-b
.$ git submodule add https://gitlab.com/<example-namespace>/project-b
$ cat .gitmodules [submodule "project-b"] path = project-b url = https://gitlab.com/<example-namespace>/project-b
$ git add . $ git commit -m "Add submodule" $ git push
-
Per our Documentation:
If you use the
CI_JOB_TOKEN
to clone a submodule in a pipeline job, the user executing the job must be assigned to a role that has permission to trigger a pipeline in the upstream submodule project. Additionally, CI/CD job token access must be properly configured in the upstream submodule project.Ensure both of these two conditions are met.
-
Start creating a
.gitlab-ci.yml
file, and set aGIT_SUBMODULE_STRATEGY
to tell the runner to fetch submodules before the job. For the whole.gitlab-ci.yml
file for the purpose of replicating this issue, you can use:test: variables: GIT_SUBMODULE_STRATEGY: recursive #CI_DEBUG_TRACE: 'true' script: ["echo 'test'"]
-
The job will fail with the following error output (additional items shown here are due to
CI_DEBUG_TRACE
being enabled in the job this output was taken from):++ git -c url.https://gitlab-ci-token:[MASKED]@us-east1-c.ci-gateway.int.gprd.gitlab.net:8989.insteadOf=https://us-east1-c.ci-gateway.int.gprd.gitlab.net:8989 submodule update --init --recursive --depth 20 Cloning into '/builds/<example-namespace>/project-a/project-b'... fatal: could not read Username for 'https://gitlab.com': No such device or address fatal: clone of 'https://gitlab.com/<example-namespace>/project-b' into submodule path '/builds/<example-namespace>/project-a/project-b' failed Failed to clone 'project-b'. Retry scheduled
What is the current behavior?
Attempting to fetch the repository for a submodule fails if absolute URLs are used, and the upstream submodule project is private.
What is the desired behavior?
Based on our current documentation, the submodule should be fetched as expected, and the example scenario should not result in a failure.
Additional testing / workarounds
-
Setting the upstream submodule project (
project-b
) to be public will cause the submodule fetch to succeed. Likely because no authentication method such as theCI_JOB_TOKEN
is required to access the upstream submodule. This is not going to be a feasible workaround for the majority of users facing this problem. -
The problem does not occur if Relative URLs are used for the
.gitmodule
configuration instead of Absolute URLs. For example, the following would work in our example scenario:[submodule "project-b"] path = project-b url = ../project-b
-
Another possible workaround is to instead opt to perform the submodule fetch inside the actual job itself, where the fetch is happening inside the actual container for the job script content. For the example scenario, the following
.gitlab-ci.yml
achieves this:test: variables: GIT_SUBMODULE_STRATEGY: none #CI_DEBUG_TRACE: 'true' before_script: - git submodule sync project-b - git submodule update --init project-b script: ["echo 'test'"]