Skip to content

Add script to check Bitrise build status #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Checkman.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
22B0D7F319BE5DAD001F35CD /* concourse.check in Resources */ = {isa = PBXBuildFile; fileRef = 22B0D7F219BE5DAD001F35CD /* concourse.check */; };
69CCFAD4174804B60097A6CC /* tracker.check in Resources */ = {isa = PBXBuildFile; fileRef = 69CCFAD3174804B60097A6CC /* tracker.check */; };
7A5F321F2103B8B8001D0B39 /* bitrise.check in Resources */ = {isa = PBXBuildFile; fileRef = 7A5F321E2103B8B8001D0B39 /* bitrise.check */; };
960C9F0816C7760100F5FAA2 /* WebUIHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 960C9F0716C7760100F5FAA2 /* WebUIHandler.m */; };
960C9F0C16C77A2700F5FAA2 /* WebSocketConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 960C9F0B16C77A2700F5FAA2 /* WebSocketConnection.m */; };
960C9F1216C7831400F5FAA2 /* WebSocketFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 960C9F1116C7831400F5FAA2 /* WebSocketFrame.m */; };
Expand Down Expand Up @@ -175,6 +176,7 @@
62BF3B9716AF60320051A1CC /* semaphore.check */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = semaphore.check; sourceTree = "<group>"; };
62BF3B9A16AF625C0051A1CC /* Checkman.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Checkman.zip; sourceTree = "<group>"; };
69CCFAD3174804B60097A6CC /* tracker.check */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tracker.check; sourceTree = "<group>"; };
7A5F321E2103B8B8001D0B39 /* bitrise.check */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bitrise.check; sourceTree = "<group>"; };
960C9F0616C7760100F5FAA2 /* WebUIHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebUIHandler.h; sourceTree = "<group>"; };
960C9F0716C7760100F5FAA2 /* WebUIHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebUIHandler.m; sourceTree = "<group>"; };
960C9F0A16C77A2700F5FAA2 /* WebSocketConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketConnection.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -687,6 +689,7 @@
children = (
AE2F71591B72BA900092CA6C /* snapci.check */,
AE40A98C1AD218B3006841E1 /* circleci.check */,
7A5F321E2103B8B8001D0B39 /* bitrise.check */,
AE40A98D1AD218B3006841E1 /* circlecijson.check */,
AE40A98E1AD218B3006841E1 /* codeship.check */,
AE40A98F1AD218B3006841E1 /* tddium.check */,
Expand Down Expand Up @@ -972,6 +975,7 @@
AE1E7D2116FD57070026129A /* github_issues.check in Resources */,
69CCFAD4174804B60097A6CC /* tracker.check in Resources */,
AE2F715A1B72BA900092CA6C /* snapci.check in Resources */,
7A5F321F2103B8B8001D0B39 /* bitrise.check in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ If you ever need to kill Checkman:
* `circlecijson.check <USERNAME> <PROJECT_NAME> <BRANCH_NAME> <API_TOKEN>`
checks specific Circle CI build status using the JSON interface which provides build time data
e.g. `circlecijson.check myusername myproject master 6cadaa96f7c455a658e00dd4500adc8f654342cc`

* `bitrise.check <APP_ID> <BRANCH_NAME> <API_TOKEN>`

(Tip: open project's setting page, then find the "API Tokens" tab to create an API token of type 'all')

* `test.check <OPTION_0> ... <OPTION_N>` returns predefined check result
Expand Down
Binary file modified bin/Checkman.zip
Binary file not shown.
160 changes: 160 additions & 0 deletions scripts/bitrise.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#!/usr/bin/env ruby
require "rubygems"
require "json"
require "time"

class BitriseBuildStatus
def initialize(hash)
@build_data = hash
end

def number
@build_data["build_number"]
end

def ok?
@build_data['status'] == 1
end

def building?
@build_data['status'] == 0
end

def build_url
@build_data["build_url"]
end

def started_at
iso8601 = @build_data["started_on_worker_at"]
Time.parse(iso8601) if iso8601
end

def finished_at
iso8601 = @build_data["finished_at"]
Time.parse(iso8601) if iso8601
end

def duration
if started_at
secs = (finished_at || Time.now) - started_at
Time.at(secs).gmtime.strftime("%R:%S")
end
end

def formatted_started_at
started_at.getlocal.strftime("%I:%M%p %m/%d/%Y %Z") if started_at
end

def last_commit_short_sha
@build_data["commit_hash"][0..5]
end

def last_commit_author
@build_data["committer_name"]
end

def last_commit_message
@build_data["commit_message"]
end

def as_json(options={})
{
:result => ok?,
:changing => building?,
:url => build_url,
:info => [
[:Build, number],
[:Duration, duration],
[:Started, formatted_started_at]
] + optional_info(options)
}
end

def to_json(*)
JSON.dump(as_json)
end

private

def optional_info(options)
if last_commit_short_sha
[ ["-", ""],
[:SHA, last_commit_short_sha],
[:Branch, @build_data['branch']],
[:Message, last_commit_message],
[:Author, last_commit_author] ]
else
[]
end
end
end

class BitriseBranchStatus
def initialize(json)
@branch_data = JSON.parse(json)['data']
@build_statuses =
@branch_data.map { |d| BitriseBuildStatus.new(d) }

raise StandardError, "Status for branch '#{branch_name}' is not available" \
unless last_build_status

rescue JSON::ParserError
raise RuntimeError, "invalid json: '#{json}'"
end

def ok?
if last_build_status.building? && last_non_pending_build_status
last_non_pending_build_status.ok?
else
last_build_status.ok?
end
end

def as_json(*)
last_build_status.as_json.tap do |hash|
hash[:result] = ok?
end
end

def to_json(*)
JSON.dump(as_json)
end

def last_build_status
@build_statuses.first
end

def last_non_pending_build_status
@build_statuses.find { |d| !d.building? }
end
end

class Bitrise
def initialize(app_id, branch_name, auth_token)
raise ArgumentError "app_id must not be nil" \
unless @app_id = app_id

raise ArgumentError "branch_name must not be nil" \
unless @branch_name = branch_name

raise ArgumentError "auth_token must not be nil" \
unless @auth_token = auth_token
end

def latest_status
BitriseBranchStatus.new(http_get(app_url))
end

private

def app_url
"https://api.bitrise.io/v0.1/apps/#{@app_id}/builds?branch=#{@branch_name}"
end

def http_get(url)
curl = "curl -s -H 'Authorization: token #{@auth_token}' '#{app_url}'"
`#{curl}`.tap { |o| $stderr.puts curl, o }
end
end

puts Bitrise.new(*ARGV).latest_status.to_json if __FILE__ == $0
8 changes: 8 additions & 0 deletions scripts/specs/bitrise_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$:.unshift(File.dirname(__FILE__))
require "spec_helper"

describe_check :Bitrise do
pending "trial account expired"
# it_returns_ok %w(<APP_ID> <PASSING_BRANCH> <WORKING_AUTH_TOKEN>)
# it_returns_fail %w(<APP_ID> <FAILING_BRANCH> <WORKING_AUTH_TOKEN>)
end