Drone CI pipelines can upload build artifacts to various destinations, but the most common and flexible approach is using a dedicated artifact repository like Nexus, Artifactory, or even cloud storage like AWS S3.
Here’s how a typical Drone CI pipeline might look for uploading artifacts, using Nexus as an example:
kind: pipeline
type: docker
name: default
steps:
- name: build
image: golang:1.19
commands:
- go build -o app
- name: upload-artifact
image: plugins/nexus
settings:
# Nexus server URL
url: https://your-nexus-instance.com
# Nexus username
username: drone-user
# Nexus password (use secrets for this!)
password:
from_secret: nexus_password
# Repository to upload to
repository: maven-releases
# Path within the repository
path: /com/example/app/${DRONE_BUILD_NUMBER}
# Files to upload
files:
- app
In this pipeline:
- The
buildstep compiles a Go application. - The
upload-artifactstep uses theplugins/nexusDrone plugin. url,username, andrepositoryare self-explanatory.passwordis fetched from a Drone secret namednexus_password.pathconstructs a directory structure within Nexus, using the Drone build number.filesspecifies which generated files (in this case, the compiledappbinary) should be uploaded.
The real magic happens when Drone executes this step. The plugins/nexus image is a pre-built Docker image that knows how to interact with the Nexus API. It takes the settings provided in the YAML, authenticates with your Nexus instance, and uploads the specified files to the designated path within the repository.
This setup allows you to store your compiled applications, libraries, Docker images, or any other build outputs in a centralized, versioned, and easily accessible location. Consumers of your builds can then reliably retrieve these artifacts for deployment or further processing.
The most surprising true thing about uploading build artifacts is that your pipeline doesn’t need to know how to talk to the artifact repository. It just needs to declare what it wants to upload and where. The plugin, or the underlying client library it uses, handles all the HTTP requests, authentication, and error handling for you. You’re essentially delegating the complexity of artifact management to specialized tools.
Let’s say you have a Java project and you want to upload the generated JAR file to a Maven repository in Nexus. The configuration would be very similar, but you’d specify the correct files and potentially a different path structure.
# ... other steps ...
- name: upload-jar
image: plugins/nexus
settings:
url: https://your-nexus-instance.com
username: drone-user
password:
from_secret: nexus_password
repository: maven-releases
path: /com/example/my-java-app/${DRONE_BUILD_NUMBER}
files:
- target/my-java-app-1.0.jar # Assuming your build tool places it here
The path here follows the standard Maven convention: groupId/artifactId/version. Drone’s build variables like ${DRONE_BUILD_NUMBER} or ${DRONE_COMMIT_SHA} are incredibly useful for creating dynamic and informative artifact paths.
Beyond Nexus, the plugins/s3 or plugins/gcs plugins work on the same principle for cloud object storage. You’d provide credentials, bucket names, and paths, and the plugin handles the AWS S3 or Google Cloud Storage API interactions.
The key to effective artifact management lies in consistency and discoverability. By using a structured naming convention for your artifact paths (e.g., incorporating build numbers, commit SHAs, or semantic versions), you make it easy for other systems or developers to find the exact artifact they need.
What most people don’t realize is the sheer power of combining artifact uploads with Drone’s built-in environment variables. You can dynamically construct artifact paths based on the commit author, branch name, or even tags. For instance, uploading release candidates to a /rc/ path and stable releases to a /stable/ path based on a Git tag is a common and highly effective pattern.
The next concept you’ll likely encounter is artifact promotion, where you move artifacts between different repositories (e.g., from a "snapshot" repository to a "release" repository) based on quality gates or manual approval.