ghamma 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 374a835681570e0824d2ee192361ed16dbfc11352cc8f8f0f69ad2a0cdaa8f7f
4
- data.tar.gz: 702786830164573d586113f1f88b8c5e983e71111c9ce3226274e468a374fb61
3
+ metadata.gz: 26ed59a6dae9c41b8fe6a3aa7b24f7ba2cc430696acfa061094c2e1e690a437d
4
+ data.tar.gz: 7bc89adfb0d48a8c4cfed55c1633771fcf57889e56e67efcbe2cc4f5d4ab5d7c
5
5
  SHA512:
6
- metadata.gz: 3e01904c7804ae9636d06aaad5af029736b8286200f2791851b10bdd11f6552721f7cdb2ab1c4dfe9489bd27ff98374f7d7037a15e0fb04ad22c396429b18361
7
- data.tar.gz: f2fb982a98a100f66072fbc80d0c4618f1281de82442dcf59c2b551ade25466303684d7fcbf55cf56eefded0a4d43ad35ce95eb7148764e71b2dc840c08c9b51
6
+ metadata.gz: a0df963608fd632710848105a954214aa5c6fbc33a7a789230d372567d0de534f5320e82ce2cd0d4b5854b960528faa5f1ca64962e2ed5c7f56219b19a0bfcb4
7
+ data.tar.gz: 7817262789b374aa634ac3c5087d88c3e9672bcb50b783928c2bf349461278c41da2b4b9702c062b4bed7116940b1eea4e584cd67f6ba72d1774a9286be53fcb
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
- ## [Unreleased]
1
+ ## Unreleased
2
2
 
3
- -
3
+ ## [0.3.0] - 2023-07-04
4
+
5
+ - Feature: Allow optionally specifying an output file for the CSV
6
+ - Change: Add ID of the workflow run to the output
7
+ - Feature: Support restricting workflow runs examined since a given date
8
+ - Feature: Fetch all the workflow runs, not just the first 100
9
+ - Breaking: Removed the `list-workflows` command and renamed the `duration-history` to just `duration`
10
+ - Breaking: The `duration` command now accepts the workflow file name (or ID) instead of the name
4
11
 
5
12
  ## [0.2.0] - 2023-06-01
6
13
 
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ghamma (0.2.0)
4
+ ghamma (0.3.0)
5
5
  dry-cli
6
6
  http
7
+ tty-progressbar
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
@@ -68,8 +69,16 @@ GEM
68
69
  standard-performance (1.0.1)
69
70
  lint_roller (~> 1.0)
70
71
  rubocop-performance (~> 1.16.0)
72
+ strings-ansi (0.2.0)
71
73
  test-unit (3.5.9)
72
74
  power_assert
75
+ tty-cursor (0.7.1)
76
+ tty-progressbar (0.18.2)
77
+ strings-ansi (~> 0.2)
78
+ tty-cursor (~> 0.7)
79
+ tty-screen (~> 0.8)
80
+ unicode-display_width (>= 1.6, < 3.0)
81
+ tty-screen (0.8.1)
73
82
  unf (0.1.4)
74
83
  unf_ext
75
84
  unf_ext (0.0.8.2)
@@ -0,0 +1,61 @@
1
+ require "csv"
2
+ require "dry/cli"
3
+ require "http"
4
+ require "tty/progressbar"
5
+
6
+ require_relative "../github_api_client"
7
+
8
+ module Ghamma
9
+ module CLI
10
+ class Duration < Dry::CLI::Command
11
+ desc "Extract the durations of successful runs of a workflow over time"
12
+
13
+ example [
14
+ "tony-rowan ghamma main.yml" \
15
+ " # Prints durations of all workflow runs of main.yml to STDOUT",
16
+ "tony-rowan ghamma main.yml --since='2023-07-01' --output='/tmp/main.csv'" \
17
+ " # Saves durations of all workflow runs of main.yml since 2023-07-01 to /tmp/main.csv"
18
+ ]
19
+
20
+ argument :owner, required: true, desc: "The user or organisation to whom the repo belongs"
21
+ argument :repo, required: true, desc: "The repo to which the workflow belongs"
22
+ argument :workflow, required: true, desc: "The filename for the desired workflow, e.g. main.yml"
23
+
24
+ option :since, desc: "Optionally restrict workflows to those created since this date"
25
+ option :output, desc: "Optional file to which to output results, defaults to STDOUT"
26
+
27
+ def call(owner:, repo:, workflow:, since: nil, output: nil)
28
+ workflow_statement = "Fetching the durations of all workflow runs of #{workflow}"
29
+ since_statment = "since #{since}" if since
30
+
31
+ puts [workflow_statement, since_statment].join(" ")
32
+
33
+ progressbar = TTY::ProgressBar.new("Fetching workflow runs [:bar] :current/:total ETA: :eta", total: nil)
34
+
35
+ durations = GithubApiClient.new(owner: owner, repo: repo, token: ENV["GH_TOKEN"])
36
+ .fetch_workflow_duration_history(workflow, since, progressbar)
37
+
38
+ progressbar.finish
39
+
40
+ puts "Generating output"
41
+
42
+ durations_output = CSV.generate do |csv|
43
+ csv << ["ID", "Date", "Duration"]
44
+ durations.each do |duration|
45
+ csv << duration
46
+ end
47
+ end
48
+
49
+ if output
50
+ File.write(output, durations_output)
51
+ else
52
+ puts
53
+ puts durations_output
54
+ puts
55
+ end
56
+
57
+ puts "Done"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,15 @@
1
+ require "dry/cli"
2
+
3
+ require_relative "../version"
4
+
5
+ module Ghamma
6
+ module CLI
7
+ class Version < Dry::CLI::Command
8
+ desc "Print version"
9
+
10
+ def call(*)
11
+ puts VERSION
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/ghamma/cli.rb CHANGED
@@ -1,60 +1,13 @@
1
- require "csv"
2
1
  require "dry/cli"
