dri 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fb31c263acfb2d576ed72028d207df2d36d76b1965ac00aa5228fbdd991a7524
4
+ data.tar.gz: 179c9389a9b3ce00a9f4ff357da3d1f4fdf3af9b22ec96a8d582dfb7d35bf17a
5
+ SHA512:
6
+ metadata.gz: d38a554fad6c98a72992c2d5c97eae39f6ecebce78ff466174f20074a4aa74b436ee6fcff6192ad4800515056fd9e53ec049a5aa1f6dfa90fdcafa2489376256
7
+ data.tar.gz: 2f2994a17800bd2d1fbf02ed9724e9b0428e4ded12ae9516135d19a6b529982d3e36d2148e6ef9df4f6bc740355555831ed035b440d30d89f94fdf814e3a1a99
data/.editorconfig ADDED
@@ -0,0 +1,9 @@
1
+ root = true
2
+
3
+ [*.rb]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ indent_style = space
8
+ indent_size = 2
9
+ trim_trailing_whitespace = true
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ .dri_profile.yml
14
+ handover_reports/*
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,28 @@
1
+ image: ruby:3.0.2
2
+
3
+ stages:
4
+ - build
5
+ - test
6
+ - deploy
7
+
8
+ before_script:
9
+ - gem install bundler:2.2.22
10
+ - bundle install
11
+
12
+ build_gem:
13
+ stage: build
14
+ script:
15
+ - gem build
16
+
17
+ rspec:
18
+ stage: test
19
+ script:
20
+ - bundle exec rspec
21
+
22
+ deploy:
23
+ stage: deploy
24
+ script:
25
+ - gem push dri*.gem
26
+ rules:
27
+ - if: '$CI_COMMIT_TAG'
28
+ when: always
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in dri.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "rspec", "~> 3.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,107 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dri (0.1.0)
5
+ httparty (~> 0.20.0)
6
+ json (~> 2.6.1)
7
+ markdown-tables (~> 1.1.1)
8
+ pastel (~> 0.8.0)
9
+ thor (~> 1.0.1)
10
+ tty-box (~> 0.7.0)
11
+ tty-config (~> 0.4.0)
12
+ tty-editor (~> 0.6)
13
+ tty-font (~> 0.5)
14
+ tty-logger (~> 0.6.0)
15
+ tty-prompt (~> 0.23.1)
16
+ tty-spinner (~> 0.9)
17
+ tty-table (~> 0.12.0)
18
+
19
+ GEM
20
+ remote: https://rubygems.org/
21
+ specs:
22
+ addressable (2.8.0)
23
+ public_suffix (>= 2.0.2, < 5.0)
24
+ crack (0.4.5)
25
+ rexml
26
+ diff-lcs (1.5.0)
27
+ hashdiff (1.0.1)
28
+ httparty (0.20.0)
29
+ mime-types (~> 3.0)
30
+ multi_xml (>= 0.5.2)
31
+ json (2.6.1)
32
+ markdown-tables (1.1.1)
33
+ mime-types (3.4.1)
34
+ mime-types-data (~> 3.2015)
35
+ mime-types-data (3.2022.0105)
36
+ multi_xml (0.6.0)
37
+ pastel (0.8.0)
38
+ tty-color (~> 0.5)
39
+ public_suffix (4.0.6)
40
+ rake (12.3.3)
41
+ rexml (3.2.5)
42
+ rspec (3.11.0)
43
+ rspec-core (~> 3.11.0)
44
+ rspec-expectations (~> 3.11.0)
45
+ rspec-mocks (~> 3.11.0)
46
+ rspec-core (3.11.0)
47
+ rspec-support (~> 3.11.0)
48
+ rspec-expectations (3.11.0)
49
+ diff-lcs (>= 1.2.0, < 2.0)
50
+ rspec-support (~> 3.11.0)
51
+ rspec-mocks (3.11.0)
52
+ diff-lcs (>= 1.2.0, < 2.0)
53
+ rspec-support (~> 3.11.0)
54
+ rspec-support (3.11.0)
55
+ strings (0.2.1)
56
+ strings-ansi (~> 0.2)
57
+ unicode-display_width (>= 1.5, < 3.0)
58
+ unicode_utils (~> 1.4)
59
+ strings-ansi (0.2.0)
60
+ thor (1.0.1)
61
+ timecop (0.9.5)
62
+ tty-box (0.7.0)
63
+ pastel (~> 0.8)
64
+ strings (~> 0.2.0)
65
+ tty-cursor (~> 0.7)
66
+ tty-color (0.6.0)
67
+ tty-config (0.4.0)
68
+ tty-cursor (0.7.1)
69
+ tty-editor (0.7.0)
70
+ tty-prompt (~> 0.22)
71
+ tty-font (0.5.0)
72
+ tty-logger (0.6.0)
73
+ pastel (~> 0.8)
74
+ tty-prompt (0.23.1)
75
+ pastel (~> 0.8)
76
+ tty-reader (~> 0.8)
77
+ tty-reader (0.9.0)
78
+ tty-cursor (~> 0.7)
79
+ tty-screen (~> 0.8)
80
+ wisper (~> 2.0)
81
+ tty-screen (0.8.1)
82
+ tty-spinner (0.9.3)
83
+ tty-cursor (~> 0.7)
84
+ tty-table (0.12.0)
85
+ pastel (~> 0.8)
86
+ strings (~> 0.2.0)
87
+ tty-screen (~> 0.8)
88
+ unicode-display_width (2.1.0)
89
+ unicode_utils (1.4.0)
90
+ webmock (3.14.0)
91
+ addressable (>= 2.8.0)
92
+ crack (>= 0.3.2)
93
+ hashdiff (>= 0.4.0, < 2.0.0)
94
+ wisper (2.0.1)
95
+
96
+ PLATFORMS
97
+ ruby
98
+
99
+ DEPENDENCIES
100
+ dri!
101
+ rake (~> 12.0)
102
+ rspec (~> 3.0)
103
+ timecop (~> 0.9.1)
104
+ webmock (~> 3.5)
105
+
106
+ BUNDLED WITH
107
+ 2.1.4
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 GitLab, Inc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # DRI
2
+
3
+ So, are you the **D**irectly **R**esponsible **I**ndividual for GitLab's QA pipelines this week? Looking for a gem to help triage and report failing tests? Look no further.
4
+
5
+ Welcome to your new gem! DRI is a CLI ready to help:
6
+
7
+ - Fetching failing test cases by pipeline
8
+ - Reporting at the end of the timezone shift
9
+ - View today's newest and untriaged failures
10
+ - Take actions on failures
11
+
12
+ ... and more.
13
+
14
+ ## Installation
15
+
16
+ To install the `dri` gem:
17
+
18
+ ```shell
19
+ $ gem install dri
20
+ ```
21
+
22
+ And then execute `dri` to see all available options:
23
+
24
+ ```shell
25
+ $ dri
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ ### Configuration
31
+
32
+ To use `dri` fully it is necessary to have:
33
+
34
+ - a Personal Access Token
35
+ - a triage emoji
36
+
37
+ The emoji is the [Award/My Reaction](https://docs.gitlab.com/ee/user/award_emojis.html) emoji associated with the failure issues to group all failures triaged on a given day. This emoji is a personal choice. Note that the same emoji should be used only while triaging failures and not associated with other issues out of the scope of triage.
38
+
39
+ To set up your personal profile:
40
+
41
+ ```shell
42
+ $ dri init
43
+ ```
44
+
45
+ To verify the profile is correctly set:
46
+
47
+ ```shell
48
+ $ dri profile
49
+ ```
50
+
51
+ ### Commands
52
+
53
+ - [1. init](#1-init)
54
+ - [2. profile](#2-profile)
55
+ - [3. fetch](#3-fetch)
56
+ - failures
57
+ - testcases
58
+ - [4. publish](#4-publish)
59
+ - report
60
+ - [5. rm](#5-rm)
61
+ - emoji
62
+ - [6. version](#6-version)
63
+
64
+ #### 1. init
65
+
66
+ ```shell
67
+ $ dri init
68
+ ```
69
+
70
+ Initializes the `dri` CLI with necessary configurations to run smoothly.
71
+
72
+ #### 2. profile
73
+
74
+ ```shell
75
+ $ dri profile
76
+ ```
77
+
78
+ Shows the current profile associated after initial configuration.
79
+ Pass the option `--edit` to edit the current profile.
80
+
81
+ #### 3. fetch
82
+
83
+ ```shell
84
+ $ dri fetch failures
85
+ ```
86
+
87
+ Fetches today's opened failures and lists them according to their triage status.
88
+ Helpful to understand if there are missing recent failures to be reviewed.
89
+
90
+ ```shell
91
+ $ dri fetch testcases
92
+ ```
93
+
94
+ Fetches test cases that failing currently and groups them by pipeline.
95
+ To filter the pipelines, pass the `--filter-pipelines` options to multi-select the pipelines you wish to consult.
96
+ (Use `Space` to select an option)
97
+
98
+ #### 4. publish
99
+
100
+ ```shell
101
+ $ dri publish report
102
+ ```
103
+
104
+ Publishes a handover report on the latest triage issue, in the [pipeline-triage](https://gitlab.com/gitlab-org/quality/pipeline-triage) project.
105
+
106
+ **Options**
107
+
108
+ ```shell
109
+ $ dri publish report --format=list # formats the report in a list
110
+ $ dri publish report --format=table # formats the report in a table (default)
111
+ $ dri publish report --dry-run # the report is only generated locally
112
+ ```
113
+
114
+ #### 5. rm
115
+
116
+ ```shell
117
+ $ dri rm emoji
118
+ ```
119
+
120
+ Removes the triage emoji from all triaged issues.
121
+
122
+ #### 6. version
123
+
124
+ ```shell
125
+ $ dri version
126
+ ```
127
+
128
+ `dri` gem version.
129
+
130
+ ## Copyright
131
+
132
+ Copyright (c) 2022 GitLab, Inc. See [MIT License](LICENSE.txt) for further details.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "dri"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/dri.gemspec ADDED
@@ -0,0 +1,41 @@
1
+ require_relative 'lib/dri/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "dri"
5
+ spec.license = "MIT"
6
+ spec.version = Dri::VERSION
7
+ spec.authors = ["GitLab Quality"]
8
+ spec.email = ["quality+dri@gitlab.com"]
9
+
10
+ spec.summary = %q{CLI app to help triage GitLab QA pipelines}
11
+ spec.homepage = 'https://gitlab.com/gitlab-org/quality/dri'
12
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
13
+
14
+ # Specify which files should be added to the gem when it is released.
15
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
16
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
17
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "tty-config", "~> 0.4.0"
24
+ spec.add_dependency "tty-font", "~> 0.5"
25
+ spec.add_dependency "tty-prompt", "~> 0.23.1"
26
+ spec.add_dependency "tty-spinner", "~> 0.9"
27
+ spec.add_dependency "tty-table", "~> 0.12.0"
28
+ spec.add_dependency 'tty-box', '~> 0.7.0'
29
+ spec.add_dependency 'tty-logger', '~> 0.6.0'
30
+ spec.add_dependency "tty-editor", "~> 0.6"
31
+ spec.add_dependency "pastel", "~> 0.8.0"
32
+ spec.add_dependency "thor", "~> 1.0.1"
33
+ spec.add_dependency "markdown-tables", "~> 1.1.1"
34
+ spec.add_dependency 'json', '~> 2.6.1'
35
+ spec.add_dependency 'httparty', '~> 0.20.0'
36
+
37
+ spec.add_development_dependency "rake"
38
+ spec.add_development_dependency 'rspec', '~> 3.10.0'
39
+ spec.add_development_dependency 'webmock', '~> 3.5'
40
+ spec.add_development_dependency "timecop", "~> 0.9.1"
41
+ end
data/exe/dri ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ lib_path = File.expand_path('../lib', __dir__)
5
+ $:.unshift(lib_path) if !$:.include?(lib_path)
6
+ require 'dri/cli'
7
+
8
+ Signal.trap('INT') do
9
+ warn("\n#{caller.join("\n")}: interrupted")
10
+ exit(1)
11
+ end
12
+
13
+ begin
14
+ Dri::CLI.start
15
+ rescue Dri::CLI::Error => err
16
+ puts "ERROR: #{err.message}"
17
+ exit 1
18
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "httparty"
4
+ require "json"
5
+ require "tty-config"
6
+
7
+ module Dri
8
+ class ApiClient
9
+
10
+ API_URL = 'https://gitlab.com/api/v4'
11
+ TESTCASES_PROJECT_ID = '11229385'
12
+ TRIAGE_PROJECT_ID = '34185524'
13
+ GITLAB_PROJECT_ID = '278964'
14
+
15
+ def initialize(config)
16
+ profile = config.read
17
+ @token = profile["settings"]["token"]
18
+ end
19
+
20
+ def header
21
+ @header ||= { 'Content-Type' => 'application/json', "Authorization" => "Bearer #{@token}" }
22
+ end
23
+
24
+ def fetch_triaged_failures(emoji:, state:)
25
+ url = ["#{API_URL}/issues"]
26
+ url << "?order_by=updated_at&my_reaction_emoji=#{emoji}"
27
+ url << "&scope=all&state=#{state}"
28
+
29
+ fetch_json(url.join)
30
+ end
31
+
32
+ def fetch_awarded_emojis(url)
33
+ fetch_json(url)
34
+ end
35
+
36
+ def fetch_failing_testcases(pipeline, state:)
37
+ url = ["#{API_URL}/projects/"]
38
+ url << "#{TESTCASES_PROJECT_ID}/issues?labels=#{pipeline}::failed"
39
+ url << "&state=#{state}&not[labels]=quarantine"
40
+ url << "&scope=all"
41
+
42
+ fetch_json(url.join)
43
+ end
44
+
45
+ def fetch_related_mrs(issue_iid:)
46
+ url = ["#{API_URL}/projects/"]
47
+ url << "#{GITLAB_PROJECT_ID}/issues/"
48
+ url << "#{issue_iid}/related_merge_requests"
49
+
50
+ fetch_json(url.join)
51
+ end
52
+
53
+ def fetch_current_triage_issue
54
+ url = ["#{API_URL}/projects/"]
55
+ url << "#{TRIAGE_PROJECT_ID}/issues?state=opened"
56
+ url << "&order_by=updated_at"
57
+
58
+ fetch_json(url.join)
59
+ end
60
+
61
+ def post_triage_report_note(iid:, body:)
62
+ url = ["#{API_URL}/projects/"]
63
+ url << "#{TRIAGE_PROJECT_ID}/issues/#{iid}/notes"
64
+
65
+ post_json(url.join, body)
66
+ end
67
+
68
+ def fetch_failures(date:, state:)
69
+ url = ["#{API_URL}/issues"]
70
+ url << "?labels=failure::new"
71
+ url << "&order_by=updated_at&state=#{state}"
72
+ url << "&scope=all"
73
+ url << "&created_after=#{date}"
74
+
75
+ fetch_json(url.join)
76
+ end
77
+
78
+ def fetch_failure_notes(issue_iid:)
79
+ url = ["#{API_URL}/projects/"]
80
+ url << "#{GITLAB_PROJECT_ID}/issues/"
81
+ url << "#{issue_iid}/notes?per_page=15"
82
+
83
+ fetch_json(url.join)
84
+ end
85
+
86
+ def delete_award_emoji(url)
87
+ delete_json(url)
88
+ end
89
+
90
+ private
91
+
92
+ def post_json(url, body)
93
+ options = {
94
+ body: { body: body },
95
+ headers: {
96
+ "Authorization" => "Bearer #{@token}"
97
+ }
98
+ }
99
+
100
+ response = HTTParty.post(url, options)
101
+ handle_response(response)
102
+ end
103
+
104
+ def delete_json(url)
105
+ response = HTTParty.delete(url, headers: header)
106
+ handle_response(response)
107
+ end
108
+
109
+ def handle_response(response)
110
+ #puts response.to_json
111
+ response
112
+ end
113
+
114
+ def fetch_json(url)
115
+ response = HTTParty.get(url, headers: header)
116
+
117
+ if response.code != 200
118
+ puts "Response error code \"#{response.code}\" - Unable to sync with GitLab"
119
+ exit 1
120
+ end
121
+
122
+ handle_response(JSON.parse(response.body))
123
+ end
124
+ end
125
+ end
data/lib/dri/cli.rb ADDED
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+ require "pastel"
5
+ require "tty-font"
6
+
7
+ module Dri
8
+ # Handle the application command line parsing
9
+ # and the dispatch to various command objects
10
+ #
11
+ # @api public
12
+ class CLI < Thor
13
+ # Error raised by this runner
14
+ Error = Class.new(StandardError)
15
+
16
+ def self.exit_on_failure?
17
+ true
18
+ end
19
+
20
+ def help(*args)
21
+ font = TTY::Font.new(:doom)
22
+ pastel = Pastel.new(enabled: !options[:no_color])
23
+ puts pastel.yellow(font.write("DRI"))
24
+ super
25
+ end
26
+
27
+ class_option :no_color, type: :boolean, default: false,
28
+ desc: "Disable colorization in output"
29
+
30
+ desc 'version', 'dri version'
31
+ def version
32
+ require_relative 'version'
33
+ puts "v#{Dri::VERSION}"
34
+ end
35
+ map %w(--version -v) => :version
36
+
37
+ require_relative 'commands/rm'
38
+ register Dri::Commands::Rm, 'rm', 'rm [SUBCOMMAND]', 'Remove triage-related items'
39
+
40
+ desc 'profile', 'View current user settings'
41
+ method_option :help, aliases: '-h', type: :boolean,
42
+ desc: 'Display usage information'
43
+ method_option :edit, type: :string, banner: "editor",
44
+ desc: "Open the holdings configuration file for " \
45
+ "editing in EDITOR, or the default editor " \
46
+ "if not specified."
47
+ def profile(*)
48
+ if options[:help]
49
+ invoke :help, ['profile']
50
+ else
51
+ require_relative 'commands/profile'
52
+ Dri::Commands::Profile.new(options).execute
53
+ end
54
+ end
55
+
56
+ desc 'init', 'Create a configuration to use dri'
57
+ method_option :help, aliases: '-h', type: :boolean,
58
+ desc: 'Display usage information'
59
+ def init(*)
60
+ if options[:help]
61
+ invoke :help, ['init']
62
+ else
63
+ require_relative 'commands/init'
64
+ Dri::Commands::Init.new(options).execute
65
+ end
66
+ end
67
+
68
+ require_relative 'commands/fetch'
69
+ register Dri::Commands::Fetch, 'fetch', 'fetch [SUBCOMMAND]', 'Fetch failures & testcases'
70
+
71
+ require_relative 'commands/publish'
72
+ register Dri::Commands::Publish, 'publish', 'publish [SUBCOMMAND]', 'Publish report for handover'
73
+ end
74
+ end