Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2019-10-24 15:06:02 +00:00
parent 33813f993b
commit 8db8e2a342
14 changed files with 150 additions and 22 deletions

View file

@ -21,6 +21,8 @@ class MergeRequestDiffEntity < Grape::Entity
expose :latest?, as: :latest expose :latest?, as: :latest
expose :short_commit_sha do |merge_request_diff| expose :short_commit_sha do |merge_request_diff|
next unless merge_request_diff.head_commit_sha
short_sha(merge_request_diff.head_commit_sha) short_sha(merge_request_diff.head_commit_sha)
end end

View file

@ -8,8 +8,9 @@
.input-group-text .input-group-text
= s_("CompareBranches|Source") = s_("CompareBranches|Source")
= hidden_field_tag :to, params[:to] = hidden_field_tag :to, params[:to]
= button_tag type: 'button', title: params[:to], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip monospace", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to], field_name: :to } do = button_tag type: 'button', title: params[:to], class: "btn form-control compare-dropdown-toggle js-compare-dropdown has-tooltip", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to], field_name: :to } do
.dropdown-toggle-text.str-truncated= params[:to] || _("Select branch/tag") .dropdown-toggle-text.str-truncated.monospace.float-left= params[:to] || _("Select branch/tag")
= sprite_icon('arrow-down', size: 16, css_class: 'float-right')
= render 'shared/ref_dropdown' = render 'shared/ref_dropdown'
.compare-ellipsis.inline ... .compare-ellipsis.inline ...
.form-group.dropdown.compare-form-group.from.js-compare-from-dropdown .form-group.dropdown.compare-form-group.from.js-compare-from-dropdown
@ -18,8 +19,9 @@
.input-group-text .input-group-text
= s_("CompareBranches|Target") = s_("CompareBranches|Target")
= hidden_field_tag :from, params[:from] = hidden_field_tag :from, params[:from]
= button_tag type: 'button', title: params[:from], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip monospace", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from], field_name: :from } do = button_tag type: 'button', title: params[:from], class: "btn form-control compare-dropdown-toggle js-compare-dropdown has-tooltip", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from], field_name: :from } do
.dropdown-toggle-text.str-truncated= params[:from] || _("Select branch/tag") .dropdown-toggle-text.str-truncated.monospace.float-left= params[:from] || _("Select branch/tag")
= sprite_icon('arrow-down', size: 16, css_class: 'float-right')
= render 'shared/ref_dropdown' = render 'shared/ref_dropdown'
&nbsp; &nbsp;
= button_tag s_("CompareBranches|Compare"), class: "btn btn-success commits-compare-btn" = button_tag s_("CompareBranches|Compare"), class: "btn btn-success commits-compare-btn"

View file

@ -0,0 +1,5 @@
---
title: Adding dropdown arrow icon and updated text alignment
merge_request:
author:
type: other

View file

@ -0,0 +1,5 @@
---
title: Bump Auto-Deploy image to v0.3.0
merge_request: 18809
author:
type: added

View file

@ -0,0 +1,5 @@
---
title: Serialize short sha as nil if head commit is blank
merge_request: 19014
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Support Enable/Disable operations in Feature Flag API
merge_request: 18368
author:
type: added

View file

