Skip to content

Instantly share code, notes, and snippets.

@jasonswett
Created April 18, 2026 19:06
Show Gist options
  • Select an option

  • Save jasonswett/8f36e54c07ff93501306374dc5f290c2 to your computer and use it in GitHub Desktop.

Select an option

Save jasonswett/8f36e54c07ff93501306374dc5f290c2 to your computer and use it in GitHub Desktop.
SaturnCI build and deploy pipeline script
#!/usr/bin/env ruby
require "json"
require "net/http"
require "uri"
credentials = JSON.parse(File.read(File.expand_path("~/.saturnci/credentials.json")))
user_id = credentials["user_id"]
api_token = credentials["api_token"]
base_url = "https://app.saturnci.com/api/v1"
repository = `git remote get-url origin`.strip.sub(/.*github\.com[:\/]/, "").sub(/\.git$/, "")
def api(method, url, user_id, api_token, params = nil)
uri = URI(url)
req = method == :post ? Net::HTTP::Post.new(uri) : Net::HTTP::Get.new(uri)
req.basic_auth(user_id, api_token)
req.set_form_data(params) if params
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
end
def poll_output(url, user_id, api_token, success_marker)
loop do
output = JSON.parse(api(:get, url, user_id, api_token).body)["output"].values.join
return output if output.include?(success_marker)
print "."
sleep 5
end
end
def poll_status(url, user_id, api_token)
loop do
data = JSON.parse(api(:get, url, user_id, api_token).body)
return data["status"] unless ["Running", "Queued"].include?(data["status"])
print "."
sleep 10
end
end
commit_hash = `git rev-parse HEAD`.strip
branch_name = `git rev-parse --abbrev-ref HEAD`.strip
commit_message = `git log -1 --format=%s`.strip
author_name = `git log -1 --format=%an`.strip
print "Testing"
test_suite_run_id = JSON.parse(api(:post, "#{base_url}/test_suite_runs", user_id, api_token, {
repository: repository,
branch_name: branch_name,
commit_hash: commit_hash,
commit_message: commit_message,
author_name: author_name
}).body)["id"]
status = poll_status("#{base_url}/test_suite_runs/#{test_suite_run_id}", user_id, api_token)
puts "\nTests #{status.downcase}."
abort "Aborting deploy." unless status == "Passed"
print "Building"
build_id = JSON.parse(api(:post, "#{base_url}/builds", user_id, api_token, { repository: repository, build_name: "production" }).body)["id"]
output = poll_output("#{base_url}/builds/#{build_id}", user_id, api_token, "Done. Image URL:")
image_url = output[/Image URL: (.+)/, 1]
puts "\nBuild complete: #{image_url}"
print "Deploying"
deploy_id = JSON.parse(api(:post, "#{base_url}/jobs", user_id, api_token, { repository: repository, job_name: "deploy", container_image_url: image_url }).body)["id"]
poll_output("#{base_url}/jobs/#{deploy_id}", user_id, api_token, "New Relic deployment marker recorded")
puts "\nDeploy complete!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment