Merge branch 'master-ce' into scheduled-manual-jobs
This commit is contained in:
commit
41fe9edcf7
|
@ -67,10 +67,7 @@ stages:
|
|||
|
||||
.use-pg: &use-pg
|
||||
services:
|
||||
# As of Jan 2018, we don't have a strong reason to upgrade to 9.6 for CI yet,
|
||||
# so using the least common denominator ensures backwards compatibility
|
||||
# (as many users are still using 9.2).
|
||||
- postgres:9.2
|
||||
- postgres:9.6
|
||||
- redis:alpine
|
||||
|
||||
.use-mysql: &use-mysql
|
||||
|
@ -444,10 +441,10 @@ setup-test-env:
|
|||
- vendor/gitaly-ruby
|
||||
|
||||
danger-review:
|
||||
<<: *pull-cache
|
||||
image: registry.gitlab.com/gitlab-org/gitlab-build-images:danger
|
||||
stage: test
|
||||
allow_failure: true
|
||||
cache: {}
|
||||
dependencies: []
|
||||
before_script: []
|
||||
only:
|
||||
|
@ -461,6 +458,8 @@ danger-review:
|
|||
- $CI_COMMIT_REF_NAME =~ /.*-stable(-ee)?-prepare-.*/
|
||||
script:
|
||||
- git version
|
||||
- node --version
|
||||
- yarn install --frozen-lockfile --cache-folder .yarn-cache
|
||||
- danger --fail-on-errors=true
|
||||
|
||||
rspec-pg 0 30: *rspec-metadata-pg
|
||||
|
|
|
@ -7,3 +7,5 @@ danger.import_dangerfile(path: 'danger/database')
|
|||
danger.import_dangerfile(path: 'danger/documentation')
|
||||
danger.import_dangerfile(path: 'danger/frozen_string')
|
||||
danger.import_dangerfile(path: 'danger/commit_messages')
|
||||
danger.import_dangerfile(path: 'danger/prettier')
|
||||
danger.import_dangerfile(path: 'danger/eslint')
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
}
|
||||
|
||||
.avatar-container {
|
||||
margin-right: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
// leave enough space for the close icon
|
||||
.modal-title {
|
||||
&.mw-100,
|
||||
&.w-100 {
|
||||
// after upgrading to Bootstrap 4.2 we can use $modal-header-padding-x here
|
||||
// https://github.com/twbs/bootstrap/pull/26976
|
||||
margin-right: -2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ class Projects::ArtifactsController < Projects::ApplicationController
|
|||
before_action :entry, only: [:file]
|
||||
|
||||
def download
|
||||
return render_404 unless artifacts_file
|
||||
|
||||
send_upload(artifacts_file, attachment: artifacts_file.filename)
|
||||
end
|
||||
|
||||
|
@ -100,7 +102,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
|
|||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
def artifacts_file
|
||||
@artifacts_file ||= build.artifacts_file
|
||||
@artifacts_file ||= build.artifacts_file_for_type(params[:file_type] || :archive)
|
||||
end
|
||||
|
||||
def entry
|
||||
|
|
|
@ -327,11 +327,15 @@ module IssuablesHelper
|
|||
end
|
||||
|
||||
def issuable_button_visibility(issuable, closed)
|
||||
return 'hidden' if issuable_button_hidden?(issuable, closed)
|
||||
end
|
||||
|
||||
def issuable_button_hidden?(issuable, closed)
|
||||
case issuable
|
||||
when Issue
|
||||
issue_button_visibility(issuable, closed)
|
||||
issue_button_hidden?(issuable, closed)
|
||||
when MergeRequest
|
||||
merge_request_button_visibility(issuable, closed)
|
||||
merge_request_button_hidden?(issuable, closed)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -64,7 +64,11 @@ module IssuesHelper
|
|||
end
|
||||
|
||||
def issue_button_visibility(issue, closed)
|
||||
return 'hidden' if issue.closed? == closed
|
||||
return 'hidden' if issue_button_hidden?(issue, closed)
|
||||
end
|
||||
|
||||
def issue_button_hidden?(issue, closed)
|
||||
issue.closed? == closed || (!closed && issue.discussion_locked)
|
||||
end
|
||||
|
||||
def confidential_icon(issue)
|
||||
|
|
|
@ -80,7 +80,11 @@ module MergeRequestsHelper
|
|||
end
|
||||
|
||||
def merge_request_button_visibility(merge_request, closed)
|
||||
return 'hidden' if merge_request.closed? == closed || (merge_request.merged? == closed && !merge_request.closed?) || merge_request.closed_without_fork?
|
||||
return 'hidden' if merge_request_button_hidden?(merge_request, closed)
|
||||
end
|
||||
|
||||
def merge_request_button_hidden?(merge_request, closed)
|
||||
merge_request.closed? == closed || (merge_request.merged? == closed && !merge_request.closed?) || merge_request.closed_without_fork?
|
||||
end
|
||||
|
||||
def merge_request_version_path(project, merge_request, merge_request_diff, start_sha = nil)
|
||||
|
|
|
@ -9,4 +9,17 @@ module VersionCheckHelper
|
|||
image_url = VersionCheck.new.url
|
||||
image_tag image_url, class: 'js-version-status-badge'
|
||||
end
|
||||
|
||||
def link_to_version
|
||||
if Gitlab.pre_release?
|
||||
commit_link = link_to(Gitlab.revision, Gitlab::COM_URL + namespace_project_commits_path('gitlab-org', source_code_project, Gitlab.revision))
|
||||
[Gitlab::VERSION, content_tag(:small, commit_link)].join(' ').html_safe
|
||||
else
|
||||
link_to Gitlab::VERSION, Gitlab::COM_URL + namespace_project_tag_path('gitlab-org', source_code_project, "v#{Gitlab::VERSION}")
|
||||
end
|
||||
end
|
||||
|
||||
def source_code_project
|
||||
'gitlab-ce'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -560,6 +560,13 @@ module Ci
|
|||
self.job_artifacts.update_all(expire_at: nil)
|
||||
end
|
||||
|
||||
def artifacts_file_for_type(type)
|
||||
file = job_artifacts.find_by(file_type: Ci::JobArtifact.file_types[type])&.file
|
||||
# TODO: to be removed once legacy artifacts is removed
|
||||
file ||= legacy_artifacts_file if type == :archive
|
||||
file
|
||||
end
|
||||
|
||||
def coverage_regex
|
||||
super || project.try(:build_coverage_regex)
|
||||
end
|
||||
|
|
|
@ -15,6 +15,7 @@ module Ci
|
|||
metadata: nil,
|
||||
trace: nil,
|
||||
junit: 'junit.xml',
|
||||
codequality: 'codequality.json',
|
||||
sast: 'gl-sast-report.json',
|
||||
dependency_scanning: 'gl-dependency-scanning-report.json',
|
||||
container_scanning: 'gl-container-scanning-report.json',
|
||||
|
@ -26,6 +27,7 @@ module Ci
|
|||
metadata: :gzip,
|
||||
trace: :raw,
|
||||
junit: :gzip,
|
||||
codequality: :gzip,
|
||||
sast: :gzip,
|
||||
dependency_scanning: :gzip,
|
||||
container_scanning: :gzip,
|
||||
|
@ -73,7 +75,8 @@ module Ci
|
|||
sast: 5, ## EE-specific
|
||||
dependency_scanning: 6, ## EE-specific
|
||||
container_scanning: 7, ## EE-specific
|
||||
dast: 8 ## EE-specific
|
||||
dast: 8, ## EE-specific
|
||||
codequality: 9 ## EE-specific
|
||||
}
|
||||
|
||||
enum file_format: {
|
||||
|
|
|
@ -15,6 +15,9 @@ module Clusters
|
|||
state :scheduled, value: 1
|
||||
state :installing, value: 2
|
||||
state :installed, value: 3
|
||||
state :updating, value: 4
|
||||
state :updated, value: 5
|
||||
state :update_errored, value: 6
|
||||
|
||||
event :make_scheduled do
|
||||
transition [:installable, :errored] => :scheduled
|
||||
|
@ -32,6 +35,18 @@ module Clusters
|
|||
transition any => :errored
|
||||
end
|
||||
|
||||
event :make_updating do
|
||||
transition [:installed, :updated, :update_errored] => :updating
|
||||
end
|
||||
|
||||
event :make_updated do
|
||||
transition [:updating] => :updated
|
||||
end
|
||||
|
||||
event :make_update_errored do
|
||||
transition any => :update_errored
|
||||
end
|
||||
|
||||
before_transition any => [:scheduled] do |app_status, _|
|
||||
app_status.status_reason = nil
|
||||
end
|
||||
|
@ -40,6 +55,15 @@ module Clusters
|
|||
status_reason = transition.args.first
|
||||
app_status.status_reason = status_reason if status_reason
|
||||
end
|
||||
|
||||
before_transition any => [:updating] do |app_status, _|
|
||||
app_status.status_reason = nil
|
||||
end
|
||||
|
||||
before_transition any => [:update_errored] do |app_status, transition|
|
||||
status_reason = transition.args.first
|
||||
app_status.status_reason = status_reason if status_reason
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
.sub-section
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :hashed_storage_enabled, class: 'form-check-input'
|
||||
= f.check_box :hashed_storage_enabled, class: 'form-check-input qa-hashed-storage-checkbox'
|
||||
= f.label :hashed_storage_enabled, class: 'form-check-label' do
|
||||
Use hashed storage paths for newly created and renamed projects
|
||||
.form-text.text-muted
|
||||
|
@ -48,4 +48,4 @@
|
|||
.form-text.text-muted
|
||||
= circuitbreaker_failure_reset_time_help_text
|
||||
|
||||
= f.submit 'Save changes', class: "btn btn-success"
|
||||
= f.submit 'Save changes', class: "btn btn-success qa-save-changes-button"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
.settings-content
|
||||
= render partial: 'repository_mirrors_form'
|
||||
|
||||
%section.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
%section.settings.qa-repository-storage-settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4
|
||||
= _('Repository storage')
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
.settings-content
|
||||
= render 'signin'
|
||||
|
||||
%section.qa-terms-settings.settings.as-terms.no-animate#js-terms-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
%section.settings.as-terms.no-animate#js-terms-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4
|
||||
= _('Terms of Service and Privacy Policy')
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
GitLab
|
||||
Community Edition
|
||||
- if user_signed_in?
|
||||
%span= link_to Gitlab::VERSION, Gitlab::COM_URL + namespace_project_tag_path('gitlab-org', 'gitlab-ce', "v#{Gitlab::VERSION}")
|
||||
%span= link_to_version
|
||||
= version_status_badge
|
||||
%hr
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) }
|
||||
.nav-sidebar.qa-admin-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) }
|
||||
.nav-sidebar-inner-scroll
|
||||
.context-header
|
||||
= link_to admin_root_path, title: _('Admin Overview') do
|
||||
|
@ -197,10 +197,10 @@
|
|||
= link_to admin_application_settings_path do
|
||||
.nav-icon-container
|
||||
= sprite_icon('settings')
|
||||
%span.nav-item-name
|
||||
%span.nav-item-name.qa-admin-settings-item
|
||||
= _('Settings')
|
||||
|
||||
%ul.sidebar-sub-level-items
|
||||
%ul.sidebar-sub-level-items.qa-admin-sidebar-submenu
|
||||
= nav_link(controller: :application_settings, html_options: { class: "fly-out-top-item" } ) do
|
||||
= link_to admin_application_settings_path do
|
||||
%strong.fly-out-top-item-name
|
||||
|
@ -215,7 +215,7 @@
|
|||
%span
|
||||
= _('Integrations')
|
||||
= nav_link(path: 'application_settings#repository') do
|
||||
= link_to repository_admin_application_settings_path, title: _('Repository') do
|
||||
= link_to repository_admin_application_settings_path, title: _('Repository'), class: 'qa-admin-settings-repository-item' do
|
||||
%span
|
||||
= _('Repository')
|
||||
- if template_exists?('admin/application_settings/templates')
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
- is_current_user = issuable_author_is_current_user(issuable)
|
||||
- display_issuable_type = issuable_display_type(issuable)
|
||||
- button_method = issuable_close_reopen_button_method(issuable)
|
||||
- are_close_and_open_buttons_hidden = issuable_button_hidden?(issuable, true) && issuable_button_hidden?(issuable, false)
|
||||
|
||||
- if can_update
|
||||
- if is_current_user
|
||||
- if is_current_user
|
||||
- if can_update
|
||||
= link_to "Close #{display_issuable_type}", close_issuable_path(issuable), method: button_method,
|
||||
class: "d-none d-sm-none d-md-block btn btn-grouped btn-close js-btn-issue-action #{issuable_button_visibility(issuable, true)}", title: "Close #{display_issuable_type}"
|
||||
- else
|
||||
= render 'shared/issuable/close_reopen_report_toggle', issuable: issuable
|
||||
- if can_reopen && is_current_user
|
||||
- if can_reopen
|
||||
= link_to "Reopen #{display_issuable_type}", reopen_issuable_path(issuable), method: button_method,
|
||||
class: "d-none d-sm-none d-md-block btn btn-grouped btn-reopen js-btn-issue-action #{issuable_button_visibility(issuable, false)}", title: "Reopen #{display_issuable_type}"
|
||||
- else
|
||||
= link_to 'Report abuse', new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
|
||||
class: 'd-none d-sm-none d-md-block btn btn-grouped btn-close-color', title: 'Report abuse'
|
||||
- if can_update && !are_close_and_open_buttons_hidden
|
||||
= render 'shared/issuable/close_reopen_report_toggle', issuable: issuable
|
||||
- else
|
||||
= link_to 'Report abuse', new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
|
||||
class: 'd-none d-sm-none d-md-block btn btn-grouped btn-close-color', title: 'Report abuse'
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Hides Close Merge request btn on merged Merge request
|
||||
merge_request: 21840
|
||||
author: Jacopo Beschi @jacopo-beschi
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix migration to avoid an exception during upgrade
|
||||
merge_request: 22055
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Align collapsed sidebar avatar container
|
||||
merge_request: 22044
|
||||
author: George Tsiolis
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Show SHA for pre-release versions on the help page
|
||||
merge_request: 22026
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Avoid close icon leaving the modal header
|
||||
merge_request: 21904
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
def get_eslint_files(files)
|
||||
files.select do |file|
|
||||
file.end_with?('.js', '.vue') &&
|
||||
File.read(file).include?('/* eslint-disable')
|
||||
end
|
||||
end
|
||||
|
||||
eslint_candidates = get_eslint_files(git.added_files + git.modified_files)
|
||||
|
||||
return if eslint_candidates.empty?
|
||||
|
||||
warn 'This merge request changed files with disabled eslint rules. Please consider fixing them.'
|
||||
|
||||
markdown(<<~MARKDOWN)
|
||||
## Disabled eslint rules
|
||||
|
||||
The following files have disabled `eslint` rules. Please consider fixing them:
|
||||
|
||||
* #{eslint_candidates.map { |path| "`#{path}`" }.join("\n* ")}
|
||||
|
||||
Run the following command for more details
|
||||
|
||||
```
|
||||
node_modules/.bin/eslint --report-unused-disable-directives --no-inline-config \\
|
||||
#{eslint_candidates.map { |path| " '#{path}'" }.join(" \\\n")}
|
||||
```
|
||||
MARKDOWN
|
|
@ -0,0 +1,39 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
def get_prettier_files(files)
|
||||
files.select do |file|
|
||||
file.end_with?('.js', '.scss', '.vue')
|
||||
end
|
||||
end
|
||||
|
||||
prettier_candidates = get_prettier_files(git.added_files + git.modified_files)
|
||||
|
||||
return if prettier_candidates.empty?
|
||||
|
||||
unpretty = `node_modules/prettier/bin-prettier.js --list-different #{prettier_candidates.join(" ")}`
|
||||
.split(/$/)
|
||||
.map(&:strip)
|
||||
.reject(&:empty?)
|
||||
|
||||
return if unpretty.empty?
|
||||
|
||||
warn 'This merge request changed frontend files without pretty printing them.'
|
||||
|
||||
markdown(<<~MARKDOWN)
|
||||
## Pretty print Frontend files
|
||||
|
||||
The following files should have been pretty printed with `prettier`:
|
||||
|
||||
* #{unpretty.map { |path| "`#{path}`" }.join("\n* ")}
|
||||
|
||||
Please run
|
||||
|
||||
```
|
||||
node_modules/.bin/prettier --write \\
|
||||
#{unpretty.map { |path| " '#{path}'" }.join(" \\\n")}
|
||||
```
|
||||
|
||||
Also consider auto-formatting [on-save].
|
||||
|
||||
[on-save]: https://docs.gitlab.com/ee/development/new_fe_guide/style/prettier.html
|
||||
MARKDOWN
|
|
@ -5,6 +5,8 @@ class RenameLoginRootNamespaces < ActiveRecord::Migration
|
|||
|
||||
DOWNTIME = false
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
# We're taking over the /login namespace as part of a fix for the Jira integration
|
||||
def up
|
||||
disable_statement_timeout do
|
||||
|
|
|
@ -1,48 +1,81 @@
|
|||
# GitLab quick actions
|
||||
|
||||
Quick actions are textual shortcuts for common actions on issues, merge requests
|
||||
or commits that are usually done by clicking buttons or dropdowns in GitLab's UI.
|
||||
You can enter these commands while creating a new issue or merge request, and
|
||||
in comments. Each command should be on a separate line in order to be properly
|
||||
detected and executed. The commands are removed from the issue, merge request or
|
||||
comment body before it is saved and will not be visible to anyone else.
|
||||
Quick actions are textual shortcuts for common actions on issues, epics, merge requests,
|
||||
and commits that are usually done by clicking buttons or dropdowns in GitLab's UI.
|
||||
You can enter these commands while creating a new issue or merge request, or
|
||||
in comments of issues, epics, merge requests, and commits. Each command should be
|
||||
on a separate line in order to be properly detected and executed. Once executed,
|
||||
the commands are removed from the text body and not visible to anyone else.
|
||||
|
||||
Below is a list of all of the available commands and descriptions about what they
|
||||
do.
|
||||
## Quick actions for issues and merge requests
|
||||
|
||||
| Command | Action |
|
||||
|:---------------------------|:-------------|
|
||||
| `/close` | Close the issue or merge request |
|
||||
| `/reopen` | Reopen the issue or merge request |
|
||||
| `/merge` | Merge (when pipeline succeeds) |
|
||||
| `/title <New title>` | Change title |
|
||||
| `/assign @username` | Assign |
|
||||
| `/unassign` | Remove assignee |
|
||||
| `/milestone %milestone` | Set milestone |
|
||||
| `/remove_milestone` | Remove milestone |
|
||||
| `/label ~foo ~"bar baz"` | Add label(s) |
|
||||
| `/unlabel ~foo ~"bar baz"` | Remove all or specific label(s) |
|
||||
| `/relabel ~foo ~"bar baz"` | Replace all label(s) |
|
||||
| `/todo` | Add a todo |
|
||||
| `/done` | Mark todo as done |
|
||||
| `/subscribe` | Subscribe |
|
||||
| `/unsubscribe` | Unsubscribe |
|
||||
| <code>/due <in 2 days | this Friday | December 31st></code> | Set due date |
|
||||
| `/remove_due_date` | Remove due date |
|
||||
| `/wip` | Toggle the Work In Progress status |
|
||||
| <code>/estimate <1w 3d 2h 14m></code> | Set time estimate |
|
||||
| `/remove_estimate` | Remove estimated time |
|
||||
| <code>/spend <time(1h 30m | -1h 5m)> <date(YYYY-MM-DD)></code> | Add or subtract spent time; optionally, specify the date that time was spent on |
|
||||
| `/remove_time_spent` | Remove time spent |
|
||||
| `/target_branch <Branch Name>` | Set target branch for current merge request |
|
||||
| `/award :emoji:` | Toggle award for :emoji: |
|
||||
| `/board_move ~column` | Move issue to column on the board |
|
||||
| `/duplicate #issue` | Closes this issue and marks it as a duplicate of another issue |
|
||||
| `/move path/to/project` | Moves issue to another project |
|
||||
| `/tag v1.2.3 <message>` | Tags a commit with a given tag name and optional message |
|
||||
| `/tableflip` | Append the comment with `(╯°□°)╯︵ ┻━┻` |
|
||||
| `/shrug` | Append the comment with `¯\_(ツ)_/¯` |
|
||||
| <code>/copy_metadata #issue | !merge_request</code> | Copy labels and milestone from other issue or merge request |
|
||||
| `/confidential` | Makes the issue confidential |
|
||||
| `/lock` | Lock the discussion |
|
||||
| `/unlock` | Unlock the discussion |
|
||||
The following quick actions are applicable to both issues and merge requests threads,
|
||||
discussions, and descriptions:
|
||||
|
||||
| Command | Action | Issue | Merge request |
|
||||
|:---------------------------|:------------------------------ |:------|:--------------|
|
||||
| `/tableflip <Comment>` | Append the comment with `(╯°□°)╯︵ ┻━┻` | ✓ | ✓ |
|
||||
| `/shrug <Comment>` | Append the comment with `¯\_(ツ)_/¯` | ✓ | ✓ |
|
||||
| `/todo` | Add a todo | ✓ | ✓ |
|
||||
| `/done` | Mark todo as done | ✓ | ✓ |
|
||||
| `/subscribe` | Subscribe | ✓ | ✓ |
|
||||
| `/unsubscribe` | Unsubscribe | ✓ | ✓ |
|
||||
| `/close` | Close | ✓ | ✓ |
|
||||
| `/reopen` | Reopen | ✓ | ✓ |
|
||||
| `/title <New title>` | Change title | ✓ | ✓ |
|
||||
| `/award :emoji:` | Toggle emoji award | ✓ | ✓ |
|
||||
| `/assign @user` | Assign one user | ✓ | ✓ |
|
||||
| `/assign @user1 @user2` | Assign multiple users **[STARTER]** | ✓ | |
|
||||
| `/unassign` | Remove assignee(s) | ✓ | ✓ |
|
||||
| `/reassign @user1 @user2` | Change assignee | ✓ | ✓ |
|
||||
| `/milestone %milestone` | Set milestone | ✓ | ✓ |
|
||||
| `/remove_milestone` | Remove milestone | ✓ | ✓ |
|
||||
| `/label ~label1 ~label2` | Add label(s) | ✓ | ✓ |
|
||||
| `/unlabel ~label1 ~label2` | Remove all or specific label(s)| ✓ | ✓ |
|
||||
| `/relabel ~label1 ~label2` | Replace label | ✓ | ✓ |
|
||||
| <code>/copy_metadata #issue | !merge_request</code> | Copy labels and milestone from other issue or merge request | ✓ | ✓ |
|
||||
| <code>/estimate <1w 3d 2h 14m></code> | Set time estimate | ✓ | ✓ |
|
||||
| `/remove_estimate` | Remove time estimate | ✓ | ✓ |
|
||||
| <code>/spend <time(1h 30m | -1h 5m)> <date(YYYY-MM-DD)></code> | Add or subtract spent time; optionally, specify the date that time was spent on | ✓ | ✓ |
|
||||
| `/remove_time_spent` | Remove time spent | ✓ | ✓ |
|
||||
| <code>/due <in 2 days | this Friday | December 31st></code>| Set due date | ✓ |
|
||||
| `/remove_due_date` | Remove due date | ✓ | |
|
||||
| `/weight 0,1,2, ...` | Set weight **[STARTER]** | ✓ | |
|
||||
| `/clear_weight` | Clears weight **[STARTER]** | ✓ | |
|
||||
| `/epic <group&epic | Epic URL>` | Add to epic **[ULTIMATE]** | ✓ | |
|
||||
| `/remove_epic` | Removes from epic **[ULTIMATE]** | ✓ | |
|
||||
| `/confidential` | Make confidential | ✓ | |
|
||||
| `/duplicate #issue` | Mark this issue as a duplicate of another issue | ✓ |
|
||||
| `/move path/to/project` | Move this issue to another project | ✓ | |
|
||||
| `/target_branch <Local branch Name>` | Set target branch | | ✓ |
|
||||
| `/wip` | Toggle the Work In Progress status | | ✓ |
|
||||
| `/merge` | Merge (when pipeline succeeds) | | ✓ |
|
||||
|
||||
|
||||
## Quick actions for commit messages
|
||||
|
||||
The following quick actions are applicable for commit messages:
|
||||
|
||||
| Command | Action |
|
||||
|:------------------------|:------------------------------------------|
|
||||
| `/tag v1.2.3 <message>` | Tags this commit with an optional message |
|
||||
|
||||
## Quick actions for Epics **[ULTIMATE]**
|
||||
|
||||
The following quick actions are applicable for epics threads and description:
|
||||
|
||||
| Command | Action |
|
||||
|:---------------------------|:----------------------------------------|
|
||||
| `/tableflip <Comment>` | Append the comment with `(╯°□°)╯︵ ┻━┻` |
|
||||
| `/shrug <Comment>` | Append the comment with `¯\_(ツ)_/¯` |
|
||||
| `/todo` | Add a todo |
|
||||
| `/done` | Mark todo as done |
|
||||
| `/subscribe` | Subscribe |
|
||||
| `/unsubscribe` | Unsubscribe |
|
||||
| `/close` | Close |
|
||||
| `/reopen` | Reopen |
|
||||
| `/title <New title>` | Change title |
|
||||
| `/award :emoji:` | Toggle emoji award |
|
||||
| `/label ~label1 ~label2` | Add label(s) |
|
||||
| `/unlabel ~label1 ~label2` | Remove all or specific label(s) |
|
||||
| `/relabel ~label1 ~label2` | Replace label |
|
|
@ -47,4 +47,8 @@ module Gitlab
|
|||
def self.dev_env_or_com?
|
||||
Rails.env.development? || org? || com?
|
||||
end
|
||||
|
||||
def self.pre_release?
|
||||
VERSION.include?('pre')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ module Gitlab
|
|||
include Validatable
|
||||
include Attributable
|
||||
|
||||
ALLOWED_KEYS = %i[junit sast dependency_scanning container_scanning dast].freeze
|
||||
ALLOWED_KEYS = %i[junit codequality sast dependency_scanning container_scanning dast].freeze
|
||||
|
||||
attributes ALLOWED_KEYS
|
||||
|
||||
|
@ -21,6 +21,7 @@ module Gitlab
|
|||
|
||||
with_options allow_nil: true do
|
||||
validates :junit, array_of_strings_or_string: true
|
||||
validates :codequality, array_of_strings_or_string: true
|
||||
validates :sast, array_of_strings_or_string: true
|
||||
validates :dependency_scanning, array_of_strings_or_string: true
|
||||
validates :container_scanning, array_of_strings_or_string: true
|
||||
|
|
|
@ -17,6 +17,12 @@ module Gitlab
|
|||
kubeclient.create_pod(command.pod_resource)
|
||||
end
|
||||
|
||||
def update(command)
|
||||
namespace.ensure_exists!
|
||||
update_config_map(command)
|
||||
kubeclient.create_pod(command.pod_resource)
|
||||
end
|
||||
|
||||
##
|
||||
# Returns Pod phase
|
||||
#
|
||||
|
@ -36,6 +42,12 @@ module Gitlab
|
|||
kubeclient.delete_pod(pod_name, namespace.name)
|
||||
end
|
||||
|
||||
def get_config_map(config_map_name)
|
||||
namespace.ensure_exists!
|
||||
|
||||
kubeclient.get_config_map(config_map_name, namespace.name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :kubeclient, :namespace
|
||||
|
@ -46,6 +58,12 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def update_config_map(command)
|
||||
command.config_map_resource.tap do |config_map_resource|
|
||||
kubeclient.update_config_map(config_map_resource)
|
||||
end
|
||||
end
|
||||
|
||||
def create_service_account(command)
|
||||
command.service_account_resource.tap do |service_account_resource|
|
||||
break unless service_account_resource
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
class UpgradeCommand
|
||||
include BaseCommand
|
||||
|
||||
attr_reader :name, :chart, :version, :repository, :files
|
||||
|
||||
def initialize(name, chart:, files:, rbac:, version: nil, repository: nil)
|
||||
@name = name
|
||||
@chart = chart
|
||||
@rbac = rbac
|
||||
@version = version
|
||||
@files = files
|
||||
@repository = repository
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
init_command,
|
||||
repository_command,
|
||||
script_command
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
def rbac?
|
||||
@rbac
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"upgrade-#{name}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_command
|
||||
'helm init --client-only >/dev/null'
|
||||
end
|
||||
|
||||
def repository_command
|
||||
"helm repo add #{name} #{repository}" if repository
|
||||
end
|
||||
|
||||
def script_command
|
||||
upgrade_flags = "#{optional_version_flag}#{optional_tls_flags}" \
|
||||
" --reset-values" \
|
||||
" --install" \
|
||||
" --namespace #{::Gitlab::Kubernetes::Helm::NAMESPACE}" \
|
||||
" -f /data/helm/#{name}/config/values.yaml"
|
||||
|
||||
"helm upgrade #{name} #{chart}#{upgrade_flags} >/dev/null\n"
|
||||
end
|
||||
|
||||
def optional_version_flag
|
||||
" --version #{version}" if version
|
||||
end
|
||||
|
||||
def optional_tls_flags
|
||||
return unless files.key?(:'ca.pem')
|
||||
|
||||
" --tls" \
|
||||
" --tls-ca-cert #{files_dir}/ca.pem" \
|
||||
" --tls-cert #{files_dir}/cert.pem" \
|
||||
" --tls-key #{files_dir}/key.pem"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1173
locale/fr/gitlab.po
1173
locale/fr/gitlab.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1403
locale/ko/gitlab.po
1403
locale/ko/gitlab.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1017
locale/uk/gitlab.po
1017
locale/uk/gitlab.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
7
qa/qa.rb
7
qa/qa.rb
|
@ -236,8 +236,11 @@ module QA
|
|||
|
||||
module Admin
|
||||
module Settings
|
||||
autoload :RepositoryStorage, 'qa/page/admin/settings/repository_storage'
|
||||
autoload :Main, 'qa/page/admin/settings/main'
|
||||
autoload :Repository, 'qa/page/admin/settings/repository'
|
||||
|
||||
module Component
|
||||
autoload :RepositoryStorage, 'qa/page/admin/settings/component/repository_storage'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
module Page
|
||||
module Admin
|
||||
module Settings
|
||||
module Component
|
||||
class RepositoryStorage < Page::Base
|
||||
view 'app/views/admin/application_settings/_repository_storage.html.haml' do
|
||||
element :hashed_storage_checkbox
|
||||
element :save_changes_button
|
||||
end
|
||||
|
||||
def enable_hashed_storage
|
||||
check_element :hashed_storage_checkbox
|
||||
end
|
||||
|
||||
def save_settings
|
||||
click_element :save_changes_button
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
module QA
|
||||
module Page
|
||||
module Admin
|
||||
module Settings
|
||||
class Main < Page::Base
|
||||
include QA::Page::Settings::Common
|
||||
|
||||
view 'app/views/admin/application_settings/show.html.haml' do
|
||||
element :terms_settings
|
||||
end
|
||||
|
||||
def expand_repository_storage(&block)
|
||||
expand_section(:terms_settings) do
|
||||
RepositoryStorage.perform(&block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
module Page
|
||||
module Admin
|
||||
module Settings
|
||||
class Repository < Page::Base
|
||||
include QA::Page::Settings::Common
|
||||
|
||||
view 'app/views/admin/application_settings/repository.html.haml' do
|
||||
element :repository_storage_settings
|
||||
end
|
||||
|
||||
def expand_repository_storage(&block)
|
||||
expand_section(:repository_storage_settings) do
|
||||
Component::RepositoryStorage.perform(&block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
module QA
|
||||
module Page
|
||||
module Admin
|
||||
module Settings
|
||||
class RepositoryStorage < Page::Base
|
||||
view 'app/views/admin/application_settings/_repository_storage.html.haml' do
|
||||
element :submit, "submit 'Save changes'"
|
||||
element :hashed_storage,
|
||||
'Use hashed storage paths for newly created and renamed projects'
|
||||
end
|
||||
|
||||
def enable_hashed_storage
|
||||
check 'Use hashed storage paths for newly created and renamed projects'
|
||||
end
|
||||
|
||||
def save_settings
|
||||
click_button 'Save changes'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -68,6 +68,10 @@ module QA
|
|||
all(element_selector_css(name))
|
||||
end
|
||||
|
||||
def check_element(name)
|
||||
find_element(name).set(true)
|
||||
end
|
||||
|
||||
def click_element(name)
|
||||
find_element(name).click
|
||||
end
|
||||
|
@ -86,6 +90,10 @@ module QA
|
|||
end
|
||||
end
|
||||
|
||||
def scroll_to_element(name, *args)
|
||||
scroll_to(element_selector_css(name), *args)
|
||||
end
|
||||
|
||||
def element_selector_css(name)
|
||||
Page::Element.new(name).selector_css
|
||||
end
|
||||
|
|
|
@ -3,11 +3,41 @@ module QA
|
|||
module Menu
|
||||
class Admin < Page::Base
|
||||
view 'app/views/layouts/nav/sidebar/_admin.html.haml' do
|
||||
element :settings, "_('Settings')"
|
||||
element :admin_sidebar
|
||||
element :admin_sidebar_submenu
|
||||
element :admin_settings_item
|
||||
element :admin_settings_repository_item
|
||||
end
|
||||
|
||||
def go_to_settings
|
||||
click_link 'Settings'
|
||||
def go_to_repository_settings
|
||||
hover_settings do
|
||||
within_submenu do
|
||||
click_element :admin_settings_repository_item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def hover_settings
|
||||
within_sidebar do
|
||||
scroll_to_element(:admin_settings_item)
|
||||
find_element(:admin_settings_item).hover
|
||||
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
def within_sidebar
|
||||
within_element(:admin_sidebar) do
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
def within_submenu
|
||||
within_element(:admin_sidebar_submenu) do
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,7 +30,7 @@ describe QA::Page::Validator do
|
|||
let(:view) { spy('view') }
|
||||
|
||||
before do
|
||||
allow(QA::Page::Admin::Settings::Main)
|
||||
allow(QA::Page::Admin::Settings::Repository)
|
||||
.to receive(:views).and_return([view])
|
||||
end
|
||||
|
||||
|
|
|
@ -19,10 +19,42 @@ describe Projects::ArtifactsController do
|
|||
end
|
||||
|
||||
describe 'GET download' do
|
||||
it 'sends the artifacts file' do
|
||||
expect(controller).to receive(:send_file).with(job.artifacts_file.path, hash_including(disposition: 'attachment')).and_call_original
|
||||
subject { get :download, namespace_id: project.namespace, project_id: project, job_id: job, file_type: file_type }
|
||||
|
||||
get :download, namespace_id: project.namespace, project_id: project, job_id: job
|
||||
context 'when no file type is supplied' do
|
||||
let(:file_type) { nil }
|
||||
|
||||
it 'sends the artifacts file' do
|
||||
expect(controller).to receive(:send_file).with(job.artifacts_file.path, hash_including(disposition: 'attachment')).and_call_original
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a file type is supplied' do
|
||||
context 'when an invalid file type is supplied' do
|
||||
let(:file_type) { 'invalid' }
|
||||
|
||||
it 'returns 404' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when codequality file type is supplied' do
|
||||
let(:file_type) { 'codequality' }
|
||||
|
||||
before do
|
||||
create(:ci_job_artifact, :codequality, job: job)
|
||||
end
|
||||
|
||||
it 'sends the codequality report' do
|
||||
expect(controller).to receive(:send_file).with(job.job_artifacts_codequality.file.path, hash_including(disposition: 'attachment')).and_call_original
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -117,6 +117,16 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :codequality do
|
||||
file_type :codequality
|
||||
file_format :gzip
|
||||
|
||||
after(:build) do |artifact, evaluator|
|
||||
artifact.file = fixture_file_upload(
|
||||
Rails.root.join('spec/fixtures/codequality/codequality.json.gz'), 'application/x-gzip')
|
||||
end
|
||||
end
|
||||
|
||||
trait :correct_checksum do
|
||||
after(:build) do |artifact, evaluator|
|
||||
artifact.file_sha256 = Digest::SHA256.file(artifact.file.path).hexdigest
|
||||
|
|
|
@ -22,11 +22,24 @@ FactoryBot.define do
|
|||
status 3
|
||||
end
|
||||
|
||||
trait :updating do
|
||||
status 4
|
||||
end
|
||||
|
||||
trait :updated do
|
||||
status 5
|
||||
end
|
||||
|
||||
trait :errored do
|
||||
status(-1)
|
||||
status_reason 'something went wrong'
|
||||
end
|
||||
|
||||
trait :update_errored do
|
||||
status(6)
|
||||
status_reason 'something went wrong'
|
||||
end
|
||||
|
||||
trait :timeouted do
|
||||
installing
|
||||
updated_at ClusterWaitForAppInstallationWorker::TIMEOUT.ago
|
||||
|
|
|
@ -13,6 +13,10 @@ FactoryBot.define do
|
|||
state :opened
|
||||
end
|
||||
|
||||
trait :locked do
|
||||
discussion_locked true
|
||||
end
|
||||
|
||||
trait :closed do
|
||||
state :closed
|
||||
closed_at { Time.now }
|
||||
|
|
|
@ -56,6 +56,24 @@ describe 'Issuables Close/Reopen/Report toggle' do
|
|||
end
|
||||
|
||||
it_behaves_like 'an issuable close/reopen/report toggle'
|
||||
|
||||
context 'when the issue is closed and locked' do
|
||||
let(:issuable) { create(:issue, :closed, :locked, project: project) }
|
||||
|
||||
it 'hides the reopen button' do
|
||||
expect(page).not_to have_link('Reopen issue')
|
||||
end
|
||||
|
||||
context 'when the issue author is the current user' do
|
||||
before do
|
||||
issuable.update(author: user)
|
||||
end
|
||||
|
||||
it 'hides the reopen button' do
|
||||
expect(page).not_to have_link('Reopen issue')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user doesnt have permission to update' do
|
||||
|
@ -93,6 +111,28 @@ describe 'Issuables Close/Reopen/Report toggle' do
|
|||
end
|
||||
|
||||
it_behaves_like 'an issuable close/reopen/report toggle'
|
||||
|
||||
context 'when the merge request is merged' do
|
||||
let(:issuable) { create(:merge_request, :merged, source_project: project) }
|
||||
|
||||
it 'shows only the `Report abuse` and `Edit` button' do
|
||||
expect(page).to have_link('Report abuse')
|
||||
expect(page).to have_link('Edit')
|
||||
expect(page).not_to have_link('Close merge request')
|
||||
expect(page).not_to have_link('Reopen merge request')
|
||||
end
|
||||
|
||||
context 'when the merge request author is the current user' do
|
||||
let(:issuable) { create(:merge_request, :merged, source_project: project, author: user) }
|
||||
|
||||
it 'shows only the `Edit` button' do
|
||||
expect(page).to have_link('Edit')
|
||||
expect(page).not_to have_link('Report abuse')
|
||||
expect(page).not_to have_link('Close merge request')
|
||||
expect(page).not_to have_link('Reopen merge request')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user doesnt have permission to update' do
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -33,6 +33,7 @@ describe Gitlab::Ci::Config::Entry::Reports do
|
|||
|
||||
where(:keyword, :file) do
|
||||
:junit | 'junit.xml'
|
||||
:codequality | 'codequality.json'
|
||||
:sast | 'gl-sast-report.json'
|
||||
:dependency_scanning | 'gl-dependency-scanning-report.json'
|
||||
:container_scanning | 'gl-container-scanning-report.json'
|
||||
|
|
|
@ -150,6 +150,43 @@ describe Gitlab::Kubernetes::Helm::Api do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
let(:rbac) { false }
|
||||
|
||||
let(:command) do
|
||||
Gitlab::Kubernetes::Helm::UpgradeCommand.new(
|
||||
application_name,
|
||||
chart: 'chart-name',
|
||||
files: files,
|
||||
rbac: rbac
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
allow(namespace).to receive(:ensure_exists!).once
|
||||
|
||||
allow(client).to receive(:update_config_map).and_return(nil)
|
||||
allow(client).to receive(:create_pod).and_return(nil)
|
||||
end
|
||||
|
||||
it 'ensures the namespace exists before creating the pod' do
|
||||
expect(namespace).to receive(:ensure_exists!).once.ordered
|
||||
expect(client).to receive(:create_pod).once.ordered
|
||||
|
||||
subject.update(command)
|
||||
end
|
||||
|
||||
it 'updates the config map on kubeclient when one exists' do
|
||||
resource = Gitlab::Kubernetes::ConfigMap.new(
|
||||
application_name, files
|
||||
).generate
|
||||
|
||||
expect(client).to receive(:update_config_map).with(resource).once
|
||||
|
||||
subject.update(command)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#status' do
|
||||
let(:phase) { Gitlab::Kubernetes::Pod::RUNNING }
|
||||
let(:pod) { Kubeclient::Resource.new(status: { phase: phase }) } # partial representation
|
||||
|
@ -179,4 +216,25 @@ describe Gitlab::Kubernetes::Helm::Api do
|
|||
subject.delete_pod!(command.pod_name)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#get_config_map' do
|
||||
before do
|
||||
allow(namespace).to receive(:ensure_exists!).once
|
||||
allow(client).to receive(:get_config_map).and_return(nil)
|
||||
end
|
||||
|
||||
it 'ensures the namespace exists before retrieving the config map' do
|
||||
expect(namespace).to receive(:ensure_exists!).once
|
||||
|
||||
subject.get_config_map('example-config-map-name')
|
||||
end
|
||||
|
||||
it 'gets the config map on kubeclient' do
|
||||
expect(client).to receive(:get_config_map)
|
||||
.with('example-config-map-name', namespace.name)
|
||||
.once
|
||||
|
||||
subject.get_config_map('example-config-map-name')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::Kubernetes::Helm::UpgradeCommand do
|
||||
let(:application) { build(:clusters_applications_prometheus) }
|
||||
let(:files) { { 'ca.pem': 'some file content' } }
|
||||
let(:namespace) { ::Gitlab::Kubernetes::Helm::NAMESPACE }
|
||||
let(:rbac) { false }
|
||||
let(:upgrade_command) do
|
||||
described_class.new(
|
||||
application.name,
|
||||
chart: application.chart,
|
||||
files: files,
|
||||
rbac: rbac
|
||||
)
|
||||
end
|
||||
|
||||
subject { upgrade_command }
|
||||
|
||||
it_behaves_like 'helm commands' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm init --client-only >/dev/null
|
||||
helm upgrade #{application.name} #{application.chart} --tls --tls-ca-cert /data/helm/#{application.name}/config/ca.pem --tls-cert /data/helm/#{application.name}/config/cert.pem --tls-key /data/helm/#{application.name}/config/key.pem --reset-values --install --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
context 'rbac is true' do
|
||||
let(:rbac) { true }
|
||||
|
||||
it_behaves_like 'helm commands' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm init --client-only >/dev/null
|
||||
helm upgrade #{application.name} #{application.chart} --tls --tls-ca-cert /data/helm/#{application.name}/config/ca.pem --tls-cert /data/helm/#{application.name}/config/cert.pem --tls-key /data/helm/#{application.name}/config/key.pem --reset-values --install --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an application with a repository' do
|
||||
let(:ci_runner) { create(:ci_runner) }
|
||||
let(:application) { build(:clusters_applications_runner, runner: ci_runner) }
|
||||
let(:upgrade_command) do
|
||||
described_class.new(
|
||||
application.name,
|
||||
chart: application.chart,
|
||||
files: files,
|
||||
rbac: rbac,
|
||||
repository: application.repository
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'helm commands' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm init --client-only >/dev/null
|
||||
helm repo add #{application.name} #{application.repository}
|
||||
helm upgrade #{application.name} #{application.chart} --tls --tls-ca-cert /data/helm/#{application.name}/config/ca.pem --tls-cert /data/helm/#{application.name}/config/cert.pem --tls-key /data/helm/#{application.name}/config/key.pem --reset-values --install --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is no ca.pem file' do
|
||||
let(:files) { { 'file.txt': 'some content' } }
|
||||
|
||||
it_behaves_like 'helm commands' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm init --client-only >/dev/null
|
||||
helm upgrade #{application.name} #{application.chart} --reset-values --install --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pod_resource' do
|
||||
subject { upgrade_command.pod_resource }
|
||||
|
||||
context 'rbac is enabled' do
|
||||
let(:rbac) { true }
|
||||
|
||||
it 'generates a pod that uses the tiller serviceAccountName' do
|
||||
expect(subject.spec.serviceAccountName).to eq('tiller')
|
||||
end
|
||||
end
|
||||
|
||||
context 'rbac is not enabled' do
|
||||
let(:rbac) { false }
|
||||
|
||||
it 'generates a pod that uses the default serviceAccountName' do
|
||||
expect(subject.spec.serviceAcccountName).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#config_map_resource' do
|
||||
let(:metadata) do
|
||||
{
|
||||
name: "values-content-configuration-#{application.name}",
|
||||
namespace: namespace,
|
||||
labels: { name: "values-content-configuration-#{application.name}" }
|
||||
}
|
||||
end
|
||||
let(:resource) { ::Kubeclient::Resource.new(metadata: metadata, data: files) }
|
||||
|
||||
it 'returns a KubeClient resource with config map content for the application' do
|
||||
expect(subject.config_map_resource).to eq(resource)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#rbac?' do
|
||||
subject { upgrade_command.rbac? }
|
||||
|
||||
context 'rbac is enabled' do
|
||||
let(:rbac) { true }
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'rbac is not enabled' do
|
||||
let(:rbac) { false }
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pod_name' do
|
||||
it 'returns the pod name' do
|
||||
expect(subject.pod_name).to eq("upgrade-#{application.name}")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1433,6 +1433,19 @@ describe Ci::Build do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#artifacts_file_for_type' do
|
||||
let(:build) { create(:ci_build, :artifacts) }
|
||||
let(:file_type) { :archive }
|
||||
|
||||
subject { build.artifacts_file_for_type(file_type) }
|
||||
|
||||
it 'queries artifacts for type' do
|
||||
expect(build).to receive_message_chain(:job_artifacts, :find_by).with(file_type: Ci::JobArtifact.file_types[file_type])
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
describe '#merge_request' do
|
||||
def create_mr(build, pipeline, factory: :merge_request, created_at: Time.now)
|
||||
create(factory, source_project: pipeline.project,
|
||||
|
|
|
@ -34,7 +34,7 @@ describe Ci::JobArtifact do
|
|||
describe '.erasable' do
|
||||
subject { described_class.erasable }
|
||||
|
||||
context 'when there is am erasable artifact' do
|
||||
context 'when there is an erasable artifact' do
|
||||
let!(:artifact) { create(:ci_job_artifact, :junit) }
|
||||
|
||||
it { is_expected.to eq([artifact]) }
|
||||
|
|
|
@ -112,7 +112,7 @@ describe IssuePolicy do
|
|||
let(:project) { create(:project, :public) }
|
||||
let(:issue) { create(:issue, project: project, assignees: [assignee], author: author) }
|
||||
let(:issue_no_assignee) { create(:issue, project: project) }
|
||||
let(:issue_locked) { create(:issue, project: project, discussion_locked: true, author: author, assignees: [assignee]) }
|
||||
let(:issue_locked) { create(:issue, :locked, project: project, author: author, assignees: [assignee]) }
|
||||
|
||||
before do
|
||||
project.add_guest(guest)
|
||||
|
|
|
@ -27,7 +27,7 @@ describe Ci::RetryBuildService do
|
|||
job_artifacts_metadata job_artifacts_trace job_artifacts_junit
|
||||
job_artifacts_sast job_artifacts_dependency_scanning
|
||||
job_artifacts_container_scanning job_artifacts_dast
|
||||
scheduled_at].freeze
|
||||
job_artifacts_codequality scheduled_at].freeze
|
||||
|
||||
IGNORE_ACCESSORS =
|
||||
%i[type lock_version target_url base_tags trace_sections
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module StubVersion
|
||||
def stub_version(version, revision)
|
||||
stub_const('Gitlab::VERSION', version)
|
||||
allow(Gitlab).to receive(:revision).and_return(revision)
|
||||
end
|
||||
end
|
|
@ -1,11 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'help/index' do
|
||||
include StubVersion
|
||||
|
||||
describe 'version information' do
|
||||
before do
|
||||
stub_helpers
|
||||
end
|
||||
|
||||
it 'is hidden from guests' do
|
||||
stub_user(nil)
|
||||
stub_version('8.0.2', 'abcdefg')
|
||||
stub_helpers
|
||||
|
||||
render
|
||||
|
||||
|
@ -13,15 +20,28 @@ describe 'help/index' do
|
|||
expect(rendered).not_to match 'abcdefg'
|
||||
end
|
||||
|
||||
it 'is shown to users' do
|
||||
stub_user
|
||||
stub_version('8.0.2', 'abcdefg')
|
||||
stub_helpers
|
||||
context 'when logged in' do
|
||||
before do
|
||||
stub_user
|
||||
end
|
||||
|
||||
render
|
||||
it 'shows a link to the tag to users' do
|
||||
stub_version('8.0.2', 'abcdefg')
|
||||
|
||||
expect(rendered).to match '8.0.2'
|
||||
expect(rendered).to have_link('8.0.2', href: 'https://gitlab.com/gitlab-org/gitlab-ce/tags/v8.0.2')
|
||||
render
|
||||
|
||||
expect(rendered).to match '8.0.2'
|
||||
expect(rendered).to have_link('8.0.2', href: %r{https://gitlab.com/gitlab-org/gitlab-(ce|ee)/tags/v8.0.2})
|
||||
end
|
||||
|
||||
it 'shows a link to the commit for pre-releases' do
|
||||
stub_version('8.0.2-pre', 'abcdefg')
|
||||
|
||||
render
|
||||
|
||||
expect(rendered).to match '8.0.2'
|
||||
expect(rendered).to have_link('abcdefg', href: %r{https://gitlab.com/gitlab-org/gitlab-(ce|ee)/commits/abcdefg})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -37,11 +57,6 @@ describe 'help/index' do
|
|||
allow(view).to receive(:user_signed_in?).and_return(user)
|
||||
end
|
||||
|
||||
def stub_version(version, revision)
|
||||
stub_const('Gitlab::VERSION', version)
|
||||
allow(Gitlab).to receive(:revision).and_return(revision)
|
||||
end
|
||||
|
||||
def stub_helpers
|
||||
allow(view).to receive(:markdown).and_return('')
|
||||
allow(view).to receive(:version_status_badge).and_return('')
|
||||
|
|
Loading…
Reference in New Issue