3
- require "http"
4
2
 
5
- require_relative "./github_api_client"
6
- require_relative "./version"
3
+ require_relative "./cli/version"
4
+ require_relative "./cli/duration"
7
5
 
8
6
  module Ghamma
9
7
  module CLI
10
8
  extend Dry::CLI::Registry
11
9
 
12
- class Version < Dry::CLI::Command
13
- desc "Print version"
14
-
15
- def call(*)
16
- puts VERSION
17
- end
18
- end
19
-
20
- class ListWorkflows < Dry::CLI::Command
21
- desc "List workflows on the given repo"
22
-
23
- argument :owner, required: true
24
- argument :repo, required: true
25
-
26
- def call(owner:, repo:)
27
- workflows = GithubApiClient.new(owner: owner, repo: repo, token: ENV["GH_TOKEN"]).fetch_workflows
28
- puts "Found #{workflows.size} workflows"
29
- workflows.each { |workflow| puts workflow[:name] }
30
- puts
31
- end
32
- end
33
-
34
- class DurationHistory < Dry::CLI::Command
35
- desc "List the duration of each successful workflow run"
36
-
37
- argument :owner, required: true
38
- argument :repo, required: true
39
- argument :workflow, required: true
40
-
41
- def call(owner:, repo:, workflow:)
42
- durations = GithubApiClient.new(owner: owner, repo: repo, token: ENV["GH_TOKEN"]).fetch_workflow_duration_history(workflow)
43
-
44
- durations_output = CSV.generate do |csv|
45
- csv << ["Date", "Duration"]
46
- durations.each do |duration|
47
- csv << duration
48
- end
49
- end
50
-
51
- puts durations_output
52
- puts
53
- end
54
- end
55
-
56
10
  register "version", Version, aliases: ["v", "-v", "--version"]
57
- register "list-workflows", ListWorkflows
58
- register "duration-history", DurationHistory
11
+ register "duration", Duration
59
12
  end
60
13
  end
@@ -9,35 +9,42 @@ module Ghamma
9
9
  @authorization_header = "Bearer #{token}"
10
10
  end
11
11
 
12
- def fetch_workflows
13
- get("/workflows")
14
- .fetch("workflows")
15
- .map do |workflow_json|
16
- workflow_json.transform_keys(&:to_sym).slice(:id, :name)
17
- end
18
- end
12
+ def fetch_workflow_duration_history(workflow_id, since, progressbar)
13
+ pages = 2 # enough to do the first loop
14
+ page = 1
15
+ timings = []
19
16
 
20
- def fetch_workflow_duration_history(workflow_name)
21
- workflow_id = get("/workflows").fetch("workflows")
22
- .find { |workflow| workflow["name"] == workflow_name }
23
- &.fetch("id", nil)
17
+ while page <= pages
18
+ since_param = ">#{since}" if since
24
19
 
25
- if workflow_id.nil?
26
- raise "Could not find workflow with name #{workflow_name}"
27
- end
20
+ response = get(
21
+ "/workflows/#{workflow_id}/runs",
22
+ {page: page, per_page: 100, status: "success", exclude_pull_requests: true, created: since_param}.compact
23
+ )
24
+
25
+ total_count = response["total_count"]
26
+ progressbar.update(total: total_count)
27
+ pages = total_count / 100
28
+ page += 1
29
+
30
+ response.fetch("workflow_runs").each do |workflow_run|
31
+ run_timing = get("/runs/#{workflow_run["id"]}/timing")
28
32
 
29
- workflow_runs = get(
30
- "/workflows/#{workflow_id}}/runs",
31
- {per_page: 100, status: "success", exclude_pull_requests: true}
32
- ).fetch("workflow_runs")
33
- .map do |workflow_run|
34
- run_timing = get("/runs/#{workflow_run["id"]}/timing")
35
-
36
- [
37
- workflow_run["created_at"],
38
- run_timing["run_duration_ms"]
39
- ]
33
+ timings << [
34
+ workflow_run["id"],
35
+ workflow_run["created_at"],
36
+ run_timing["run_duration_ms"]
37
+ ]
38
+
39
+ progressbar.advance
40
+
41
+ sleep 0.1 # Try to keep under the Github rate limit
42
+ end
43
+
44
+ sleep 1 # Try to keep under the Github rate limit
40
45
  end
46
+
47
+ timings
41
48
  end
42
49
 
43
50
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ghamma
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ghamma
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Rowan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-01 00:00:00.000000000 Z
11
+ date: 2023-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-cli
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tty-progressbar
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -99,6 +113,8 @@ files:
99
113
  - exe/ghamma
100
114
  - lib/ghamma.rb
101
115
  - lib/ghamma/cli.rb
116
+ - lib/ghamma/cli/duration.rb
117
+ - lib/ghamma/cli/version.rb
102
118
  - lib/ghamma/github_api_client.rb
103
119
  - lib/ghamma/version.rb
104
120
  - sig/ghamma.rbs