提交 8db8e2a3 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 33813f99
......@@ -21,6 +21,8 @@ class MergeRequestDiffEntity < Grape::Entity
expose :latest?, as: :latest
expose :short_commit_sha do |merge_request_diff|
next unless merge_request_diff.head_commit_sha
short_sha(merge_request_diff.head_commit_sha)
end
......
......@@ -8,8 +8,9 @@
.input-group-text
= s_("CompareBranches|Source")
= 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
.dropdown-toggle-text.str-truncated= params[:to] || _("Select branch/tag")
= 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.monospace.float-left= params[:to] || _("Select branch/tag")
= sprite_icon('arrow-down', size: 16, css_class: 'float-right')
= render 'shared/ref_dropdown'
.compare-ellipsis.inline ...
.form-group.dropdown.compare-form-group.from.js-compare-from-dropdown
......@@ -18,8 +19,9 @@
.input-group-text
= s_("CompareBranches|Target")
= 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
.dropdown-toggle-text.str-truncated= params[:from] || _("Select branch/tag")
= 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.monospace.float-left= params[:from] || _("Select branch/tag")
= sprite_icon('arrow-down', size: 16, css_class: 'float-right')
= render 'shared/ref_dropdown'
&nbsp;
= button_tag s_("CompareBranches|Compare"), class: "btn btn-success commits-compare-btn"
......
---
title: Adding dropdown arrow icon and updated text alignment
merge_request:
author:
type: other
---
title: Bump Auto-Deploy image to v0.3.0
merge_request: 18809
author:
type: added
---
title: Serialize short sha as nil if head commit is blank
merge_request: 19014
author:
type: fixed
---
title: Support Enable/Disable operations in Feature Flag API
merge_request: 18368
author:
type: added
......@@ -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_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_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`. |
| `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. |
......
.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:
extends: .auto-deploy
......
......@@ -13,6 +13,15 @@ module Quality
end
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 = [
%(--namespace "#{namespace}"),
'delete',
......@@ -20,7 +29,7 @@ module Quality
'--now',
'--ignore-not-found',
'--include-uninitialized',
%(-l release="#{release_name}")
selector
]
run_command(command)
......
......@@ -60,6 +60,8 @@ class AutomatedCleanup
stop_threshold = threshold_time(days: days_for_stop)
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|
break if Time.parse(deployment.created_at) < deployments_look_back_threshold
......@@ -75,7 +77,7 @@ class AutomatedCleanup
if deployed_at < delete_threshold
delete_environment(environment, deployment)
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
stop_environment(environment, deployment)
else
......@@ -84,6 +86,8 @@ class AutomatedCleanup
checked_environments << environment.slug
end
delete_helm_releases(releases_to_delete)
end
def perform_helm_releases_cleanup!(days:)
......@@ -91,16 +95,20 @@ class AutomatedCleanup
threshold_day = threshold_time(days: days)
releases_to_delete = []
helm_releases.each do |release|
# Prevents deleting `dns-gitlab-review-app` releases or other unrelated releases
next unless release.name.start_with?('review-')
if release.status == 'FAILED' || release.last_update < threshold_day
delete_helm_release(release)
releases_to_delete << release
else
print_release_state(subject: 'Release', release_name: release.name, release_date: release.last_update, action: 'leaving')
end
end
delete_helm_releases(releases_to_delete)
end
private
......@@ -121,10 +129,17 @@ class AutomatedCleanup
helm.releases(args: args)
end
def delete_helm_release(release)
print_release_state(subject: 'Release', release_name: release.name, release_status: release.status, release_date: release.last_update, action: 'cleaning')
helm.delete(release_name: release.name)
kubernetes.cleanup(release_name: release.name)
def delete_helm_releases(releases)
return if releases.empty?
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
raise ex unless ignore_exception?(ex.message, IGNORED_HELM_ERRORS)
......
......@@ -17,7 +17,7 @@ module Trigger
end
class Base
def invoke!(post_comment: false)
def invoke!(post_comment: false, downstream_job_name: nil)
pipeline = Gitlab.run_trigger(
downstream_project_path,
trigger_token,
......@@ -28,7 +28,18 @@ module Trigger
puts "Waiting for downstream pipeline status"
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
private
......@@ -187,6 +198,14 @@ module Trigger
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)
@project = project
@id = id
......@@ -199,17 +218,17 @@ module Trigger
def wait!
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
when :created, :pending, :running
print "."
sleep INTERVAL
when :success
puts "Pipeline succeeded in #{duration} minutes!"
puts "#{self.class.unscoped_class_name} succeeded in #{duration} minutes!"
break
else
raise "Pipeline did not succeed!"
raise "#{self.class.unscoped_class_name} did not succeed!"
end
STDOUT.flush
......@@ -225,7 +244,7 @@ module Trigger
end
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
puts "Ignoring the following error: #{error}"
# Ignore GitLab API hiccups. If GitLab is really down, we'll hit the job
......@@ -233,11 +252,13 @@ module Trigger
:running
end
end
Job = Class.new(Pipeline)
end
case ARGV[0]
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'
Trigger::CNG.new.invoke!.wait!
else
......
......@@ -107,5 +107,25 @@ RSpec.describe Quality::HelmClient do
expect(subject.delete(release_name: release_name)).to eq('')
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
......@@ -29,5 +29,30 @@ RSpec.describe Quality::KubernetesClient do
# We're not verifying the output here, just silencing it
expect { subject.cleanup(release_name: release_name) }.to output.to_stdout
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
......@@ -7,14 +7,15 @@ describe MergeRequestDiffEntity do
let(:request) { EntityRequest.new(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_diff) { merge_request_diffs.first }
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
context 'as json' do
subject { entity.as_json }
subject { entity.as_json }
context 'as json' do
it 'exposes needed attributes' do
expect(subject).to include(
:version_index, :created_at, :commits_count,
......@@ -23,4 +24,16 @@ describe MergeRequestDiffEntity do
)
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册