@ -924,6 +924,7 @@ applications.
| `AUTO_DEVOPS_CHART_REPOSITORY_NAME` | From GitLab 11.11, used to set the name of the Helm repository. Defaults to `gitlab`. | | `AUTO_DEVOPS_CHART_REPOSITORY_NAME` | From GitLab 11.11, used to set the name of the Helm repository. Defaults to `gitlab`. |
| `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME` | From GitLab 11.11, used to set a username to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD`. | | `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME` | From GitLab 11.11, used to set a username to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD`. |
| `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD` | From GitLab 11.11, used to set a password to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME`. | | `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD` | From GitLab 11.11, used to set a password to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME`. |
| `AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE` | From GitLab 12.5, used in combination with [Modsecurity feature flag](../../user/clusters/applications.md#web-application-firewall-modsecurity) to toggle [Modsecurity's `SecRuleEngine`](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecRuleEngine) behavior. Defaults to `DetectionOnly`. |
| `BUILDPACK_URL` | Buildpack's full URL. Can point to either Git repositories or a tarball URL. For Git repositories, it is possible to point to a specific `ref`. For example `https://github.com/heroku/heroku-buildpack-ruby.git#v142`. | | `BUILDPACK_URL` | Buildpack's full URL. Can point to either Git repositories or a tarball URL. For Git repositories, it is possible to point to a specific `ref`. For example `https://github.com/heroku/heroku-buildpack-ruby.git#v142`. |
| `CANARY_ENABLED` | From GitLab 11.0, used to define a [deploy policy for canary environments](#deploy-policy-for-canary-environments-premium). | | `CANARY_ENABLED` | From GitLab 11.0, used to define a [deploy policy for canary environments](#deploy-policy-for-canary-environments-premium). |
| `CANARY_PRODUCTION_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md) in the production environment. Takes precedence over `CANARY_REPLICAS`. Defaults to 1. | | `CANARY_PRODUCTION_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md) in the production environment. Takes precedence over `CANARY_REPLICAS`. Defaults to 1. |

View file

@ -1,5 +1,5 @@
.auto-deploy: .auto-deploy:
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.1.0" image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.3.0"
review: review:
extends: .auto-deploy extends: .auto-deploy

View file

@ -13,6 +13,15 @@ module Quality
end end
def cleanup(release_name:) def cleanup(release_name:)
selector = case release_name
when String
%(-l release="#{release_name}")
when Array
%(-l 'release in (#{release_name.join(', ')})')
else
raise ArgumentError, 'release_name must be a string or an array'
end
command = [ command = [
%(--namespace "#{namespace}"), %(--namespace "#{namespace}"),
'delete', 'delete',
@ -20,7 +29,7 @@ module Quality
'--now', '--now',
'--ignore-not-found', '--ignore-not-found',
'--include-uninitialized', '--include-uninitialized',
%(-l release="#{release_name}") selector
] ]
run_command(command) run_command(command)

View file

@ -60,6 +60,8 @@ class AutomatedCleanup
stop_threshold = threshold_time(days: days_for_stop) stop_threshold = threshold_time(days: days_for_stop)
deployments_look_back_threshold = threshold_time(days: days_for_delete * 5) deployments_look_back_threshold = threshold_time(days: days_for_delete * 5)
releases_to_delete = []
gitlab.deployments(project_path, per_page: DEPLOYMENTS_PER_PAGE, sort: 'desc').auto_paginate do |deployment| gitlab.deployments(project_path, per_page: DEPLOYMENTS_PER_PAGE, sort: 'desc').auto_paginate do |deployment|
break if Time.parse(deployment.created_at) < deployments_look_back_threshold break if Time.parse(deployment.created_at) < deployments_look_back_threshold
@ -75,7 +77,7 @@ class AutomatedCleanup
if deployed_at < delete_threshold if deployed_at < delete_threshold
delete_environment(environment, deployment) delete_environment(environment, deployment)
release = Quality::HelmClient::Release.new(environment.slug, 1, deployed_at.to_s, nil, nil, review_apps_namespace) release = Quality::HelmClient::Release.new(environment.slug, 1, deployed_at.to_s, nil, nil, review_apps_namespace)
delete_helm_release(release) releases_to_delete << release
elsif deployed_at < stop_threshold elsif deployed_at < stop_threshold
stop_environment(environment, deployment) stop_environment(environment, deployment)
else else
@ -84,6 +86,8 @@ class AutomatedCleanup
checked_environments << environment.slug checked_environments << environment.slug
end end
delete_helm_releases(releases_to_delete)
end end
def perform_helm_releases_cleanup!(days:) def perform_helm_releases_cleanup!(days:)
@ -91,16 +95,20 @@ class AutomatedCleanup
threshold_day = threshold_time(days: days) threshold_day = threshold_time(days: days)
releases_to_delete = []
helm_releases.each do |release| helm_releases.each do |release|
# Prevents deleting `dns-gitlab-review-app` releases or other unrelated releases # Prevents deleting `dns-gitlab-review-app` releases or other unrelated releases
next unless release.name.start_with?('review-') next unless release.name.start_with?('review-')
if release.status == 'FAILED' || release.last_update < threshold_day if release.status == 'FAILED' || release.last_update < threshold_day
delete_helm_release(release) releases_to_delete << release
else else
print_release_state(subject: 'Release', release_name: release.name, release_date: release.last_update, action: 'leaving') print_release_state(subject: 'Release', release_name: release.name, release_date: release.last_update, action: 'leaving')
end end
end end
delete_helm_releases(releases_to_delete)
end end
private private
@ -121,10 +129,17 @@ class AutomatedCleanup
helm.releases(args: args) helm.releases(args: args)
end end
def delete_helm_release(release) def delete_helm_releases(releases)
print_release_state(subject: 'Release', release_name: release.name, release_status: release.status, release_date: release.last_update, action: 'cleaning') return if releases.empty?
helm.delete(release_name: release.name)
kubernetes.cleanup(release_name: release.name) releases.each do |release|
print_release_state(subject: 'Release', release_name: release.name, release_status: release.status, release_date: release.last_update, action: 'cleaning')
end
releases_names = releases.map(&:name)
helm.delete(release_name: releases_names)
kubernetes.cleanup(release_name: releases_names)
rescue Quality::HelmClient::CommandFailedError => ex rescue Quality::HelmClient::CommandFailedError => ex
raise ex unless ignore_exception?(ex.message, IGNORED_HELM_ERRORS) raise ex unless ignore_exception?(ex.message, IGNORED_HELM_ERRORS)

View file

@ -17,7 +17,7 @@ module Trigger
end end
class Base class Base
def invoke!(post_comment: false) def invoke!(post_comment: false, downstream_job_name: nil)
pipeline = Gitlab.run_trigger( pipeline = Gitlab.run_trigger(
downstream_project_path, downstream_project_path,
trigger_token, trigger_token,
@ -28,7 +28,18 @@ module Trigger
puts "Waiting for downstream pipeline status" puts "Waiting for downstream pipeline status"
Trigger::CommitComment.post!(pipeline, access_token) if post_comment Trigger::CommitComment.post!(pipeline, access_token) if post_comment
Trigger::Pipeline.new(downstream_project_path, pipeline.id, access_token) downstream_job =
if downstream_job_name
Gitlab.pipeline_jobs(downstream_project_path, pipeline.id).auto_paginate.find do |potential_job|
potential_job.name == downstream_job_name
end
end
if downstream_job
Trigger::Job.new(downstream_project_path, downstream_job.id, access_token)
else
Trigger::Pipeline.new(downstream_project_path, pipeline.id, access_token)
end
end end
private private
@ -187,6 +198,14 @@ module Trigger
attr_reader :project, :id, :api_token attr_reader :project, :id, :api_token
def self.unscoped_class_name
name.split('::').last
end
def self.gitlab_api_method_name
unscoped_class_name.downcase
end
def initialize(project, id, api_token) def initialize(project, id, api_token)
@project = project @project = project
@id = id @id = id
@ -199,17 +218,17 @@ module Trigger
def wait! def wait!
loop do loop do
raise "Pipeline timed out after waiting for #{duration} minutes!" if timeout? raise "#{self.class.unscoped_class_name} timed out after waiting for #{duration} minutes!" if timeout?
case status case status
when :created, :pending, :running when :created, :pending, :running
print "." print "."
sleep INTERVAL sleep INTERVAL
when :success when :success
puts "Pipeline succeeded in #{duration} minutes!" puts "#{self.class.unscoped_class_name} succeeded in #{duration} minutes!"
break break
else else
raise "Pipeline did not succeed!" raise "#{self.class.unscoped_class_name} did not succeed!"
end end
STDOUT.flush STDOUT.flush
@ -225,7 +244,7 @@ module Trigger
end end
def status def status
Gitlab.pipeline(project, id).status.to_sym Gitlab.public_send(self.class.gitlab_api_method_name, project, id).status.to_sym # rubocop:disable GitlabSecurity/PublicSend
rescue Gitlab::Error::Error => error rescue Gitlab::Error::Error => error
puts "Ignoring the following error: #{error}" puts "Ignoring the following error: #{error}"
# Ignore GitLab API hiccups. If GitLab is really down, we'll hit the job # Ignore GitLab API hiccups. If GitLab is really down, we'll hit the job
@ -233,11 +252,13 @@ module Trigger
:running :running
end end
end end
Job = Class.new(Pipeline)
end end
case ARGV[0] case ARGV[0]
when 'omnibus' when 'omnibus'
Trigger::Omnibus.new.invoke!(post_comment: true).wait! Trigger::Omnibus.new.invoke!(post_comment: true, downstream_job_name: 'Trigger:qa-test').wait!
when 'cng' when 'cng'
Trigger::CNG.new.invoke!.wait! Trigger::CNG.new.invoke!.wait!
else else

View file

@ -107,5 +107,25 @@ RSpec.describe Quality::HelmClient do
expect(subject.delete(release_name: release_name)).to eq('') expect(subject.delete(release_name: release_name)).to eq('')
end end
context 'with multiple release names' do
let(:release_name) { ['my-release', 'my-release-2'] }
it 'raises an error if the Helm command fails' do
expect(Gitlab::Popen).to receive(:popen_with_detail)
.with([%(helm delete --tiller-namespace "#{namespace}" --purge #{release_name.join(' ')})])
.and_return(Gitlab::Popen::Result.new([], '', '', double(success?: false)))
expect { subject.delete(release_name: release_name) }.to raise_error(described_class::CommandFailedError)
end
it 'calls helm delete with multiple release names' do
expect(Gitlab::Popen).to receive(:popen_with_detail)
.with([%(helm delete --tiller-namespace "#{namespace}" --purge #{release_name.join(' ')})])
.and_return(Gitlab::Popen::Result.new([], '', '', double(success?: true)))
expect(subject.delete(release_name: release_name)).to eq('')
end
end
end end
end end

View file

@ -29,5 +29,30 @@ RSpec.describe Quality::KubernetesClient do
# We're not verifying the output here, just silencing it # We're not verifying the output here, just silencing it
expect { subject.cleanup(release_name: release_name) }.to output.to_stdout expect { subject.cleanup(release_name: release_name) }.to output.to_stdout
end end
context 'with multiple releases' do
let(:release_name) { ['my-release', 'my-release-2'] }
it 'raises an error if the Kubernetes command fails' do
expect(Gitlab::Popen).to receive(:popen_with_detail)
.with([%(kubectl --namespace "#{namespace}" delete ) \
'ingress,svc,pdb,hpa,deploy,statefulset,job,pod,secret,configmap,pvc,secret,clusterrole,clusterrolebinding,role,rolebinding,sa ' \
"--now --ignore-not-found --include-uninitialized -l 'release in (#{release_name.join(', ')})'"])
.and_return(Gitlab::Popen::Result.new([], '', '', double(success?: false)))
expect { subject.cleanup(release_name: release_name) }.to raise_error(described_class::CommandFailedError)
end
it 'calls kubectl with the correct arguments' do
expect(Gitlab::Popen).to receive(:popen_with_detail)
.with([%(kubectl --namespace "#{namespace}" delete ) \
'ingress,svc,pdb,hpa,deploy,statefulset,job,pod,secret,configmap,pvc,secret,clusterrole,clusterrolebinding,role,rolebinding,sa ' \
"--now --ignore-not-found --include-uninitialized -l 'release in (#{release_name.join(', ')})'"])
.and_return(Gitlab::Popen::Result.new([], '', '', double(success?: true)))
# We're not verifying the output here, just silencing it
expect { subject.cleanup(release_name: release_name) }.to output.to_stdout
end
end
end end
end end

View file

@ -7,14 +7,15 @@ describe MergeRequestDiffEntity do
let(:request) { EntityRequest.new(project: project) } let(:request) { EntityRequest.new(project: project) }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
let(:merge_request_diffs) { merge_request.merge_request_diffs } let(:merge_request_diffs) { merge_request.merge_request_diffs }
let(:merge_request_diff) { merge_request_diffs.first }
let(:entity) do let(:entity) do
described_class.new(merge_request_diffs.first, request: request, merge_request: merge_request, merge_request_diffs: merge_request_diffs) described_class.new(merge_request_diff, request: request, merge_request: merge_request, merge_request_diffs: merge_request_diffs)
end end
context 'as json' do subject { entity.as_json }
subject { entity.as_json }
context 'as json' do
it 'exposes needed attributes' do it 'exposes needed attributes' do
expect(subject).to include( expect(subject).to include(
:version_index, :created_at, :commits_count, :version_index, :created_at, :commits_count,
@ -23,4 +24,16 @@ describe MergeRequestDiffEntity do
) )
end end
end end
describe '#short_commit_sha' do
it 'returns short sha' do
expect(subject[:short_commit_sha]).to eq('b83d6e39')
end
it 'returns nil if head_commit_sha does not exist' do
allow(merge_request_diff).to receive(:head_commit_sha).and_return(nil)
expect(subject[:short_commit_sha]).to eq(nil)
end
end
end end