Skip to content

Commit

Permalink
download-release.sh: Add support for downloading recent releases from…
Browse files Browse the repository at this point in the history
… CircleCI
  • Loading branch information
cameel committed Jul 17, 2020
1 parent 29c2692 commit 80c24c3
Showing 1 changed file with 136 additions and 5 deletions.
141 changes: 136 additions & 5 deletions download-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set -e
set -o pipefail

default_source=github
default_source=circleci
default_solidity_version=latest

if [[ $1 == --help ]]; then
Expand All @@ -17,19 +17,19 @@ if [[ $1 == --help ]]; then
echo " ./$(basename "$0") --help"
echo " ./$(basename "$0") [source] [solidity_version] [solc_bin_dir]"
echo
echo " source The source to get binaries from. Must be 'github'."
echo " Other sources may be added in the future."
echo " source The source to get binaries from. Can be 'circleci' or 'github'."
echo " Default: '${default_source}'."
echo " solidity_version Version tag representing the release to download, including"
echo " the leading 'v'. Use 'latest' to get the most recent release."
echo " In case of CircleCI 'latest' is the only supported value."
echo " Default: '${default_solidity_version}'."
echo " solc_bin_dir Location of the solc-bin checkout."
echo " Default: current working directory."
echo
echo
echo "Examples:"
echo " ./$(basename "$0") --help"
echo " ./$(basename "$0") github latest"
echo " ./$(basename "$0") circleci latest"
echo " ./$(basename "$0") github v0.6.9"
echo " ./$(basename "$0") github latest ~/solc-bin/"
exit 0
Expand Down Expand Up @@ -66,12 +66,40 @@ expect_single_line() {
}


# JOB INFO FROM CIRCLECI API

filter_jobs_by_name() {
local job_name="$1"
jq '[ .[] | select (.workflows.job_name == "'"$job_name"'") ]'
}

select_latest_job_info() {
# ASSUMPTION: Newer jobs always have higher build_num
jq 'sort_by(.build_num) | last'
}


# ARTIFACT INFO FROM CIRCLECI API

filter_artifacts_by_name() {
local artifact_name="$1"

jq '[ .[] | select (.path == "'"$artifact_name"'") ]'
}


# TAG INFO FROM GITHUB API

filter_only_version_tags() {
jq '.[] | select (.name | startswith("v"))'
}

filter_tags_by_commit() {
local commit_hash="$1"

jq '[ . | select (.commit.sha == "'"$commit_hash"'") ]'
}

filter_tags_by_name() {
local tag_name="$1"

Expand All @@ -90,6 +118,29 @@ filter_assets_by_name() {

# REPOSITORY STRUCTURE

target_to_job_name() {
local target="$1"

case "$target" in
# FIXME: We don't have Windows or static Linux builds set up on CircleCI
macosx-amd64) echo b_osx ;;
emscripten) echo b_ems ;;
*) die "Invalid target: %s" "$target" ;;
esac
}

target_to_circleci_artifact_name() {
local target="$1"

case "$target" in
# FIXME: What would that be in case of Windows? A zip file or an executable?
linux-amd64) echo solc ;;
macosx-amd64) echo solc ;;
emscripten) echo soljson.js ;;
*) die "Invalid target: %s" "$target" ;;
esac
}

target_to_github_artifact_regex() {
local target="$1"

Expand Down Expand Up @@ -138,6 +189,22 @@ format_binary_path() {

# MAIN LOGIC

query_circleci_artifact_url() {
local target="$1"
local build_num="$2"

local artifact_endpoint="https://circleci.com/api/v1.1/project/github/ethereum/solidity/${build_num}/artifacts"
local artifact_name; artifact_name="$(target_to_circleci_artifact_name "$target")"
local artifact_url; artifact_url="$(
query_api "$artifact_endpoint" |
filter_artifacts_by_name "$artifact_name" |
jq --raw-output '.[].url'
)"
expect_single_line "$artifact_url"

echo "$artifact_url"
}

query_github_tag_info() {
local endpoint="https://api.github.com/repos/ethereum/solidity/tags?per_page=100"

Expand All @@ -163,6 +230,49 @@ download_binary() {
curl "$download_url" --output "${target_path}" --location --no-progress-meter --create-dirs
}

download_binary_from_circleci() {
local target="$1"
local successful_jobs="$2"
local tag_info="$3"
local solc_bin_dir="$4"

local job_name; job_name="$(target_to_job_name "$target")"
local job_info; job_info="$(
echo "$successful_jobs" |
filter_jobs_by_name "$job_name" |
select_latest_job_info
)"
echo "$job_info" | jq '{
job_name: .workflows.job_name,
build_url,
stop_time,
status,
subject,
vcs_revision,
branch,
author_date
}'

local build_num; build_num="$(echo "$job_info" | jq --raw-output '.build_num')"
local commit_hash; commit_hash="$(echo "$job_info" | jq --raw-output '.vcs_revision')"

local solidity_version; solidity_version="$(
echo "$tag_info" |
filter_tags_by_commit "$commit_hash" |
jq --raw-output '.[].name'
)"
expect_single_line "$solidity_version"

local artifact_url; artifact_url="$(query_circleci_artifact_url "$target" "$build_num")"
local binary_path; binary_path="$(format_binary_path "$target" "$solidity_version" "$commit_hash")"
download_binary "${solc_bin_dir}/${binary_path}" "$artifact_url"
! is_executable "$target" || chmod +x "${solc_bin_dir}/${binary_path}"

if [[ $target == emscripten ]]; then
disambiguate_emscripten_binary "$binary_path" "$solidity_version" "$commit_hash" "$solc_bin_dir"
fi
}

download_binary_from_github() {
local target="$1"
local release_info="$2"
Expand Down Expand Up @@ -236,6 +346,27 @@ download_release() {
local tag_info; tag_info="$(query_github_tag_info | filter_only_version_tags)"

case "$source" in
circleci)
local release_targets=(
# FIXME: We don't have Windows or static Linux builds set up on CircleCI
#linux-amd64
#windows-amd64
macosx-amd64
emscripten
)

[[ $solidity_version == latest ]] || die "Only getting the latest release is supported for CircleCI"

local job_endpoint="https://circleci.com/api/v1.1/project/github/ethereum/solidity/tree/release"
local filter="filter=successful&limit=100"
local successful_jobs; successful_jobs="$(query_api "${job_endpoint}?${filter}")"
echo "Got $(echo "$successful_jobs" | jq '. | length') recent successful job records from CircleCI"

for target in ${release_targets[@]}; do
download_binary_from_circleci "$target" "$successful_jobs" "$tag_info" "$solc_bin_dir"
done
;;

github)
local release_targets=(
linux-amd64
Expand Down Expand Up @@ -270,7 +401,7 @@ download_release() {
done
;;

*) die "Invalid source: '${source}'. The only currently supported value is 'github'." ;;
*) die "Invalid source: '${source}'. Must be either 'circleci' or 'github'." ;;
esac
}

Expand Down

0 comments on commit 80c24c3

Please sign in to comment.