gitlab-triage 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +19 -0
- data/.gitignore +15 -0
- data/.gitlab-ci.yml +101 -0
- data/.gitlab/issue_templates/Policy.md +32 -0
- data/.rubocop.yml +6 -0
- data/Gemfile +4 -0
- data/Guardfile +70 -0
- data/README.md +13 -0
- data/Rakefile +6 -0
- data/bin/gitlab-triage +63 -0
- data/gitlab-triage.gemspec +29 -0
- data/lib/gitlab/triage.rb +6 -0
- data/lib/gitlab/triage/command_builders/base_command_builder.rb +32 -0
- data/lib/gitlab/triage/command_builders/cc_command_builder.rb +19 -0
- data/lib/gitlab/triage/command_builders/comment_command_builder.rb +23 -0
- data/lib/gitlab/triage/command_builders/label_command_builder.rb +19 -0
- data/lib/gitlab/triage/command_builders/status_command_builder.rb +23 -0
- data/lib/gitlab/triage/engine.rb +146 -0
- data/lib/gitlab/triage/filter_builders/base_filter_builder.rb +18 -0
- data/lib/gitlab/triage/filter_builders/multi_filter_builder.rb +20 -0
- data/lib/gitlab/triage/filter_builders/single_filter_builder.rb +13 -0
- data/lib/gitlab/triage/limiters/base_conditions_limiter.rb +65 -0
- data/lib/gitlab/triage/limiters/date_conditions_limiter.rb +63 -0
- data/lib/gitlab/triage/limiters/name_conditions_limiter.rb +30 -0
- data/lib/gitlab/triage/limiters/votes_conditions_limiter.rb +54 -0
- data/lib/gitlab/triage/network.rb +37 -0
- data/lib/gitlab/triage/network_adapters/httparty_adapter.rb +36 -0
- data/lib/gitlab/triage/network_adapters/test_adapter.rb +31 -0
- data/lib/gitlab/triage/retryable.rb +31 -0
- data/lib/gitlab/triage/ui.rb +15 -0
- data/lib/gitlab/triage/version.rb +5 -0
- data/policies.yml +232 -0
- metadata +160 -0
checksums.yaml
ADDED
@@ -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
|
data/.codeclimate.yml
ADDED
@@ -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/
|
data/.gitignore
ADDED
data/.gitlab-ci.yml
ADDED
@@ -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"
|
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
data/bin/gitlab-triage
ADDED
@@ -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,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
|