CircleCI Artifact Retrieval via the API
# Finds a CircleCI job of a given name, and retrieves an artifact from a given CircleCI project build | |
# Usage: | |
# $ API_TOKEN=xxx GITHUB_USERNAME=bsimpson GITHUB_PROJECT=some-project TARGET_JOB=lighthouse ARTIFACT=averages_pageload ruby ./circleci.rb | |
require "net/http" | |
require "json" | |
API_TOKEN = ENV["API_TOKEN"] | |
LIMIT = 100 | |
GITHUB_USERNAME = ENV["GITHUB_USERNAME"] | |
GITHUB_PROJECT = ENV["GITHUB_PROJECT"] | |
TARGET_JOB = ENV["TARGET_JOB"] | |
ARTIFACT = ENV["ARTIFACT"] | |
# Recent builds for a single project | |
# curl https://circleci.com/api/v1.1/project/:vcs-type/:username/:project?circle-token=:token&limit=20&offset=5&filter=completed | |
def find_job(job=TARGET_JOB) | |
offset = 0 | |
while offset < LIMIT * 10 do | |
url = "https://circleci.com/api/v1.1/project/github/%{github_username}/%{github_project}?circle-token=%{token}&limit=%{limit}&offset=%{offset}" | |
uri = URI.parse url % { | |
github_username: GITHUB_USERNAME, | |
github_project: GITHUB_PROJECT, | |
token: API_TOKEN, | |
limit: LIMIT, | |
offset: offset | |
} | |
response = Net::HTTP.get(uri) | |
jobs = JSON.parse(response) | |
matching_job = jobs.detect { |job| job["build_parameters"]["CIRCLE_JOB"].match(TARGET_JOB) } | |
if matching_job | |
return matching_job | |
end | |
puts "Trying offset #{offset}..." | |
offset += LIMIT | |
end | |
puts "Exhausted pages" | |
end | |
# Return artifacts of a build | |
# curl https://circleci.com/api/v1.1/project/:vcs-type/:username/:project/:build_num/artifacts?circle-token=:token | |
def find_artifacts(job, artifact=ARTIFACT) | |
build_num = job["build_num"] | |
url = "https://circleci.com/api/v1.1/project/github/%{github_username}/%{github_project}/%{build_num}/artifacts?circle-token=%{token}" | |
uri = URI.parse url % { | |
github_username: GITHUB_USERNAME, | |
github_project: GITHUB_PROJECT, | |
build_num: build_num, | |
token: API_TOKEN | |
} | |
response = Net::HTTP.get(uri) | |
artifacts = JSON.parse(response) | |
matching_artifact = artifacts.detect { |artifact| artifact["path"].match(ARTIFACT) } | |
return matching_artifact | |
end | |
# Download an artifact | |
# https://132-55688803-gh.circle-artifacts.com/0//tmp/circle-artifacts.7wgAaIU/file.txt?circle-token=:token | |
def download_artifact(artifact) | |
url = "#{artifact["url"]}?circle-token=%{token}" | |
uri = URI.parse url % { | |
token: API_TOKEN | |
} | |
response = Net::HTTP.get(uri) | |
puts response | |
return response | |
end | |
job = find_job | |
artifact = find_artifacts(job) | |
download_artifact(artifact) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment