There are a few ways to achieve what you are trying to do. The most recent and comprehensive answer is in my SO answer on a related topic here.
You have three options to perform the task you want:
Follow the link above to add a Service Principal to the Azure Active Directory which is linked to the Azure DevOps Organisation, generate a secret for it, and add it to the repositories in question with Read access on the specific repository.
If the projects are part of the same organisation, you can add the Project Collection Build Service from your project to the source project's repository with Read access. You can then use a combination of a repository resource (more info here) and the standard checkout step to clone the target resource. If you do this, you can set the submodules
property of the checkout step to true
and it will handle the submodule initialisation for you. Note that your Project Collection Build Service user must have read on the submodule repositories also.
If you want to run commands in this folder afterwards, you can also set persistCredentials
to true
which will mean you can then run other commands (like submodule init
or push
) inside that repository once it has been cloned - assuming your Project Collection Build Service has permissions.
If the projects are part of the same organisation, you can try manually running the clone step using "classic" git commands inside a bash shell. You can do this by exposing the System.AccessToken
which is documented in more detail in the microsoft documentation on how to use and access it. Note that as the System.AccessToken
variable is sensitive, you must pass it in via environment variables to your script (it will not be replaced directly in inline scripts like a usual variable). Once you have this, you can simply use something resembling the below in your clone script:
git clone https://[ACCESS_TOKEN]@dev.azure.com/[YOUR_ORG]/[YOUR_PROJECT]/_git/[YOUR_REPOSITORY]
If you do this, you'll be able to use all the standard commands such as submodule init
etc.
Note that Option 3 above is actually identical to Option 2, because that's the commands that Azure DevOps will run for you as part of the checkout
step - you just have more access to the commands used to do it.
Personally, if you can control the Azure Active Directory that is backing the Azure DevOps Organisation in question, Option 1 is the cleanest. You are completely disconnected in your consuming pipeline from the source. If both projects are part of the same Organisation, Option 2 is cleaner as there's no secrets to pass around - you just use the Build Service identity and it's all kept nice and tidy (and secure) in Microsoft's stack.
Edit For those visiting who want to do this purely through cURL, this blog post has a brilliant overview.
Repeating the key elements here in case that link dies,
curl https://login.microsoftonline.com/<tenant-ID>/oauth2/token
-H "Content-Type: application/x-www-form-urlencoded"
--data
"
grant_type=client_credentials&
client_id=<Client ID>&
client_secret=<Client Secret>&
resource=499b84ac-1321-427f-aa17-267ca6975798
"
Interestingly that post goes on to remark that you can use the Tenant Name rather than Tenant ID, though I have not tested this.