Commit 2f7e88df authored by Stan Hu's avatar Stan Hu

Merge branch '1600-remove-jenkinsdeprecatedservice' into 'master'

Remove JenkinsDeprecatedService

See merge request gitlab-org/gitlab!31607
parents d3ac1aee 43f04aa3
---
title: Remove JenkinsDeprecatedService
merge_request: 31607
author: tnwx
type: removed
# frozen_string_literal: true
class RemoveDeprecatedJenkinsServiceRecords < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
execute <<~SQL.strip
DELETE FROM services WHERE type = 'JenkinsDeprecatedService';
SQL
end
def down
# no-op
# The records were removed by `up`
end
end
# frozen_string_literal: true
class EnsureDeprecatedJenkinsServiceRecordsRemoval < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
execute <<~SQL.strip
DELETE FROM services WHERE type = 'JenkinsDeprecatedService';
SQL
end
def down
# no-op
# The records were removed by `up`
end
end
......@@ -13808,6 +13808,8 @@ COPY "schema_migrations" (version) FROM STDIN;
20200511121549
20200511121610
20200511121620
20200511130129
20200511130130
20200511145545
20200511162057
20200511162115
......
......@@ -9246,7 +9246,6 @@ enum ServiceType {
HANGOUTS_CHAT_SERVICE
HIPCHAT_SERVICE
IRKER_SERVICE
JENKINS_DEPRECATED_SERVICE
JENKINS_SERVICE
JIRA_SERVICE
MATTERMOST_SERVICE
......
......@@ -27478,12 +27478,6 @@
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "JENKINS_DEPRECATED_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
......
......@@ -1303,6 +1303,9 @@ GET /projects/:id/services/jenkins
A continuous integration and build server
NOTE: **Note:**
This service was [removed in v13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/1600)
### Create/Edit Jenkins CI (Deprecated) service
Set Jenkins CI (Deprecated) service for a project.
......
......@@ -48,15 +48,18 @@ to avoid getting this error, you need to remove all instances of the
**Omnibus Installation**
```shell
sudo gitlab-rails runner "Service.where(type: ['JenkinsService', 'JenkinsDeprecatedService', 'GithubService']).delete_all"
sudo gitlab-rails runner "Service.where(type: ['JenkinsService', 'GithubService']).delete_all"
```
**Source Installation**
```shell
bundle exec rails runner "Service.where(type: ['JenkinsService', 'JenkinsDeprecatedService', 'GithubService']).delete_all" production
bundle exec rails runner "Service.where(type: ['JenkinsService', 'GithubService']).delete_all" production
```
NOTE: **Note:**
If you are running `GitLab =< v13.0` you need to also remove `JenkinsDeprecatedService` records.
### Variables environment scopes
If you're using this feature and there are variables sharing the same
......
......@@ -6,6 +6,9 @@ was deprecated in favor of the
[GitLab Plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+Plugin).
Please use documentation for the new [Jenkins CI service](jenkins.md).
NOTE: **Note:**
This service was [removed in v13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/1600)
Integration includes:
- Trigger Jenkins build after push to repo
......
......@@ -257,7 +257,6 @@ but commented out to help encourage others to add to it in the future. -->
|projects_hipchat_active|counts||
|projects_irker_active|counts||
|projects_jenkins_active|counts||
|projects_jenkins_deprecated_active|counts||
|projects_jira_active -|counts||
|projects_mattermost_active|counts||
|projects_mattermost_slash_commands_active|counts||
......
......@@ -40,7 +40,6 @@ module EE
has_one :index_status
has_one :jenkins_service
has_one :jenkins_deprecated_service
has_one :github_service
has_one :gitlab_slack_application_service
......@@ -547,7 +546,7 @@ module EE
def disabled_services
strong_memoize(:disabled_services) do
[].tap do |services|
services.push('jenkins', 'jenkins_deprecated') unless feature_available?(:jenkins_integration)
services.push('jenkins') unless feature_available?(:jenkins_integration)
services.push('github') unless feature_available?(:github_project_service_integration)
::Gitlab::CurrentSettings.slack_app_enabled ? services.push('slack_slash_commands') : services.push('gitlab_slack_application')
end
......
......@@ -7,7 +7,6 @@ module EE
EE_SERVICE_NAMES = %w[
github
jenkins
jenkins_deprecated
].freeze
EE_DEV_SERVICE_NAMES = %w[
......
# frozen_string_literal: true
require 'uri'
class JenkinsDeprecatedService < CiService
include ReactiveService
prop_accessor :project_url
boolean_accessor :multiproject_enabled
boolean_accessor :pass_unstable
validates :project_url, presence: true, if: :activated?
after_save :compose_service_hook, if: :activated?
def compose_service_hook
hook = service_hook || build_service_hook
jenkins_url = project_url.sub(%r{job/.*}, '')
hook.url = jenkins_url + "gitlab/build_now"
hook.save
end
def execute(data, hook_name = 'service_hook')
return if project.disabled_services.include?(to_param)
service_hook.execute(data, hook_name)
end
def title
'Jenkins CI (Deprecated)'
end
def description
'An extendable open source continuous integration server'
end
def help
'You must have installed GitLab Hook plugin into Jenkins. This service ' \
'is deprecated. Use "Jenkins CI" service instead.'
end
def self.to_param
'jenkins_deprecated'
end
def fields
[
{ type: 'text', name: 'project_url', placeholder: 'Jenkins project URL like http://jenkins.example.com/job/my-project/' },
{ type: 'checkbox', name: 'multiproject_enabled', title: "Multi-project setup enabled?",
help: "Multi-project mode is configured in Jenkins GitLab Hook plugin." },
{ type: 'checkbox', name: 'pass_unstable', title: 'Should unstable builds be treated as passing?',
help: 'Unstable builds will be treated as passing.' }
]
end
def multiproject_enabled?
Gitlab::Utils.to_boolean(self.multiproject_enabled)
end
def pass_unstable?
Gitlab::Utils.to_boolean(self.pass_unstable)
end
def build_page(sha, ref = nil)
if multiproject_enabled? && ref.present?
"#{base_project_url}/#{project.name}_#{ref.tr('/', '_')}/scm/bySHA1/#{sha}"
else
"#{project_url}/scm/bySHA1/#{sha}"
end
end
def commit_status(sha, ref = nil)
with_reactive_cache(sha, ref) {|cached| cached[:commit_status] }
end
# When multi-project is enabled we need to have a different URL. Rather than
# relying on the user to provide the proper URL depending on multi-project
# we just parse the URL and make sure it's how we want it.
def base_project_url
url = URI.parse(project_url)
URI.join(url, '/job').to_s # It's intended to discard paths in project_url
end
def calculate_reactive_cache(sha, ref)
{ commit_status: read_commit_status(sha, ref) }
rescue Gitlab::HTTP::BlockedUrlError => ex
Gitlab::ErrorTracking.track_exception(ex)
end
private
def read_commit_status(sha, ref)
parsed_url = URI.parse(build_page(sha, ref))
if parsed_url.userinfo.blank?
response = Gitlab::HTTP.get(build_page(sha, ref), verify: false)
else
get_url = build_page(sha, ref).gsub("#{parsed_url.userinfo}@", "")
auth = {
username: CGI.unescape(parsed_url.user),
password: CGI.unescape(parsed_url.password)
}
response = Gitlab::HTTP.get(get_url, verify: false, basic_auth: auth)
end
if response.code == 200
# img.build-caption-status-icon for old jenkins version
begin
src = Nokogiri.parse(response).css('img.build-caption-status-icon,.build-caption>img').first.attributes['src'].value
rescue NoMethodError => ex
Gitlab::ErrorTracking.track_exception(ex, response: response)
return :error
end
if src =~ /blue\.png$/ || (src =~ /yellow\.png/ && pass_unstable?)
'success'
elsif src =~ /(red|aborted|yellow)\.png$/
'failed'
elsif src =~ /anime\.gif$/
'running'
else
'pending'
end
else
:error
end
end
end
......@@ -57,26 +57,6 @@ module EE
type: String,
desc: 'The password of the user'
}
],
'jenkins-deprecated' => [
{
required: true,
name: :project_url,
type: String,
desc: 'Jenkins project URL like http://jenkins.example.com/job/my-project/'
},
{
required: false,
name: :pass_unstable,
type: ::API::Services::Boolean,
desc: 'Multi-project setup enabled?'
},
{
required: false,
name: :multiproject_enabled,
type: ::API::Services::Boolean,
desc: 'Should unstable builds be treated as passing?'
}
]
)
end
......@@ -86,7 +66,6 @@ module EE
[
::GithubService,
::JenkinsService,
::JenkinsDeprecatedService,
*super
]
end
......
......@@ -29,7 +29,7 @@ describe Projects::Settings::IntegrationsController do
context 'Sets correct services list' do
let(:active_services) { assigns(:services).map(&:type) }
let(:disabled_services) { %w(JenkinsService JenkinsDeprecatedService) }
let(:disabled_services) { %w(JenkinsService) }
it 'enables SlackSlashCommandsService and disables GitlabSlackApplication' do
get :show, params: { namespace_id: project.namespace, project_id: project }
......
# frozen_string_literal: true
require 'spec_helper'
describe JenkinsDeprecatedService, use_clean_rails_memory_store_caching: true do
include ReactiveCachingHelpers
describe "Associations" do
it { is_expected.to belong_to :project }
it { is_expected.to have_one :service_hook }
end
describe 'commits methods' do
def status_body_for_icon(state)
<<ICON_STATUS_HTML
<h1 class="build-caption page-headline">
<img src="/static/8b0a9b52/images/48x48/#{state}" alt="Success" tooltip="Success" style="width: 48px; height: 48px; " class="icon-#{state} icon-xlg" />
Build #188
(Oct 15, 2014 9:45:21 PM)
</h1>
ICON_STATUS_HTML
end
describe '#calculate_reactive_cache' do
let(:pass_unstable) { '0' }
before do
@service = JenkinsDeprecatedService.new
allow(@service).to receive_messages(
service_hook: true,
project_url: 'http://jenkins.gitlab.org/job/2',
multiproject_enabled: '0',
pass_unstable: pass_unstable,
token: 'verySecret'
)
end
statuses = { 'blue.png' => 'success', 'yellow.png' => 'failed', 'red.png' => 'failed', 'aborted.png' => 'failed', 'blue-anime.gif' => 'running', 'grey.png' => 'pending' }
statuses.each do |icon, state|
it "has a commit_status of #{state} when the icon #{icon} exists." do
stub_request(:get, "http://jenkins.gitlab.org/job/2/scm/bySHA1/2ab7834c").to_return(status: 200, body: status_body_for_icon(icon), headers: {})
expect(@service.calculate_reactive_cache('2ab7834c', 'master')).to eq(commit_status: state)
end
end
context 'with passing unstable' do
let(:pass_unstable) { '1' }
it 'has a commit_status of success when the icon yellow exists' do
stub_request(:get, "http://jenkins.gitlab.org/job/2/scm/bySHA1/2ab7834c").to_return(status: 200, body: status_body_for_icon('yellow.png'), headers: {})
expect(@service.calculate_reactive_cache('2ab7834c', 'master')).to eq(commit_status: 'success')
end
end
context 'with bad response' do
it 'has a commit_status of error' do
stub_request(:get, "http://jenkins.gitlab.org/job/2/scm/bySHA1/2ab7834c").to_return(status: 200, body: '<h1>404</h1>', headers: {})
expect(@service.calculate_reactive_cache('2ab7834c', 'master')).to eq(commit_status: :error)
end
end
describe 'respects outbound network setting' do
let(:url) { 'http://127.0.0.1:8080/job/test' }
before do
stub_application_setting(allow_local_requests_from_web_hooks_and_services: setting)
allow(@service).to receive(:project_url).and_return(url)
end
context 'when local requests are allowed' do
let(:setting) { true }
it "makes an outbound request" do
stub_request(:get, 'http://127.0.0.1:8080/job/test/scm/bySHA1/2ab7834c').to_return(status: 200, body: status_body_for_icon('blue.png'), headers: {})
expect(@service.calculate_reactive_cache('2ab7834c', 'master')).to eq(commit_status: 'success')
end
end
context 'when local requests are not allowed' do
let(:setting) { false }
it 'raises an exception' do
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(an_instance_of(Gitlab::HTTP::BlockedUrlError)).and_call_original
expect { @service.calculate_reactive_cache('2ab7834c', 'master') }.not_to raise_error
end
end
end
end
describe '#commit_status' do
subject(:service) { described_class.new(project_id: 666) }
it 'returns the contents of the reactive cache' do
stub_reactive_cache(service, { commit_status: 'foo' }, 'sha', 'ref')
expect(service.commit_status('sha', 'ref')).to eq('foo')
end
end
describe 'multiproject enabled' do
let!(:project) { create(:project) }
before do
@service = JenkinsDeprecatedService.new
allow(@service).to receive_messages(
service_hook: true,
project_url: 'http://jenkins.gitlab.org/job/2',
multiproject_enabled: '1',
token: 'verySecret',
project: project
)
end
describe '#build_page' do
it { expect(@service.build_page("2ab7834c", 'feature/my-branch')).to eq("http://jenkins.gitlab.org/job/#{project.name}_feature_my-branch/scm/bySHA1/2ab7834c") }
end
end
describe 'multiproject disabled' do
before do
@service = JenkinsDeprecatedService.new
allow(@service).to receive_messages(
service_hook: true,
project_url: 'http://jenkins.gitlab.org/job/2',
multiproject_enabled: '0',
token: 'verySecret'
)
end
describe '#build_page' do
it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://jenkins.gitlab.org/job/2/scm/bySHA1/2ab7834c") }
end
describe '#build_page with branch' do
it { expect(@service.build_page("2ab7834c", 'test_branch')).to eq("http://jenkins.gitlab.org/job/2/scm/bySHA1/2ab7834c") }
end
end
end
shared_examples 'a disabled jenkins deprecated service' do
it 'does not invoke the service hook' do
expect_any_instance_of(ServiceHook).not_to receive(:execute)
jenkins_service.execute(push_sample_data)
end
end
shared_examples 'an enabled jenkins deprecated service' do
it 'invokes the service hook' do
expect_any_instance_of(ServiceHook).to receive(:execute)
jenkins_service.execute(push_sample_data)
end
end
describe '#execute' do
let(:user) { create(:user, username: 'username') }
let(:namespace) { create(:group, :private) }
let(:project) { create(:project, :private, name: 'project', namespace: namespace) }
let(:push_sample_data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
let(:jenkins_service) { described_class.create(active: true, project: project) }
let!(:service_hook) { create(:service_hook, service: jenkins_service) }
context 'without a license key' do
before do
License.destroy_all # rubocop: disable DestroyAll
end
it_behaves_like 'a disabled jenkins deprecated service'
end
context 'with a license key' do
context 'when namespace plan check is not enabled' do
before do
stub_application_setting_on_object(project, should_check_namespace_plan: false)
end
it_behaves_like 'an enabled jenkins deprecated service'
end
context 'when namespace plan check is enabled' do
before do
stub_application_setting_on_object(project, should_check_namespace_plan: true)
end
context 'when namespace does not have a plan' do
let(:namespace) { create(:group, :private) }
it_behaves_like 'a disabled jenkins deprecated service'
end
context 'when namespace has a plan' do
let(:namespace) { create(:group, :private) }
let!(:gitlab_subscription) { create(:gitlab_subscription, :bronze, namespace: namespace) }
it_behaves_like 'an enabled jenkins deprecated service'
end
end
end
end
end
......@@ -1307,7 +1307,7 @@ describe Project do
subject { project.disabled_services }
where(:license_feature, :disabled_services) do
:jenkins_integration | %w(jenkins jenkins_deprecated)
:jenkins_integration | %w(jenkins)
:github_project_service_integration | %w(github)
end
......
......@@ -8,7 +8,6 @@ describe Service do
%w(
github
jenkins
jenkins_deprecated
)
end
......
......@@ -7394,26 +7394,6 @@
"category": "common",
"default": false,
"wiki_page_events": true
},
{
"id": 101,
"title": "JenkinsDeprecated",
"project_id": 5,
"created_at": "2016-06-14T15:01:51.031Z",
"updated_at": "2016-06-14T15:01:51.031Z",
"active": false,
"properties": {},
"template": false,
"push_events": true,
"issues_events": true,
"merge_requests_events": true,
"tag_push_events": true,
"note_events": true,
"job_events": true,
"category": "common",
"default": false,
"wiki_page_events": true,
"type": "JenkinsDeprecatedService"
}
],
"hooks": [],
......
......@@ -17,4 +17,3 @@
{"id":83,"title":"Atlassian Bamboo CI","project_id":5,"created_at":"2016-06-14T15:01:51.067Z","updated_at":"2016-06-14T15:01:51.067Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"BambooService","category":"ci","default":false,"wiki_page_events":true}
{"id":82,"title":"Assembla","project_id":5,"created_at":"2016-06-14T15:01:51.047Z","updated_at":"2016-06-14T15:01:51.047Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"AssemblaService","category":"common","default":false,"wiki_page_events":true}
{"id":81,"title":"Asana","project_id":5,"created_at":"2016-06-14T15:01:51.031Z","updated_at":"2016-06-14T15:01:51.031Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"AsanaService","category":"common","default":false,"wiki_page_events":true}
{"id":101,"title":"JenkinsDeprecated","project_id":5,"created_at":"2016-06-14T15:01:51.031Z","updated_at":"2016-06-14T15:01:51.031Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"category":"common","default":false,"wiki_page_events":true,"type":"JenkinsDeprecatedService"}
......@@ -429,7 +429,6 @@ project:
- mirror_user
- push_rule
- jenkins_service
- jenkins_deprecated_service
- index_status
- feature_usage
- approval_rules
......
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'migrate', '20200511130129_remove_deprecated_jenkins_service_records.rb')
require Rails.root.join('db', 'post_migrate', '20200511130130_ensure_deprecated_jenkins_service_records_removal.rb')
shared_examples 'remove DeprecatedJenkinsService records' do
let(:services) { table(:services) }
before do
services.create!(type: 'JenkinsDeprecatedService')
services.create!(type: 'JenkinsService')
end
it 'deletes services when template and attached to a project' do
expect { migrate! }
.to change { services.where(type: 'JenkinsDeprecatedService').count }.from(1).to(0)
.and not_change { services.where(type: 'JenkinsService').count }
end
end
describe RemoveDeprecatedJenkinsServiceRecords, :migration do
it_behaves_like 'remove DeprecatedJenkinsService records'
end
describe EnsureDeprecatedJenkinsServiceRecordsRemoval, :migration do
it_behaves_like 'remove DeprecatedJenkinsService records'
end
......@@ -31,8 +31,7 @@ Service.available_services_names.each do |service|
let(:licensed_features) do
{
'github' => :github_project_service_integration,
'jenkins' => :jenkins_integration,
'jenkins_deprecated' => :jenkins_integration
'jenkins' => :jenkins_integration
}
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment