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 +4 -4
- data/CHANGELOG.md +9 -2
- data/Gemfile.lock +10 -1
- data/lib/ghamma/cli/duration.rb +61 -0
- data/lib/ghamma/cli/version.rb +15 -0
- data/lib/ghamma/cli.rb +3 -50
- data/lib/ghamma/github_api_client.rb +32 -25
- data/lib/ghamma/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26ed59a6dae9c41b8fe6a3aa7b24f7ba2cc430696acfa061094c2e1e690a437d
|
4
|
+
data.tar.gz: 7bc89adfb0d48a8c4cfed55c1633771fcf57889e56e67efcbe2cc4f5d4ab5d7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0df963608fd632710848105a954214aa5c6fbc33a7a789230d372567d0de534f5320e82ce2cd0d4b5854b960528faa5f1ca64962e2ed5c7f56219b19a0bfcb4
|
7
|
+
data.tar.gz: 7817262789b374aa634ac3c5087d88c3e9672bcb50b783928c2bf349461278c41da2b4b9702c062b4bed7116940b1eea4e584cd67f6ba72d1774a9286be53fcb
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
-
##
|
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.
|
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
|
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 "./
|
6
|
-
require_relative "./
|
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 "
|
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
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
21
|
-
|
22
|
-
.find { |workflow| workflow["name"] == workflow_name }
|
23
|
-
&.fetch("id", nil)
|
17
|
+
while page <= pages
|
18
|
+
since_param = ">#{since}" if since
|
24
19
|
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
data/lib/ghamma/version.rb
CHANGED
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.
|
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-
|
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
|