Module: CIRunner::TestRunFinder

Extended by:
TestRunFinder
Included in:
TestRunFinder
Defined in:
lib/ci_runner/test_run_finder.rb

Constant Summary collapse

GITHUB_ACTION =
"github-actions"

Instance Method Summary collapse

Instance Method Details

#detect_runner(ci_log) ⇒ Runners::MinitestRunner, Runners::RSpec

Try to guess which runner (Minitest, RSpec) was responsible for this log output.

The runner is the most important part of CI Runner. It’s what determine the failures for a CI log, as well as how to rerun those only.

Raises:

  • (Error)

    In case none of the runners could detect the log output.



103
104
105
106
107
108
109
110
111
# File 'lib/ci_runner/test_run_finder.rb', line 103

def detect_runner(ci_log)
  raise_if_not_found = lambda { raise(Error, "Couldn't detect the test runner") }

  runner = [Runners::MinitestRunner, Runners::RSpec].find(raise_if_not_found) do |runner|
    runner.match?(ci_log)
  end

  runner.new(ci_log)
end

#fetch_ci_checks(repository, commit, &block) ⇒ Array<Check::Base>

Makes a request to GitHub to retrieve the checks for a commit. Display a nice UI with a spinner while the user wait.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ci_runner/test_run_finder.rb', line 18

def fetch_ci_checks(repository, commit, &block)
  error = nil
  ci_checks = []
  title = "Fetching failed CI checks from GitHub for commit {{info:#{commit[..12]}}}"

  ::CLI::UI.spinner(title, auto_debrief: false) do
    ci_checks = github_ci(repository, commit)
    ci_checks += other_ci(repository, commit)
  rescue Client::Error, StandardError => e
    error = e

    ::CLI::UI::Spinner::TASK_FAILED
  end

  block.call(error) if error

  ci_checks
end

#find(ci_checks, run_name) ⇒ Check::Base

Find the CI check the user requested from the list of upstream checks. This method is useful only when the user passes the ‘–run-name` flag to `ci-runner`. This makes sure the CI check actually exists.

Raises:

  • (Error)

    If no CI checks with the given run_name could be found.

  • (Error)

    If the CI check was successfull. No point to continue as there should be no tests to rerun.



85
86
87
88
89
90
91
# File 'lib/ci_runner/test_run_finder.rb', line 85

def find(ci_checks, run_name)
  check_run = ci_checks.find { |check| check.name == run_name }
  raise(Error, no_check_message(ci_checks, run_name)) if check_run.nil?
  raise(Error, check_succeed(run_name)) unless check_run.failed?

  check_run
end

#github_ci(repository, commit) ⇒ Array<Check::Github>

Download the GitHub checks. This is used in case a project uses GitHub itself as its CI provider.



45
46
47
48
49
50
51
52
53
54
# File 'lib/ci_runner/test_run_finder.rb', line 45

def github_ci(repository, commit)
  github_client = Client::Github.new(Configuration::User.instance.github_token)
  ci_checks = github_client.check_runs(repository, commit)["check_runs"]

  ci_checks.filter_map do |check_run|
    next unless check_run.dig("app", "slug") == GITHUB_ACTION

    Check::Github.new(repository, commit, *check_run.values_at("name", "conclusion", "id"))
  end
end

#other_ci(repository, commit) ⇒ Array<Check::CircleCI, Check::Unsupported>

Download the Commit Statuses for this commit. Some CI provider (like GitHub or Buildkite), doesn’t use the GitHub Check API, but instead this API.



65
66
67
68
69
70
71
72
# File 'lib/ci_runner/test_run_finder.rb', line 65

def other_ci(repository, commit)
  github_client = Client::Github.new(Configuration::User.instance.github_token)
  commit_statuses = github_client.commit_statuses(repository, commit)

  commit_statuses.map do |commit_status|
    check_class_from_url(commit_status, repository, commit)
  end.compact
end