Skip to content

Instantly share code, notes, and snippets.

@Val
Last active June 12, 2018 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Val/3851480869a84ef9e60d7c705b5a26e3 to your computer and use it in GitHub Desktop.
Save Val/3851480869a84ef9e60d7c705b5a26e3 to your computer and use it in GitHub Desktop.
Ruby script to download latest Crystal tagged Debian package
#!/usr/bin/env ruby
# vim: ft=ruby syn=ruby fileencoding=utf-8 sw=2 ts=2 ai eol et si
#
# download_latest_crystal_tagged_deb.rb: this script looks up the latest
# successfull tagged build of crystal on Circle CI, extracts the build number
# of `dist_artifacts` job and retrieves it's Debian artifacts, depending of
# ARCH environment variable (default: 'amd64')
#
# (c) 2018 Laurent Vallar <val@zbla.net>, WTFPL license v2 see below.
#
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://www.wtfpl.net/ for more details.
#
# frozen_string_literal: true
require 'json'
require 'open-uri'
ARCH = ENV['ARCH'] || 'amd64' # 'amd64' or 'i386'
raise "invalid arch #{ARCH}" unless %w[amd64 i386].include?(ARCH)
URL_BASE = "https://circleci.com/api/v1.1/project/github/crystal-lang/crystal"
def last_tagged_build_with_artifacts(limit: 100, offset: 0)
location = "?filter=successful&limit=#{limit}&branch=master&offset=#{offset}"
puts "requesting page ##{offset} of #{limit} items"
open("#{URL_BASE}#{location}") do |body|
JSON.parse(body.read, symbolize_names: true)
.sort_by { |hash| - hash[:build_num] }
.find do |hash|
hash[:vcs_tag] && hash[:build_parameters][:CIRCLE_JOB] == 'dist_artifacts'
end
end
end
def find_last_tagged_build_with_artifacts(depth: 10)
0.upto(depth) do |offset|
current = last_tagged_build_with_artifacts
break current if current
end
end
def artifact_url
build = find_last_tagged_build_with_artifacts
build_num = build[:build_num]
puts "found build ##{build_num}, tags: #{build[:vcs_tag]}"
open("#{URL_BASE}/#{build[:build_num]}/artifacts") do |file|
file.read.scan(%r{https://[^"]*#{ARCH}\.deb}m).first
end
end
@total = nil
CONTENT_LENGTH_PROC = lambda { |content_length| @total = content_length }
PROGRESS_PROC = lambda { |transferred|
print("\r#{transferred}/#{@total || 'unknown'}")
}
def get(source, dest)
open(dest, 'w') do |target|
open(source,
content_length_proc: CONTENT_LENGTH_PROC,
progress_proc: PROGRESS_PROC) do |file|
content = file.read
@total = content.size
target.write(content)
end
puts
end
end
def download(url: artifact_url)
basename = File.basename(url)
raise("#{basename} already present!") if File.exist?(basename)
get(url, basename)
puts "#{basename} downloaded #{@total} bytes"
end
download
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment