gitlab-triage 0.0.1

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.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +19 -0
  3. data/.gitignore +15 -0
  4. data/.gitlab-ci.yml +101 -0
  5. data/.gitlab/issue_templates/Policy.md +32 -0
  6. data/.rubocop.yml +6 -0
  7. data/Gemfile +4 -0
  8. data/Guardfile +70 -0
  9. data/README.md +13 -0
  10. data/Rakefile +6 -0
  11. data/bin/gitlab-triage +63 -0
  12. data/gitlab-triage.gemspec +29 -0
  13. data/lib/gitlab/triage.rb +6 -0
  14. data/lib/gitlab/triage/command_builders/base_command_builder.rb +32 -0
  15. data/lib/gitlab/triage/command_builders/cc_command_builder.rb +19 -0
  16. data/lib/gitlab/triage/command_builders/comment_command_builder.rb +23 -0
  17. data/lib/gitlab/triage/command_builders/label_command_builder.rb +19 -0
  18. data/lib/gitlab/triage/command_builders/status_command_builder.rb +23 -0
  19. data/lib/gitlab/triage/engine.rb +146 -0
  20. data/lib/gitlab/triage/filter_builders/base_filter_builder.rb +18 -0
  21. data/lib/gitlab/triage/filter_builders/multi_filter_builder.rb +20 -0
  22. data/lib/gitlab/triage/filter_builders/single_filter_builder.rb +13 -0
  23. data/lib/gitlab/triage/limiters/base_conditions_limiter.rb +65 -0
  24. data/lib/gitlab/triage/limiters/date_conditions_limiter.rb +63 -0
  25. data/lib/gitlab/triage/limiters/name_conditions_limiter.rb +30 -0
  26. data/lib/gitlab/triage/limiters/votes_conditions_limiter.rb +54 -0
  27. data/lib/gitlab/triage/network.rb +37 -0
  28. data/lib/gitlab/triage/network_adapters/httparty_adapter.rb +36 -0
  29. data/lib/gitlab/triage/network_adapters/test_adapter.rb +31 -0
  30. data/lib/gitlab/triage/retryable.rb +31 -0
  31. data/lib/gitlab/triage/ui.rb +15 -0
  32. data/lib/gitlab/triage/version.rb +5 -0
  33. data/policies.yml +232 -0
  34. metadata +160 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ff9f08acbd7e13f681bff4673c63d450b283f70a30d19a5831556b3d99bc3b49
4
+ data.tar.gz: 7ef092df664c16f65aecaf34ef1983ea25c2a9b611c0fcd33be96c3188624bdb
5
+ SHA512:
6
+ metadata.gz: 4587c4b294c332aab7d113d1925f0ee86512d02bcb8aabcaf59ad25f71674290ca361101094deb339a03f6e296ac0fd46142a6a1b5c548e6282efa2cedf68906
7
+ data.tar.gz: 786ad737d5891758591b4d78533b25f3aff7993c2a235e419603d8a5bcd01e18ae138514e7e73f7827126f6cf4ae94aa58225eb7b9029b8f7874aab8a36ed1a8
@@ -0,0 +1,19 @@
1
+ ---
2
+ engines:
3
+ bundler-audit:
4
+ enabled: true
5
+ duplication:
6
+ enabled: true
7
+ config:
8
+ languages:
9
+ - ruby
10
+ rubocop-gitlab:
11
+ enabled: true
12
+ ratings:
13
+ paths:
14
+ - Gemfile.lock
15
+ - "**.rb"
16
+ exclude_paths:
17
+ - spec/
18
+ - vendor/
19
+ - tmp/
@@ -0,0 +1,15 @@
1
+ /.DS_Store
2
+ /vendor/
3
+ /.rspec
4
+ /.bundle/
5
+ /.yardoc
6
+ /Gemfile.lock
7
+ /_yardoc/
8
+ /coverage/
9
+ /doc/
10
+ /pkg/
11
+ /spec/reports/
12
+ /tmp/
13
+
14
+ # rspec failure tracking
15
+ .rspec_status
@@ -0,0 +1,101 @@
1
+ image: ruby:2.4
2
+
3
+ stages:
4
+ - prepare
5
+ - test
6
+ - process_rules
7
+
8
+ .default-cache-config: &default-cache-config
9
+ key: "ruby-2.4"
10
+ paths:
11
+ - vendor/cache/
12
+ - Gemfile.lock
13
+
14
+ .pull-cache: &pull-cache
15
+ cache:
16
+ <<: *default-cache-config
17
+ policy: pull
18
+
19
+ before_script:
20
+ - gem install bundler
21
+ - bundle --version
22
+ - bundle install --jobs $(nproc) --retry 3 --quiet
23
+
24
+ setup-test-env:
25
+ stage: prepare
26
+ script:
27
+ - echo "All set!"
28
+ cache:
29
+ <<: *default-cache-config
30
+ artifacts:
31
+ paths:
32
+ - vendor/cache/
33
+ - Gemfile.lock
34
+
35
+ styles:
36
+ stage: test
37
+ script:
38
+ - bundle exec rubocop
39
+ except:
40
+ - schedules
41
+ <<: *pull-cache
42
+
43
+ specs:
44
+ stage: test
45
+ script:
46
+ - bundle exec rake spec
47
+ <<: *pull-cache
48
+
49
+ build:
50
+ stage: test
51
+ script:
52
+ - bundle exec rake build
53
+ - bundle exec rake clobber
54
+ except:
55
+ - schedules
56
+ <<: *pull-cache
57
+
58
+ codequality:
59
+ image: docker:latest
60
+ stage: test
61
+ variables:
62
+ DOCKER_DRIVER: overlay
63
+ services:
64
+ - docker:dind
65
+ before_script: []
66
+ script:
67
+ - docker run
68
+ --env CODECLIMATE_CODE="$PWD"
69
+ --volume "$PWD":/code
70
+ --volume /var/run/docker.sock:/var/run/docker.sock
71
+ --volume /tmp/cc:/tmp/cc
72
+ dev.gitlab.org:5005/gitlab/gitlab-build-images:gitlab-codeclimate
73
+ analyze -f json > raw_codeclimate.json
74
+ - cat raw_codeclimate.json | docker run -i stedolan/jq -c 'map({check_name,fingerprint,location})' > codeclimate.json
75
+ artifacts:
76
+ paths:
77
+ - codeclimate.json
78
+ except:
79
+ - schedules
80
+ <<: *pull-cache
81
+
82
+ dry-run:triage:
83
+ stage: test
84
+ script:
85
+ - bundle exec bin/gitlab-triage --dry-run --token $API_TOKEN --policies-file policies.yml --project-id gitlab-org/triage
86
+ <<: *pull-cache
87
+
88
+ dry-run:gilab-ce:
89
+ stage: process_rules
90
+ script:
91
+ - bundle exec bin/gitlab-triage --dry-run --token $API_TOKEN --policies-file policies.yml --project-id gitlab-org/gitlab-ce
92
+ when: manual
93
+ <<: *pull-cache
94
+
95
+ results:
96
+ stage: process_rules
97
+ script:
98
+ - bundle exec bin/gitlab-triage --token $API_TOKEN --policies-file policies.yml --project-id gitlab-org/gitlab-ce
99
+ only:
100
+ - schedules
101
+ <<: *pull-cache
@@ -0,0 +1,32 @@
1
+ ### Policy title
2
+
3
+ ( add a title to accurately describe the policy that you are referring to )
4
+
5
+ ### New Policy/Policy Change/Policy Removal
6
+
7
+ ( declare the type of policy change this is )
8
+
9
+ ### Issues or Merge Requests Policy?
10
+
11
+ Issues/Merge Requests/both
12
+
13
+ ### Policy Conditions
14
+
15
+ ( declare the conditions for the related policy )
16
+
17
+ #### Example
18
+
19
+ - Label: bug
20
+ - not updated for over 6 months
21
+ - no associated milestone (unscheduled)
22
+ - state: open
23
+
24
+ ### Policy Actions
25
+
26
+ ( declare the actions for the related policy )
27
+
28
+ #### Example
29
+
30
+ - Add a comment
31
+ - Mention @markglenfletcher
32
+ - Label: "awaiting feedback" "auto updated"
@@ -0,0 +1,6 @@
1
+ inherit_gem:
2
+ gitlab-styles:
3
+ - rubocop-default.yml
4
+
5
+ Rails/Output:
6
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gitlab-rubocop.gemspec
4
+ gemspec
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w[erb haml slim])
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.call("routing/#{m[1]}_routing"),
51
+ rspec.spec.call("controllers/#{m[1]}_controller"),
52
+ rspec.spec.call("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
64
+
65
+ # Turnip features and steps
66
+ watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ end
70
+ end
@@ -0,0 +1,13 @@
1
+ [![pipeline status](https://gitlab.com/gitlab-org/triage/badges/master/pipeline.svg)](https://gitlab.com/gitlab-org/triage/commits/master)
2
+
3
+ ## GitLab Triage Project
4
+
5
+ This project contains scripts used for triaging Issues and Merge Requests in [GitLab-CE Project](https://gitlab.com/gitlab-org/gitlab-ce) projects and enforcing our Issue Triage policies as well of generating data related to triaging issues more effectively.
6
+ The scripts found here may be useful for triaging issues in other projects too.
7
+
8
+ - We define the policies in code in a public project where those interested can raise issues surrounding our policies.
9
+ - We use scheduled pipelines to run the scripts to enforce our policies on a daily basis.
10
+
11
+ ## Suggesting new policies or suggesting changes to policies
12
+
13
+ Please feel free to [open an issue](https://gitlab.com/gitlab-org/triage/issues/new) about creating, editing or deleting a policy. Please select the policy issue template when creating an issue.
@@ -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
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'yaml'
5
+ require_relative '../lib/gitlab/triage/engine'
6
+
7
+ Options = Struct.new(
8
+ :dry_run,
9
+ :policies_file,
10
+ :project_id,
11
+ :token,
12
+ :debug
13
+ )
14
+
15
+ class TriageOptionParser
16
+ class << self
17
+ def parse(argv)
18
+ options = Options.new
19
+
20
+ parser = OptionParser.new do |opts|
21
+ opts.banner = "Usage: #{__FILE__} [options]\n\n"
22
+
23
+ opts.on('-n', '--dry-run', "Don't actually update anything, just print") do |value|
24
+ options.dry_run = value
25
+ end
26
+
27
+ opts.on('-f', '--policies-file [string]', String, 'A valid policies YML file') do |value|
28
+ options.policies_file = value
29
+ end
30
+
31
+ opts.on('-p', '--project-id [string]', String, 'A project ID or path') do |value|
32
+ options.project_id = value
33
+ end
34
+
35
+ opts.on('-t', '--token [string]', String, 'A valid API token') do |value|
36
+ options.token = value
37
+ end
38
+
39
+ opts.on('-d', '--debug', 'Print debug information') do |value|
40
+ options.debug = value
41
+ end
42
+
43
+ opts.on('-h', '--help', 'Print help message') do
44
+ $stdout.puts opts
45
+ exit
46
+ end
47
+ end
48
+
49
+ parser.parse!(argv)
50
+
51
+ options
52
+ end
53
+ end
54
+ end
55
+
56
+ options = TriageOptionParser.parse(ARGV)
57
+
58
+ policies_file = options.policies_file || '.triage-policies.yml'
59
+ policies = HashWithIndifferentAccess.new(YAML.load_file(policies_file))
60
+
61
+ Gitlab::Triage::Engine
62
+ .new(policies: policies, options: options)
63
+ .perform
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'gitlab/triage/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'gitlab-triage'
7
+ spec.version = Gitlab::Triage::VERSION
8
+ spec.authors = ['GitLab']
9
+ spec.email = ['remy@rymai.me']
10
+
11
+ spec.summary = 'GitLab triage automation project.'
12
+ spec.homepage = 'https://gitlab.com/gitlab-org/triage'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency 'activesupport', '~> 5.1'
23
+ spec.add_dependency 'httparty', '~> 0.15'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.15'
26
+ spec.add_development_dependency 'gitlab-styles', '~> 2.1'
27
+ spec.add_development_dependency 'rake', '~> 10.0'
28
+ spec.add_development_dependency 'rspec', '~> 3.0'
29
+ end
@@ -0,0 +1,6 @@
1
+ require 'gitlab/triage/version'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ end
6
+ end
@@ -0,0 +1,32 @@
1
+ module Gitlab
2
+ module Triage
3
+ module CommandBuilders
4
+ class BaseCommandBuilder
5
+ def initialize(items)
6
+ @items = [items].flatten
7
+ @items.delete('')
8
+ end
9
+
10
+ def build_command
11
+ if @items.any?
12
+ [slash_command_string, content_string].compact.join(separator)
13
+ else
14
+ ""
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def separator
21
+ ' '
22
+ end
23
+
24
+ def content_string
25
+ @items.map do |item|
26
+ format_item(item)
27
+ end.join(separator)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'base_command_builder'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module CommandBuilders
6
+ class CcCommandBuilder < BaseCommandBuilder
7
+ private
8
+
9
+ def slash_command_string
10
+ "/cc"
11
+ end
12
+
13
+ def format_item(item)
14
+ "@#{item}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'base_command_builder'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module CommandBuilders
6
+ class CommentCommandBuilder < BaseCommandBuilder
7
+ private
8
+
9
+ def separator
10
+ "\n\n"
11
+ end
12
+
13
+ def slash_command_string
14
+ nil
15
+ end
16
+
17
+ def format_item(item)
18
+ item
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end