Class: FaHarnessTools::GithubClient

Inherits:
Object
  • Object
show all
Defined in:
lib/fa-harness-tools/github_client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(oauth_token:, owner:, repo:) ⇒ GithubClient

Returns a new instance of GithubClient.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/fa-harness-tools/github_client.rb', line 8

def initialize(oauth_token:, owner:, repo:)
  @octokit = Octokit::Client.new(access_token: oauth_token)
  @octokit.connection_options = {
    request: {
      open_timeout: 60,
      timeout: 60
    }
  }

  @owner = owner
  @repo = repo
  @oauth_token = oauth_token
  validate_repo
end

Instance Attribute Details

#ownerObject (readonly)

Returns the value of attribute owner.



6
7
8
# File 'lib/fa-harness-tools/github_client.rb', line 6

def owner
  @owner
end

#repoObject (readonly)

Returns the value of attribute repo.



6
7
8
# File 'lib/fa-harness-tools/github_client.rb', line 6

def repo
  @repo
end

Instance Method Details

#all_deploy_tags(prefix:, environment:) ⇒ Array[Hash]

Return all tags starting “harness-deploy-ENV-”

Used to find deployments in an environment. Provides only the tag name and object, though that may be an annotated tag or a commit.

Use #get_commit_sha_from_tag to reliably find the commit that a tag points to.

Returns:

  • (Array[Hash])

    Array of tag data hash, or [] if none



36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/fa-harness-tools/github_client.rb', line 36

def all_deploy_tags(prefix:, environment:)
  # #refs is a much quicker way than #tags to pull back all tag names, so
  # we prefer this and then fetch commit information only when we need it
  @octokit.refs(owner_repo, "tags/#{prefix}-#{environment}-").map do |ref|
    {
      name: ref[:ref][10..-1], # remove refs/tags/ prefix
      object: ref[:object],
    }
  end
rescue Octokit::NotFound
  []
end

#branch_contains?(branch, commit) ⇒ Bool

Checks if <commit> is on branch <branch>

Returns:

  • (Bool)

    True is <commit> is on <branch>



112
113
114
115
116
117
# File 'lib/fa-harness-tools/github_client.rb', line 112

def branch_contains?(branch, commit)
  # The same implementation works for this question. We have both methods
  # to make the intent clearer and also this one is guaranteed to resolve a
  # branch name for the first argument.
  is_ancestor_of?(commit, branch)
end

#create_tag(tag, message, commit_sha, *args) ⇒ Object

Creates a Git tag

Arguments match Octokit::Client::Objects#create_tag, minus first repo argument (octokit.github.io/octokit.rb/Octokit/Client/Objects.html#create_tag-instance_method)



123
124
125
126
# File 'lib/fa-harness-tools/github_client.rb', line 123

def create_tag(tag, message, commit_sha, *args)
  @octokit.create_ref(owner_repo, "tags/#{tag}", commit_sha)
  @octokit.create_tag(owner_repo, tag, message, commit_sha, *args)
end

#get_commit_sha(short_sha) ⇒ String

Return a full commit SHA from a short SHA

Returns:

  • (String)

    Full commit SHA

Raises:



69
70
71
72
73
# File 'lib/fa-harness-tools/github_client.rb', line 69

def get_commit_sha(short_sha)
  commit = @octokit.commit(owner_repo, short_sha)
  raise LookupError, "Unable to find commit #{short_sha} in Git repo" unless commit
  commit[:sha]
end

#get_commit_sha_from_tag(tag) ⇒ String

Return a full commit SHA from a tag

The ‘tag` argument should be a Hash of tag data with an :object that can either be an annotated tag or a commit object.

Returns:

  • (String)

    Full commit SHA

Raises:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/fa-harness-tools/github_client.rb', line 82

def get_commit_sha_from_tag(tag)
  case tag[:object][:type]
  when "commit"
    tag[:object][:sha]
  when "tag"
    # When a tag points to a tag, recurse into it until we find a commit object
    refed_tag = @octokit.tag(owner_repo, tag[:object][:sha])
    get_commit_sha_from_tag(refed_tag.to_h.merge(tag.slice(:name)))
  else
    raise LookupError, "Tag #{tag[:name]} points to a non-commit object (#{tag[:object].inspect})"
  end
rescue Octokit::NotFound
  raise LookupError, "Unable to find tag #{tag.inspect} in Git repo"
end

#is_ancestor_of?(ancestor, commit) ⇒ Bool

Checks if <ancestor> is an ancestor of <commit>

i.e. commit and ancestor are directly related

Returns:

  • (Bool)

    True is <ancestor> is ancestor of <commit>



102
103
104
105
106
107
# File 'lib/fa-harness-tools/github_client.rb', line 102

def is_ancestor_of?(ancestor, commit)
  # Compare returns the merge base, the common point in history between the
  # two commits. If X is the ancestor of Y, then the merge base must be X.
  # If not, it's a different branch.
  @octokit.compare(owner_repo, ancestor, commit)[:merge_base_commit][:sha] == get_commit_sha(ancestor)
end

#last_deploy_tag(prefix:, environment:) ⇒ Hash

Return the last (when sorted) tag starting “harness-deploy-ENV-”

Used to find the most recent deployment in an environment. The commit SHA of the tag is in [:commit] in the returned hash.

Returns:

  • (Hash)

    Tag data hash, or nil if none



55
56
57
58
59
60
61
62
63
# File 'lib/fa-harness-tools/github_client.rb', line 55

def last_deploy_tag(prefix:, environment:)
  last_tag = all_deploy_tags(prefix: prefix, environment: environment).
    sort_by { |tag| tag[:name] }.last
  return nil unless last_tag

  last_tag.merge(
    commit: { sha: get_commit_sha_from_tag(last_tag) },
  )
end

#owner_repoObject



23
24
25
# File 'lib/fa-harness-tools/github_client.rb', line 23

def owner_repo
  "#{owner}/#{repo}"
end