Rakefiles: refactor Jenkins API for downloading (binary) artifacts
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 17 Jan 2020 10:36:16 +0000
changeset 288 2986b947d89f
parent 287 0283457aef8a
child 289 c10f5a5b2e92
Rakefiles: refactor Jenkins API for downloading (binary) artifacts ...to allow multiple "backends" in (near) future. Introduce a concept of an arfifact repository. A repository contains multiple builds (currently the API provides only access to `latestBuild()`), build contains multipe artifacts. An artifact is essentially a downloadabe file. This commit is a preparation for introduction of "simple HTTP listing"-based repository as there's no public Jenkins instance anymore.
rakelib/support.rb
--- a/rakelib/support.rb	Mon Jan 20 13:33:54 2020 +0000
+++ b/rakelib/support.rb	Fri Jan 17 10:36:16 2020 +0000
@@ -32,25 +32,54 @@
 end
 
 # Returns true if and only if this is machine of one of the core developers
-# (currently only JV). 
+# (currently only JV).
 # Indeed this is a feeble check and can be easily bypassed by changing the
-# code or by setting a proper environment variable. But this should not hurt 
-# much as in that case, unauthorized person wouldn't be able to connect to 
-# stc and librun repository so the build will fail. 
+# code or by setting a proper environment variable. But this should not hurt
+# much as in that case, unauthorized person wouldn't be able to connect to
+# stc and librun repository so the build will fail.
 def core_developer?
   # JV's box: jv@..., vranyj1@...
   user = ENV['USER'] || ENV['USERNAME']
   (user == 'jv') or (user == 'vranyj1') ? true : false
 end
 
-# A super simple API for Jenkins used to download pre-built stc and librun.
-module Jenkins
-  # Return an a Jenkins build with pre-built stc and librun. 
-  # Used to download pre-build stc and librun
-  def self.smalltalkx_jv_branch_build
-    return Jenkins::Build.new(%Q{https://swing.fit.cvut.cz/jenkins/job/stx_jv/lastStableBuild})
+# ArtifactRepository module provides API for downloading (binary) files from
+# some sort of - well - artifact repository. A repository contains multiple
+# builds (currently the API provides only access to `latestBuild()`), build
+# contains multipe `Artifact`s. An `Artifact` is essentially a downloadable
+# (binary) file.
+#
+# Currently only Jenkins-based repository is provided (see class `Jenkins`
+# within this module)
+module ArtifactRepository
+
+  private
+
+  # A private method to GET data over HTTP(S)
+  def self.get(uri, &block)
+    # http parameters
+    http_host = Net::HTTP.new(uri.host, uri.port)
+    http_host.use_ssl = (uri.scheme == 'https') # simple true enough
+
+    if false # host verification not used (yet)
+      http_host.verify_mode = OpenSSL::SSL::VERIFY_PEER
+      http_host.cert_store = OpenSSL::X509::Store.new
+      http_host.cert_store.set_default_paths
+      http_host.cert_store.add_file('cacert.pem') # file downloaded from curl.haxx.se/ca/cacert.pem
+    else
+      http_host.verify_mode = OpenSSL::SSL::VERIFY_NONE
+    end
+
+    # actual download
+    body = nil
+    http_host.start do |http|
+      http.request_get(uri) {|response| block ? (yield response) : (body = response.body)}
+    end
+    body
   end
 
+  public
+
   class Artifact
     attr_reader :name
     attr_reader :uri
@@ -70,7 +99,7 @@
           destination = File.join(destination, @name)
         end
       end
-      Jenkins::get(@uri) do |response|
+      ArtifactRepository::get(@uri) do |response|
         File.open(destination, 'wb') do |file|
           response.read_body {|part| file.write part}
         end
@@ -78,45 +107,34 @@
     end
   end
 
-  class Build
-    attr_reader :data
-    attr_reader :uri
+  # Jenkins-based artifact repository.
+  class Jenkins
 
     def initialize(uri)
       @uri = uri
-      @data = JSON.parse(Jenkins::get(URI(uri.to_s + '/api/json')))
+    end
+
+    def latestBuild()
+      return Build.new(@uri + '/lastStableBuild')
     end
 
-    # Return a list of artifacts (as instances of `Jenkins::Artifact`) 
-    # associated with this build. 
-    def artifacts
-      unless @artifacts
-        @artifacts = @data['artifacts'].collect {|each| Artifact.new(each['fileName'], URI(@uri.to_s + '/artifact/' + each['relativePath']))}
+    class Build
+      attr_reader :data
+      attr_reader :uri
+
+      def initialize(uri)
+        @uri = uri
+        @data = JSON.parse(ArtifactRepository::get(URI(uri.to_s + '/api/json')))
       end
-      @artifacts
-    end
-  end
-
-  # A private method to GET data over HTTP(S)  
-  def self.get(uri, &block)
-    # http parameters       
-    http_host = Net::HTTP.new(uri.host, uri.port)
-    http_host.use_ssl = (uri.scheme == 'https') # simple true enough
 
-    if false # host verification not used (yet)
-      http_host.verify_mode = OpenSSL::SSL::VERIFY_PEER
-      http_host.cert_store = OpenSSL::X509::Store.new
-      http_host.cert_store.set_default_paths
-      http_host.cert_store.add_file('cacert.pem') # file downloaded from curl.haxx.se/ca/cacert.pem
-    else
-      http_host.verify_mode = OpenSSL::SSL::VERIFY_NONE
-    end
-
-    # actual download
-    body = nil
-    http_host.start do |http|
-      http.request_get(uri) {|response| block ? (yield response) : (body = response.body)}
-    end
-    body
-  end
-end
\ No newline at end of file
+      # Return a list of artifacts (as instances of `ArtifactRepository::Artifact`) 
+      # associated with this build. 
+      def artifacts
+        unless @artifacts
+          @artifacts = @data['artifacts'].collect {|each| Artifact.new(each['fileName'], URI(@uri.to_s + '/artifact/' + each['relativePath']))}
+        end
+        @artifacts
+      end
+    end # class ArtifactRepository::Jenkins::Build
+  end # class ArtifactRepository::Jenkins
+end # module ArtifactRepository
\ No newline at end of file