How drone clones a repository

The question was asked how Drone clones a repository. I wanted to document this in Discourse so that others could benefit from the answer (and ask follow-up questions). A common misconception is that the agent clones the repository, or that the repository is cloned inside the agent container, which is not the case.

Drone adds a default clone step to every Pipeline. The clone steps executes the clone plugin, which is pretty much just a vanilla Drone plugin that handles cloning the repository. You can find the plugin here.

Let’s say we have the following configuration file:

kind: pipeline
name: default

steps:
- name: build
  image: golang
  commands:
  - go build
  - go test

Conceptually speaking, Drone automatically prepends the clone step to your Pipeline (demonstrated below). The plugin then clones your repository to the shared workspace volume.

kind: pipeline
name: default

steps:
+ - name: clone
+   image: drone/git
  - name: build
    image: golang
    commands:
      - go build
      - go test

Since the clone plugin is just a Docker container, it can be easily run locally:

docker run \
-e DRONE_COMMIT_SHA=15e3f9b7e16332eee3bbdff9ef31f95d23c5da2c \
-e DRONE_COMMIT_BRANCH=master \
-e DRONE_REMOTE_URL=https://github.com/drone/envsubst drone/git \
drone/git

The clone credentials are passed via the below environment variables (private repositories only)

DRONE_NETRC_MACHINE=github.com
DRONE_NETRC_USERNAME=
DRONE_NETRC_PASSWORD=

The username and password vary based on your source code management system. If your source code management system is github, for example, the password is x-oauth-basic and the username is the oauth token.

There are two caveats to this behavior:

  • the credentials are only passed to the plugin if the repository is private or DRONE_GIT_ALWAYS_AUTH=true
  • if you set DRONE_GIT_USERNAME and DRONE_GIT_PASSWORD, these values are used as the username and password
1 Like

Can I ask is this the same behaviour for services ?

I am getting an issue where the /drone/src does not have code yet for services and can only put it down to the service containers starting while clone is still happening is this the case ?

The default clone step executes first, then services, then pipeline steps.

yeah that’s my expectation but that’s definitely not what’s happening I can click the steps in the build and see the logs stream before clone has even commenced.

any idea’s on what could cause that ?

I do not have enough information available to make any recommendations. I would need to see a sample configuration file that can be used to reproduce the problem.

I can’t figure out a proper way to override the image used for this. I need to use one in a private repository. Neither of these options work. Is it documented somewhere?

kind: pipeline
name: default

steps:
- name: clone
  image: privaterepo.com/drone/git
- name: greeting
  image: privaterepo.com/docker-registry/alpine
  commands:
  - echo hello
  - echo world

trigger:
  branch:
  - master
  event:
  - push

---
kind: pipeline
name: default

clone:
  image: privaterepo.com/drone/git

steps:
- name: greeting
  image: privaterepo.com/docker-registry/alpine
  commands:
  - echo hello
  - echo world

trigger:
  branch:
  - master
  event:
  - push

@micahlmartin check out https://docs.drone.io/pipeline/digitalocean/syntax/cloning/#custom-logic

If you look at the official documentation you will note that the clone section of the yaml does not have an image attribute. The syntax in your example is invalid, which is why it does not work.

Hello,

I’m not sure to understand how the variables for the credentials are managed by drone (talking about DRONE_NETRC_*).
In a specific step (not the clone one) I need to access another git repository using the same credentials : is it possible ? I have tried but it seems DRONE_NETRC_USERNAME and DRONE_NETRC_PASSWORD are unset once the clone was done.
Am I right ?

First of all, thank @bradrydzewski for putting the plugin link here. It saved some time for me.

However, I am still facing an issue on how to check if a certain tag has been put on the default branch or not. In case of the annotated tags $DRONE_BRANCH will be empty and git branch --contains tags/vX.Y.Z will also return an error:

error: malformed object name tags/vX.Y.Z

Could you recommend how to overcome this?