danger-gitlab_cancelbot 1.0.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: 5518c8ecd95faf5787056aba173e3217f030bac119c1cffc4d234275c7608d4c
4
+ data.tar.gz: 30c88633c2adf71f00a5189e0dec8105b327777be314a2bcded1e38b924f9d6c
5
+ SHA512:
6
+ metadata.gz: 29f145c75b2093725385011ea736d03200746dd8070bef88acf273bd5be2992b1b80d1e63d129f6b55cf8a083be1a315782a4f1c1488969f367b7e42e374fb13
7
+ data.tar.gz: 35c4f90f999e110c6262fda424e79b50c19c9b6b5a2ef2c0dfdceac1d8ac27770b678d222b8140d22b38b5d1d52b2437166cd9ce22ff316bffc7b8dddc233909
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ pkg
3
+ .idea/
4
+ .yardoc
5
+
6
+ rspec.xml
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,19 @@
1
+ image: "ruby:2.6"
2
+
3
+ cache:
4
+ paths:
5
+ - vendor/bundle/
6
+
7
+ test:
8
+ stage: test
9
+ script:
10
+ - gem install bundler
11
+ - bundle --path vendor/bundle
12
+ - bundle exec rake spec
13
+ - bundle exec rake build
14
+ artifacts:
15
+ paths:
16
+ - rspec.xml
17
+ reports:
18
+ junit: rspec.xml
19
+
data/.rubocop.yml ADDED
@@ -0,0 +1,148 @@
1
+ # Defaults can be found here: https://github.com/bbatsov/rubocop/blob/master/config/default.yml
2
+
3
+ # If you don't like these settings, just delete this file :)
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.4
7
+
8
+ Style/StringLiterals:
9
+ EnforcedStyle: double_quotes
10
+ Enabled: true
11
+
12
+ # kind_of? is a good way to check a type
13
+ Style/ClassCheck:
14
+ EnforcedStyle: kind_of?
15
+
16
+ # specs sometimes have useless assignments, which is fine
17
+ Lint/UselessAssignment:
18
+ Exclude:
19
+ - '**/spec/**/*'
20
+
21
+ # We could potentially enable the 2 below:
22
+ Layout/FirstHashElementIndentation:
23
+ Enabled: false
24
+
25
+ Layout/HashAlignment:
26
+ Enabled: false
27
+
28
+ # HoundCI doesn't like this rule
29
+ Layout/DotPosition:
30
+ Enabled: false
31
+
32
+ # We allow !! as it's an easy way to convert ot boolean
33
+ Style/DoubleNegation:
34
+ Enabled: false
35
+
36
+ # Cop supports --auto-correct.
37
+ Lint/UnusedBlockArgument:
38
+ Enabled: false
39
+
40
+ # We want to allow class Fastlane::Class
41
+ Style/ClassAndModuleChildren:
42
+ Enabled: false
43
+
44
+ Metrics/AbcSize:
45
+ Max: 60
46
+
47
+ # The %w might be confusing for new users
48
+ Style/WordArray:
49
+ MinSize: 19
50
+
51
+ # raise and fail are both okay
52
+ Style/SignalException:
53
+ Enabled: false
54
+
55
+ # Better too much 'return' than one missing
56
+ Style/RedundantReturn:
57
+ Enabled: false
58
+
59
+ # Having if in the same line might not always be good
60
+ Style/IfUnlessModifier:
61
+ Enabled: false
62
+
63
+ # and and or is okay
64
+ Style/AndOr:
65
+ Enabled: false
66
+
67
+ # Configuration parameters: CountComments.
68
+ Metrics/ClassLength:
69
+ Max: 350
70
+
71
+ Metrics/CyclomaticComplexity:
72
+ Max: 17
73
+
74
+ # Configuration parameters: AllowURI, URISchemes.
75
+ Metrics/LineLength:
76
+ Max: 370
77
+
78
+ # Configuration parameters: CountKeywordArgs.
79
+ Metrics/ParameterLists:
80
+ Max: 10
81
+
82
+ Metrics/PerceivedComplexity:
83
+ Max: 18
84
+
85
+ # Sometimes it's easier to read without guards
86
+ Style/GuardClause:
87
+ Enabled: false
88
+
89
+ # something = if something_else
90
+ # that's confusing
91
+ Style/ConditionalAssignment:
92
+ Enabled: false
93
+
94
+ # Better to have too much self than missing a self
95
+ Style/RedundantSelf:
96
+ Enabled: false
97
+
98
+ Metrics/MethodLength:
99
+ Max: 60
100
+
101
+ # We're not there yet
102
+ Style/Documentation:
103
+ Enabled: false
104
+
105
+ # Adds complexity
106
+ Style/IfInsideElse:
107
+ Enabled: false
108
+
109
+ # danger specific
110
+
111
+ Style/BlockComments:
112
+ Enabled: false
113
+
114
+ Layout/MultilineMethodCallIndentation:
115
+ EnforcedStyle: indented
116
+
117
+ # FIXME: 25
118
+ Metrics/BlockLength:
119
+ Max: 345
120
+ Exclude:
121
+ - "**/*_spec.rb"
122
+
123
+ Style/MixinGrouping:
124
+ Enabled: false
125
+
126
+ Style/FileName:
127
+ Enabled: false
128
+
129
+ Layout/HeredocIndentation:
130
+ Enabled: false
131
+
132
+ Style/SpecialGlobalVars:
133
+ Enabled: false
134
+
135
+ PercentLiteralDelimiters:
136
+ PreferredDelimiters:
137
+ "%": ()
138
+ "%i": ()
139
+ "%q": ()
140
+ "%Q": ()
141
+ "%r": "{}"
142
+ "%s": ()
143
+ "%w": ()
144
+ "%W": ()
145
+ "%x": ()
146
+
147
+ Security/YAMLLoad:
148
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in danger-gitlab_reviewbot.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,158 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ danger-gitlab_cancelbot (1.0.0)
5
+ danger-gitlab
6
+ danger-plugin-api (~> 1.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ addressable (2.7.0)
12
+ public_suffix (>= 2.0.2, < 5.0)
13
+ ast (2.4.0)
14
+ claide (1.0.3)
15
+ claide-plugins (0.9.2)
16
+ cork
17
+ nap
18
+ open4 (~> 1.3)
19
+ coderay (1.1.2)
20
+ colored2 (3.1.2)
21
+ cork (0.3.0)
22
+ colored2 (~> 3.1)
23
+ danger (8.0.0)
24
+ claide (~> 1.0)
25
+ claide-plugins (>= 0.9.2)
26
+ colored2 (~> 3.1)
27
+ cork (~> 0.1)
28
+ faraday (>= 0.9.0, < 2.0)
29
+ faraday-http-cache (~> 2.0)
30
+ git (~> 1.7)
31
+ kramdown (~> 2.0)
32
+ kramdown-parser-gfm (~> 1.0)
33
+ no_proxy_fix
34
+ octokit (~> 4.7)
35
+ terminal-table (~> 1)
36
+ danger-gitlab (5.0.1)
37
+ danger (>= 5.0)
38
+ gitlab (~> 4.0)
39
+ danger-plugin-api (1.0.0)
40
+ danger (> 2.0)
41
+ diff-lcs (1.3)
42
+ faraday (1.0.1)
43
+ multipart-post (>= 1.2, < 3)
44
+ faraday-http-cache (2.2.0)
45
+ faraday (>= 0.8)
46
+ ffi (1.12.2)
47
+ formatador (0.2.5)
48
+ git (1.7.0)
49
+ rchardet (~> 1.8)
50
+ gitlab (4.14.1)
51
+ httparty (~> 0.14, >= 0.14.0)
52
+ terminal-table (~> 1.5, >= 1.5.1)
53
+ guard (2.16.2)
54
+ formatador (>= 0.2.4)
55
+ listen (>= 2.7, < 4.0)
56
+ lumberjack (>= 1.0.12, < 2.0)
57
+ nenv (~> 0.1)
58
+ notiffany (~> 0.0)
59
+ pry (>= 0.9.12)
60
+ shellany (~> 0.0)
61
+ thor (>= 0.18.1)
62
+ guard-compat (1.2.1)
63
+ guard-rspec (4.7.3)
64
+ guard (~> 2.1)
65
+ guard-compat (~> 1.1)
66
+ rspec (>= 2.99.0, < 4.0)
67
+ httparty (0.18.0)
68
+ mime-types (~> 3.0)
69
+ multi_xml (>= 0.5.2)
70
+ kramdown (2.2.1)
71
+ rexml
72
+ kramdown-parser-gfm (1.1.0)
73
+ kramdown (~> 2.0)
74
+ listen (3.0.7)
75
+ rb-fsevent (>= 0.9.3)
76
+ rb-inotify (>= 0.9.7)
77
+ lumberjack (1.2.4)
78
+ method_source (1.0.0)
79
+ mime-types (3.3.1)
80
+ mime-types-data (~> 3.2015)
81
+ mime-types-data (3.2020.0512)
82
+ multi_xml (0.6.0)
83
+ multipart-post (2.1.1)
84
+ nap (1.1.0)
85
+ nenv (0.3.0)
86
+ no_proxy_fix (0.1.2)
87
+ notiffany (0.1.3)
88
+ nenv (~> 0.1)
89
+ shellany (~> 0.0)
90
+ octokit (4.18.0)
91
+ faraday (>= 0.9)
92
+ sawyer (~> 0.8.0, >= 0.5.3)
93
+ open4 (1.3.4)
94
+ parallel (1.19.1)
95
+ parser (2.7.1.2)
96
+ ast (~> 2.4.0)
97
+ pry (0.13.1)
98
+ coderay (~> 1.1)
99
+ method_source (~> 1.0)
100
+ public_suffix (4.0.5)
101
+ rainbow (3.0.0)
102
+ rake (13.0.1)
103
+ rb-fsevent (0.10.4)
104
+ rb-inotify (0.10.1)
105
+ ffi (~> 1.0)
106
+ rchardet (1.8.0)
107
+ rexml (3.2.4)
108
+ rspec (3.9.0)
109
+ rspec-core (~> 3.9.0)
110
+ rspec-expectations (~> 3.9.0)
111
+ rspec-mocks (~> 3.9.0)
112
+ rspec-core (3.9.2)
113
+ rspec-support (~> 3.9.3)
114
+ rspec-expectations (3.9.2)
115
+ diff-lcs (>= 1.2.0, < 2.0)
116
+ rspec-support (~> 3.9.0)
117
+ rspec-mocks (3.9.1)
118
+ diff-lcs (>= 1.2.0, < 2.0)
119
+ rspec-support (~> 3.9.0)
120
+ rspec-support (3.9.3)
121
+ rspec_junit_formatter (0.4.1)
122
+ rspec-core (>= 2, < 4, != 2.12.0)
123
+ rubocop (0.83.0)
124
+ parallel (~> 1.10)
125
+ parser (>= 2.7.0.1)
126
+ rainbow (>= 2.2.2, < 4.0)
127
+ rexml
128
+ ruby-progressbar (~> 1.7)
129
+ unicode-display_width (>= 1.4.0, < 2.0)
130
+ ruby-progressbar (1.10.1)
131
+ sawyer (0.8.2)
132
+ addressable (>= 2.3.5)
133
+ faraday (> 0.8, < 2.0)
134
+ shellany (0.0.1)
135
+ terminal-table (1.8.0)
136
+ unicode-display_width (~> 1.1, >= 1.1.1)
137
+ thor (1.0.1)
138
+ unicode-display_width (1.7.0)
139
+ yard (0.9.25)
140
+
141
+ PLATFORMS
142
+ ruby
143
+
144
+ DEPENDENCIES
145
+ bundler (~> 2.1)
146
+ danger-gitlab_cancelbot!
147
+ guard (~> 2.14)
148
+ guard-rspec (~> 4.7)
149
+ listen (= 3.0.7)
150
+ pry
151
+ rake
152
+ rspec
153
+ rspec_junit_formatter
154
+ rubocop
155
+ yard
156
+
157
+ BUNDLED WITH
158
+ 2.1.4
data/Guardfile ADDED
@@ -0,0 +1,19 @@
1
+ # A guardfile for making Danger Plugins
2
+ # For more info see https://github.com/guard/guard#readme
3
+
4
+ # To run, use `bundle exec guard`.
5
+
6
+ guard :rspec, cmd: 'bundle exec rspec' do
7
+ require 'guard/rspec/dsl'
8
+ dsl = Guard::RSpec::Dsl.new(self)
9
+
10
+ # RSpec files
11
+ rspec = dsl.rspec
12
+ watch(rspec.spec_helper) { rspec.spec_dir }
13
+ watch(rspec.spec_support) { rspec.spec_dir }
14
+ watch(rspec.spec_files)
15
+
16
+ # Ruby files
17
+ ruby = dsl.ruby
18
+ dsl.watch_spec_files_for(ruby.lib_files)
19
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2020 Fabio Gallonetto <fabio.gallonetto@imaginecurve.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # danger-gitlab_reviewbot
2
+
3
+ A description of danger-gitlab_cancelbot.
4
+
5
+ ## Installation
6
+
7
+ $ gem install danger-gitlab_cancelbot
8
+
9
+ ## Usage
10
+
11
+ Methods and attributes from this plugin are available in
12
+ your `Dangerfile` under the `gitlab_cancelbot` namespace.
13
+
14
+ ## Development
15
+
16
+ 1. Clone this repo
17
+ 2. Run `bundle install` to setup dependencies.
18
+ 3. Run `bundle exec rake spec` to run the tests.
19
+ 4. Use `bundle exec guard` to automatically have tests run as you make changes.
20
+ 5. Make your changes.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:specs) do |t|
6
+ t.rspec_opts = "--format progress --format RspecJunitFormatter --out rspec.xml"
7
+ end
8
+ task default: :specs
9
+
10
+ task :spec do
11
+ Rake::Task['specs'].invoke
12
+ Rake::Task['rubocop'].invoke
13
+ Rake::Task['spec_docs'].invoke
14
+ end
15
+
16
+ desc 'Run RuboCop on the lib/specs directory'
17
+ RuboCop::RakeTask.new(:rubocop) do |task|
18
+ task.patterns = ['lib/**/*.rb', 'spec/**/*.rb']
19
+ end
20
+
21
+ desc 'Ensure that the plugin passes `danger plugins lint`'
22
+ task :spec_docs do
23
+ sh 'bundle exec danger plugins lint'
24
+ end
@@ -0,0 +1,51 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gitlab_cancelbot/gem_version.rb'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'danger-gitlab_cancelbot'
8
+ spec.version = GitlabReviewbot::VERSION
9
+ spec.authors = ['Fabio Gallonetto']
10
+ spec.email = ['fabio.gallonetto@curve.com']
11
+ spec.description = %q{A Danger plugin that cancels previous runs of the same pipeline on Gitlab }
12
+ spec.summary = %q{ This plugin helps to keep builds under control by cancelling obsolete builds on a merge request branch when a new commit is pushed. }
13
+ spec.homepage = 'https://github.com/curve-technology/danger-gitlab_cancelbot'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_runtime_dependency 'danger-plugin-api', '~> 1.0'
22
+ spec.add_runtime_dependency 'danger-gitlab'
23
+
24
+ # General ruby development
25
+ spec.add_development_dependency 'bundler', '~> 2.1'
26
+ spec.add_development_dependency 'rake'
27
+
28
+ # Testing support
29
+ spec.add_development_dependency 'rspec'
30
+ spec.add_development_dependency "rspec_junit_formatter"
31
+
32
+ # Linting code and docs
33
+ spec.add_development_dependency "rubocop"
34
+ spec.add_development_dependency "yard"
35
+
36
+ # Makes testing easy via `bundle exec guard`
37
+ spec.add_development_dependency 'guard', '~> 2.14'
38
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
39
+
40
+ # If you want to work on older builds of ruby
41
+ spec.add_development_dependency 'listen', '3.0.7'
42
+
43
+ # This gives you the chance to run a REPL inside your tests
44
+ # via:
45
+ #
46
+ # require 'pry'
47
+ # binding.pry
48
+ #
49
+ # This will stop test execution and let you inspect the results
50
+ spec.add_development_dependency 'pry'
51
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gitlab_cancelbot/gem_version"
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gitlab_cancelbot/plugin"
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GitlabReviewbot
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gitlab"
4
+
5
+ module Gitlab
6
+ class Pipeline
7
+ attr_accessor :id
8
+ attr_accessor :status
9
+ attr_accessor :created_at
10
+
11
+ def initialize(id, status, created_at)
12
+ @id = id
13
+ @status = status
14
+ @created_at = created_at
15
+ end
16
+ end
17
+
18
+ def running?
19
+ @status == "running"
20
+ end
21
+ class Client < API
22
+ def running_pipelines_for_mr(project_id, mr_iid)
23
+ pipelines = merge_request_pipelines(project_id, mr_iid)
24
+ pipelines.filter { |p| p.status == "running" }
25
+ .map { |p| Pipeline.new(p.id.to_i, p.status, DateTime.parse(p.created_at)) }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gitlab_cancelbot/gitlab"
4
+
5
+ module Danger
6
+ # Cancels all redunant pipelines for the current merge request
7
+ # @example Cancelling all redunant pipelines for the current merge request
8
+ #
9
+ # # Runs a linter with comma style and tense present disabled
10
+ # gitlab_cancelbot.cancel_redundant_pipelines!
11
+ #
12
+ # @see Fabio Gallonetto/danger-gitlab_cancelbot
13
+ # @tags cancel, gitlab, pipelines
14
+ #
15
+ class DangerGitlabCancelbot < Plugin
16
+ # Add verbosity to the logs
17
+ #
18
+ # @return Bool
19
+ attr_accessor :verbose
20
+
21
+ # Call this method from the Dangerfile to cancel obsolete pipelines running for the same merge request
22
+ #
23
+ # @return The IDs of the cancelled pipelines [Array<Int>]
24
+ #
25
+ def cancel_redundant_pipelines!
26
+ project_id = ENV["CI_PROJECT_ID"]
27
+ mr_iid = ENV["CI_MERGE_REQUEST_IID"]
28
+ if mr_iid.nil?
29
+ raise "Env variable CI_MERGE_REQUEST_IID doesn't point to a valid merge request iid"
30
+ end
31
+
32
+ if project_id.nil?
33
+ raise "Env variable CI_PROJECT_ID doesn't point to a valid project id"
34
+ end
35
+
36
+ project_id = project_id.to_i
37
+ mr_iid = mr_iid.to_i
38
+
39
+ running_pipelines = gitlab.api.running_pipelines_for_mr(project_id, mr_iid).sort_by(&:created_at)
40
+
41
+ puts "Found #{running_pipelines.length} for MR ##{mr_iid}" if @verbose
42
+ if running_pipelines.length > 1
43
+ running_pipelines.pop
44
+ running_pipelines.each { |p| gitlab.api.cancel_pipeline(project_id, p.id) }
45
+ end
46
+
47
+ cancelled_ids = running_pipelines.map(&:id)
48
+ puts "Cancelled the following obsolete pipelines: #{cancelled_ids}" if @verbose
49
+
50
+ return cancelled_ids
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("spec_helper", __dir__)
4
+
5
+ module Danger
6
+ describe Danger::DangerGitlabCancelbot do
7
+ it "should be a plugin" do
8
+ expect(Danger::DangerGitlabCancelbot.new(nil)).to be_a Danger::Plugin
9
+ end
10
+
11
+ #
12
+ # You should test your custom attributes and methods here
13
+ #
14
+ describe "with Dangerfile" do
15
+ before do
16
+ testing_env.each { |k, v| ENV[k] = v.to_s }
17
+
18
+ @dangerfile = testing_dangerfile
19
+ @plugin = @dangerfile.gitlab_cancelbot
20
+ @client_mock = double(Gitlab::Client)
21
+ allow(@dangerfile.gitlab).to receive(:api).and_return(@client_mock)
22
+ end
23
+
24
+ it "Cancel all running except the most recent one" do
25
+ pipelines = [Gitlab::Pipeline.new(1, "running", DateTime.parse("2020-05-12T15:45:30.720Z")),
26
+ Gitlab::Pipeline.new(2, "running", DateTime.now),
27
+ Gitlab::Pipeline.new(3, "running", DateTime.parse("2020-05-11T15:45:30.720Z"))]
28
+ expect(@client_mock).to receive(:running_pipelines_for_mr).with(346, 549).and_return(pipelines)
29
+ expect(@client_mock).to receive(:cancel_pipeline).with(346, 1)
30
+ expect(@client_mock).to receive(:cancel_pipeline).with(346, 3)
31
+
32
+ @plugin.cancel_redundant_pipelines!
33
+ end
34
+
35
+ it "Doesn't cancel anything if there's nothing to cancel" do
36
+ pipelines = [Gitlab::Pipeline.new(2, "running", DateTime.now)]
37
+ expect(@client_mock).to receive(:running_pipelines_for_mr).with(346, 549).and_return(pipelines)
38
+ expect(@client_mock).not_to receive(:cancel_pipeline)
39
+
40
+ @plugin.cancel_redundant_pipelines!
41
+ end
42
+
43
+ ["CI_PROJECT_ID", "CI_MERGE_REQUEST_IID"].each do |var|
44
+ it "Fails when required #{var} variables are not available" do
45
+ ENV[var] = nil
46
+ expect { @plugin.cancel_redundant_pipelines! }.to raise_error(RuntimeError)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("spec_helper", __dir__)
4
+
5
+ module Gitlab
6
+ class Pipeline
7
+ def ==(other)
8
+ id == other.id && created_at == other.created_at && status = other.status
9
+ end
10
+ end
11
+
12
+ describe Client do
13
+ before do
14
+ @client = Gitlab::Client.new({ auth_token: "token-token-token", endpoint: "gitlab.com" })
15
+ end
16
+
17
+ it "Filters non running pipelines" do
18
+ pipelines = [{ id: 1, status: "running", created_at: "2020-05-12T10:45:30.720Z" },
19
+ { id: 2, status: "failed", created_at: "2020-05-12T11:45:30.720Z" },
20
+ { id: 3, status: "finished", created_at: "2020-05-12T12:45:30.720Z" }]
21
+ .map { |p| Gitlab::ObjectifiedHash.new(p) }
22
+ allow_any_instance_of(Gitlab::Client).to receive(:merge_request_pipelines).with(346, 549).and_return(pipelines)
23
+ expect(@client.running_pipelines_for_mr(346, 549)).to eq([Gitlab::Pipeline.new(1, "running", DateTime.parse("2020-05-12T10:45:30.720Z"))])
24
+ end
25
+
26
+ it "Parses pipelines into ::Pipeline" do
27
+ raw_pipelines = [{ id: 1, status: "running", created_at: "2020-05-12T10:45:30.720Z" },
28
+ { id: 2, status: "running", created_at: "2020-05-12T11:45:30.720Z" },
29
+ { id: 3, status: "running", created_at: "2020-05-12T12:45:30.720Z" }]
30
+ gitlab_pipelines = raw_pipelines.map { |p| Gitlab::ObjectifiedHash.new(p) }
31
+ parsed_pipelines = raw_pipelines.map { |p| Gitlab::Pipeline.new(p[:id], p[:status], DateTime.parse(p[:created_at])) }
32
+
33
+ allow_any_instance_of(Gitlab::Client).to receive(:merge_request_pipelines).with(346, 549).and_return(gitlab_pipelines)
34
+ @client = Gitlab::Client.new({ auth_token: "token-token-token", endpoint: "gitlab.com" })
35
+
36
+ expect(@client.running_pipelines_for_mr(346, 549)).to match_array(parsed_pipelines)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ ROOT = Pathname.new(File.expand_path("..", __dir__))
5
+ $:.unshift((ROOT + "lib").to_s)
6
+ $:.unshift((ROOT + "spec").to_s)
7
+
8
+ require "bundler/setup"
9
+ require "pry"
10
+
11
+ require "rspec"
12
+ require "danger"
13
+
14
+ if `git remote -v` == ""
15
+ puts "You cannot run tests without setting a local git remote on this repo"
16
+ puts "It's a weird side-effect of Danger's internals."
17
+ exit(0)
18
+ end
19
+
20
+ # Use coloured output, it's the best.
21
+ RSpec.configure do |config|
22
+ config.filter_gems_from_backtrace "bundler"
23
+ config.color = true
24
+ config.tty = true
25
+ end
26
+
27
+ require "danger_plugin"
28
+
29
+ # These functions are a subset of https://github.com/danger/danger/blob/master/spec/spec_helper.rb
30
+ # If you are expanding these files, see if it's already been done ^.
31
+
32
+ # A silent version of the user interface,
33
+ # it comes with an extra function `.string` which will
34
+ # strip all ANSI colours from the string.
35
+
36
+ # rubocop:disable Lint/NestedMethodDefinition
37
+ def testing_ui
38
+ @output = StringIO.new
39
+ def @output.winsize
40
+ [20, 9999]
41
+ end
42
+
43
+ cork = Cork::Board.new(out: @output)
44
+ def cork.string
45
+ out.string.gsub(/\e\[([;\d]+)?m/, "")
46
+ end
47
+ cork
48
+ end
49
+ # rubocop:enable Lint/NestedMethodDefinition
50
+
51
+ # Example environment (ENV) that would come from
52
+ # running a PR on TravisCI
53
+ def testing_env
54
+ {
55
+ "CI_MERGE_REQUEST_IID" => "549",
56
+ "CI_MERGE_REQUEST_PROJECT_PATH" => "...",
57
+ "CI_MERGE_REQUEST_PROJECT_URL" => "...",
58
+ "DANGER_GITLAB_HOST" => "git.curve.tools", # This needs to be the same as where the repo is stored due to Danger internals :facepalm:
59
+ "CI_API_V4_URL" => "https://git.curve.tools/api/v4",
60
+ "CI_PROJECT_ID" => "346",
61
+ "GITLAB_CI" => true,
62
+ "DANGER_GITLAB_API_TOKEN" => "token-token-token"
63
+ }
64
+ end
65
+
66
+ # A stubbed out Dangerfile for use in tests
67
+ def testing_dangerfile
68
+ env = Danger::EnvironmentManager.new(testing_env)
69
+ Danger::Dangerfile.new(env, testing_ui)
70
+ end
metadata ADDED
@@ -0,0 +1,233 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: danger-gitlab_cancelbot
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Fabio Gallonetto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: danger-plugin-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: danger-gitlab
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec_junit_formatter
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: yard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: guard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.14'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.14'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard-rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '4.7'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '4.7'
153
+ - !ruby/object:Gem::Dependency
154
+ name: listen
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '='
158
+ - !ruby/object:Gem::Version
159
+ version: 3.0.7
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '='
165
+ - !ruby/object:Gem::Version
166
+ version: 3.0.7
167
+ - !ruby/object:Gem::Dependency
168
+ name: pry
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description: 'A Danger plugin that cancels previous runs of the same pipeline on Gitlab '
182
+ email:
183
+ - fabio.gallonetto@curve.com
184
+ executables: []
185
+ extensions: []
186
+ extra_rdoc_files: []
187
+ files:
188
+ - ".gitignore"
189
+ - ".gitlab-ci.yml"
190
+ - ".rubocop.yml"
191
+ - Gemfile
192
+ - Gemfile.lock
193
+ - Guardfile
194
+ - LICENSE.txt
195
+ - README.md
196
+ - Rakefile
197
+ - danger-gitlab_cancelbot.gemspec
198
+ - lib/danger_gitlab_cancelbot.rb
199
+ - lib/danger_plugin.rb
200
+ - lib/gitlab_cancelbot/gem_version.rb
201
+ - lib/gitlab_cancelbot/gitlab.rb
202
+ - lib/gitlab_cancelbot/plugin.rb
203
+ - spec/gitlab_cancelbot_spec.rb
204
+ - spec/gitlab_spec.rb
205
+ - spec/spec_helper.rb
206
+ homepage: https://github.com/curve-technology/danger-gitlab_cancelbot
207
+ licenses:
208
+ - MIT
209
+ metadata: {}
210
+ post_install_message:
211
+ rdoc_options: []
212
+ require_paths:
213
+ - lib
214
+ required_ruby_version: !ruby/object:Gem::Requirement
215
+ requirements:
216
+ - - ">="
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ required_rubygems_version: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ requirements: []
225
+ rubygems_version: 3.0.3
226
+ signing_key:
227
+ specification_version: 4
228
+ summary: This plugin helps to keep builds under control by cancelling obsolete builds
229
+ on a merge request branch when a new commit is pushed.
230
+ test_files:
231
+ - spec/gitlab_cancelbot_spec.rb
232
+ - spec/gitlab_spec.rb
233
+ - spec/spec_helper.rb