Skip to content

Instantly share code, notes, and snippets.

@bsimpson

bsimpson/circleci.rb

Created Nov 15, 2019
Embed
What would you like to do?
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
You can’t perform that action at this time.