33set -e
44set -o pipefail
55
6- default_source=github
6+ default_source=circleci
77default_solidity_version=latest
88
99if [[ $1 == --help ]]; then
@@ -17,19 +17,19 @@ if [[ $1 == --help ]]; then
1717 echo " ./$( basename " $0 " ) --help"
1818 echo " ./$( basename " $0 " ) [source] [solidity_version] [solc_bin_dir]"
1919 echo
20- echo " source The source to get binaries from. Must be 'github'."
21- echo " Other sources may be added in the future."
20+ echo " source The source to get binaries from. Can be 'circleci' or 'github'."
2221 echo " Default: '${default_source} '."
2322 echo " solidity_version Version tag representing the release to download, including"
2423 echo " the leading 'v'. Use 'latest' to get the most recent release."
24+ echo " In case of CircleCI 'latest' is the only supported value."
2525 echo " Default: '${default_solidity_version} '."
2626 echo " solc_bin_dir Location of the solc-bin checkout."
2727 echo " Default: current working directory."
2828 echo
2929 echo
3030 echo " Examples:"
3131 echo " ./$( basename " $0 " ) --help"
32- echo " ./$( basename " $0 " ) github latest"
32+ echo " ./$( basename " $0 " ) circleci latest"
3333 echo " ./$( basename " $0 " ) github v0.6.9"
3434 echo " ./$( basename " $0 " ) github latest ~/solc-bin/"
3535 exit 0
@@ -66,12 +66,40 @@ expect_single_line() {
6666}
6767
6868
69+ # JOB INFO FROM CIRCLECI API
70+
71+ filter_jobs_by_name () {
72+ local job_name=" $1 "
73+ jq ' [ .[] | select (.workflows.job_name == "' " $job_name " ' ") ]'
74+ }
75+
76+ select_latest_job_info () {
77+ # ASSUMPTION: Newer jobs always have higher build_num
78+ jq ' sort_by(.build_num) | last'
79+ }
80+
81+
82+ # ARTIFACT INFO FROM CIRCLECI API
83+
84+ filter_artifacts_by_name () {
85+ local artifact_name=" $1 "
86+
87+ jq ' [ .[] | select (.path == "' " $artifact_name " ' ") ]'
88+ }
89+
90+
6991# TAG INFO FROM GITHUB API
7092
7193filter_only_version_tags () {
7294 jq ' .[] | select (.name | startswith("v"))'
7395}
7496
97+ filter_tags_by_commit () {
98+ local commit_hash=" $1 "
99+
100+ jq ' [ . | select (.commit.sha == "' " $commit_hash " ' ") ]'
101+ }
102+
75103filter_tags_by_name () {
76104 local tag_name=" $1 "
77105
@@ -90,6 +118,29 @@ filter_assets_by_name() {
90118
91119# REPOSITORY STRUCTURE
92120
121+ target_to_job_name () {
122+ local target=" $1 "
123+
124+ case " $target " in
125+ # FIXME: We don't have Windows or static Linux builds set up on CircleCI
126+ macosx-amd64) echo b_osx ;;
127+ emscripten) echo b_ems ;;
128+ * ) die " Invalid target: %s" " $target " ;;
129+ esac
130+ }
131+
132+ target_to_circleci_artifact_name () {
133+ local target=" $1 "
134+
135+ case " $target " in
136+ # FIXME: What would that be in case of Windows? A zip file or an executable?
137+ linux-amd64) echo solc ;;
138+ macosx-amd64) echo solc ;;
139+ emscripten) echo soljson.js ;;
140+ * ) die " Invalid target: %s" " $target " ;;
141+ esac
142+ }
143+
93144target_to_github_artifact_regex () {
94145 local target=" $1 "
95146
@@ -138,6 +189,22 @@ format_binary_path() {
138189
139190# MAIN LOGIC
140191
192+ query_circleci_artifact_url () {
193+ local target=" $1 "
194+ local build_num=" $2 "
195+
196+ local artifact_endpoint=" https://circleci.com/api/v1.1/project/github/ethereum/solidity/${build_num} /artifacts"
197+ local artifact_name; artifact_name=" $( target_to_circleci_artifact_name " $target " ) "
198+ local artifact_url; artifact_url=" $(
199+ query_api " $artifact_endpoint " |
200+ filter_artifacts_by_name " $artifact_name " |
201+ jq --raw-output ' .[].url'
202+ ) "
203+ expect_single_line " $artifact_url "
204+
205+ echo " $artifact_url "
206+ }
207+
141208query_github_tag_info () {
142209 local endpoint=" https://api.github.com/repos/ethereum/solidity/tags?per_page=100"
143210
@@ -163,6 +230,49 @@ download_binary() {
163230 curl " $download_url " --output " ${target_path} " --location --no-progress-meter --create-dirs
164231}
165232
233+ download_binary_from_circleci () {
234+ local target=" $1 "
235+ local successful_jobs=" $2 "
236+ local tag_info=" $3 "
237+ local solc_bin_dir=" $4 "
238+
239+ local job_name; job_name=" $( target_to_job_name " $target " ) "
240+ local job_info; job_info=" $(
241+ echo " $successful_jobs " |
242+ filter_jobs_by_name " $job_name " |
243+ select_latest_job_info
244+ ) "
245+ echo " $job_info " | jq ' {
246+ job_name: .workflows.job_name,
247+ build_url,
248+ stop_time,
249+ status,
250+ subject,
251+ vcs_revision,
252+ branch,
253+ author_date
254+ }'
255+
256+ local build_num; build_num=" $( echo " $job_info " | jq --raw-output ' .build_num' ) "
257+ local commit_hash; commit_hash=" $( echo " $job_info " | jq --raw-output ' .vcs_revision' ) "
258+
259+ local solidity_version; solidity_version=" $(
260+ echo " $tag_info " |
261+ filter_tags_by_commit " $commit_hash " |
262+ jq --raw-output ' .[].name'
263+ ) "
264+ expect_single_line " $solidity_version "
265+
266+ local artifact_url; artifact_url=" $( query_circleci_artifact_url " $target " " $build_num " ) "
267+ local binary_path; binary_path=" $( format_binary_path " $target " " $solidity_version " " $commit_hash " ) "
268+ download_binary " ${solc_bin_dir} /${binary_path} " " $artifact_url "
269+ ! is_executable " $target " || chmod +x " ${solc_bin_dir} /${binary_path} "
270+
271+ if [[ $target == emscripten ]]; then
272+ disambiguate_emscripten_binary " $binary_path " " $solidity_version " " $commit_hash " " $solc_bin_dir "
273+ fi
274+ }
275+
166276download_binary_from_github () {
167277 local target=" $1 "
168278 local release_info=" $2 "
@@ -236,6 +346,27 @@ download_release() {
236346 local tag_info; tag_info=" $( query_github_tag_info | filter_only_version_tags) "
237347
238348 case " $source " in
349+ circleci)
350+ local release_targets=(
351+ # FIXME: We don't have Windows or static Linux builds set up on CircleCI
352+ # linux-amd64
353+ # windows-amd64
354+ macosx-amd64
355+ emscripten
356+ )
357+
358+ [[ $solidity_version == latest ]] || die " Only getting the latest release is supported for CircleCI"
359+
360+ local job_endpoint=" https://circleci.com/api/v1.1/project/github/ethereum/solidity/tree/release"
361+ local filter=" filter=successful&limit=100"
362+ local successful_jobs; successful_jobs=" $( query_api " ${job_endpoint} ?${filter} " ) "
363+ echo " Got $( echo " $successful_jobs " | jq ' . | length' ) recent successful job records from CircleCI"
364+
365+ for target in ${release_targets[@]} ; do
366+ download_binary_from_circleci " $target " " $successful_jobs " " $tag_info " " $solc_bin_dir "
367+ done
368+ ;;
369+
239370 github)
240371 local release_targets=(
241372 linux-amd64
@@ -270,7 +401,7 @@ download_release() {
270401 done
271402 ;;
272403
273- * ) die " Invalid source: '${source} '. The only currently supported value is 'github'." ;;
404+ * ) die " Invalid source: '${source} '. Must be either 'circleci' or 'github'." ;;
274405 esac
275406}
276407
0 commit comments