#!/usr/bin/env ruby require 'json' require 'restclient' auth_token = ENV["AUTH_TOKEN"] api_url = ENV["SCALINGO_API_URL"] || "https://api.scalingo.com/v1" auth_url = ENV["SCALINGO_AUTH_URL"] || "https://auth.scalingo.com/v1" app = ENV["APP"] gitlab_token = ENV["GITLAB_TOKEN"] gitlab_url = ENV["GITLAB_URL"] || "https://gitlab.com" child_app = ARGV[0] gitlab_repo = ARGV[1] git_branch = ARGV[2] || "master" if gitlab_token.nil? puts "environment variable 'GITLAB_TOKEN' required" exit -1 end if auth_token.nil? puts "environment variable 'AUTH_TOKEN' required" exit -1 end if app.nil? puts "environment variable 'APP' required" exit -1 end if child_app.nil? or gitlab_repo.nil? puts "usage: #{$0} [git ref (master)]" exit -1 end begin response = RestClient::Request.execute method: :post, url: "#{auth_url}/tokens/exchange", user: "scalingo", password: auth_token, headers: {content_type: :json} rescue => e puts "Fail to get a short term authentication Token" exit -2 end jwt_token = JSON.parse(response)['token'] # Create a child app from the app defined in ENV['APP'] # Environment, addons and collaborators are copied begin response = RestClient::Request.execute method: :post, url: "#{api_url}/apps/#{app}/child_apps", payload: {"app" => {"name" => child_app}}.to_json, headers: {"Authorization" => "Bearer #{jwt_token}", content_type: :json} rescue => e puts "Fail to create child app: #{e.http_code} - #{e.http_body}" exit -2 end body = JSON.parse response.body child_app = body['app'] # Use gitlab /repository/archive endpoint to get a given version of the source code to deploy # The request is authenticated from a user API token # Then trigger a deployment using the archive URL as source_url for the deployment. begin response = RestClient::Request.execute method: :post, url: "#{api_url}/apps/#{child_app['id']}/deployments", payload: { source_url: "#{gitlab_url}/#{gitlab_repo}/repository/archive.tar.gz?ref=#{git_branch}&private_token=#{gitlab_token}" }.to_json, headers: {"Authorization" => "Bearer #{jwt_token}", content_type: "application/json"} rescue => e puts "Fail to start deployment: #{e.http_code} - #{e.http_body}" exit -2 end body = JSON.parse response.body deployment_id = body['deployment']['id'] print "Deployment started (#{deployment_id}) for #{child_app['name']}, waiting" # Wait for the deployment to finish (success or error) deployment = nil loop do print "." response = RestClient::Request.execute method: :get, url: "#{api_url}/apps/#{child_app['id']}/deployments/#{deployment_id}", headers: {"Authorization" => "Bearer #{jwt_token}", content_type: "application/json"} deployment = JSON.parse(response.body)['deployment'] if deployment['status'].include?('error') || deployment['status'] == "success" break end sleep 5 end print "\n" puts "Deployment of app '#{child_app['name']}' finished with status '#{deployment['status']}'" if deployment['status'] == "success" puts "URL is: #{child_app['url']}" else puts "Logs at: https://my.scalingo.com/apps/#{child_app['name']}/deployments/#{deployment['id']}" end # Finally list all the child apps of the parent app (ENV['APP']) puts puts "Child apps for #{app}:" response = RestClient::Request.execute method: :get, url: "#{api_url}/apps/#{app}/child_apps", headers: {"Authorization" => "Bearer #{jwt_token}", content_type: "application/json"} body = JSON.parse(response.body) body['child_apps'].each do |child_app| puts "* #{child_app['name']} (#{child_app['id']}) - #{child_app['url']}" end