New upstream version 12.10.3
This commit is contained in:
parent
d76068268a
commit
87b5168698
53 changed files with 306 additions and 222 deletions
|
@ -1,5 +1,14 @@
|
||||||
Please view this file on the master branch, on stable branches it's out of date.
|
Please view this file on the master branch, on stable branches it's out of date.
|
||||||
|
|
||||||
|
## 12.10.2 (2020-04-30)
|
||||||
|
|
||||||
|
### Security (3 changes)
|
||||||
|
|
||||||
|
- Fix rendering failure of Audit Event generated by Releases API.
|
||||||
|
- Ensure that NuGet package versions are SemVer compliant.
|
||||||
|
- Ensure that NuGet package versions are validated before updating the stored file path.
|
||||||
|
|
||||||
|
|
||||||
## 12.10.1 (2020-04-24)
|
## 12.10.1 (2020-04-24)
|
||||||
|
|
||||||
### Changed (1 change)
|
### Changed (1 change)
|
||||||
|
|
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -2,6 +2,22 @@
|
||||||
documentation](doc/development/changelog.md) for instructions on adding your own
|
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
|
## 12.10.3 (2020-05-04)
|
||||||
|
|
||||||
|
### Fixed (6 changes)
|
||||||
|
|
||||||
|
- Fix errors creating project with active Prometheus service template. !30340
|
||||||
|
- Fix incorrect commits number in commits list. !30412
|
||||||
|
- Fix second 500 error with NULL restricted visibility levels. !30414
|
||||||
|
- Add LFS badge feature flag to RefsController#logs_tree. !30442
|
||||||
|
- Disable schema dumping after migrations in production. !30812
|
||||||
|
- Fixes branch name not getting escaped correctly on frontend.
|
||||||
|
|
||||||
|
### Changed (1 change)
|
||||||
|
|
||||||
|
- Handle possible RSA key exceptions when generating CI_JOB_JWT. !30702
|
||||||
|
|
||||||
|
|
||||||
## 12.10.2 (2020-04-30)
|
## 12.10.2 (2020-04-30)
|
||||||
|
|
||||||
### Security (8 changes)
|
### Security (8 changes)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
12.10.2
|
12.10.3
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
12.10.2
|
12.10.3
|
||||||
|
|
|
@ -3,7 +3,6 @@ import SecretValues from '~/behaviors/secret_values';
|
||||||
import AjaxVariableList from '~/ci_variable_list/ajax_variable_list';
|
import AjaxVariableList from '~/ci_variable_list/ajax_variable_list';
|
||||||
import registrySettingsApp from '~/registry/settings/registry_settings_bundle';
|
import registrySettingsApp from '~/registry/settings/registry_settings_bundle';
|
||||||
import initVariableList from '~/ci_variable_list';
|
import initVariableList from '~/ci_variable_list';
|
||||||
import initDeployKeys from '~/deploy_keys';
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
// Initialize expandable settings panels
|
// Initialize expandable settings panels
|
||||||
|
@ -41,5 +40,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
registrySettingsApp();
|
registrySettingsApp();
|
||||||
initDeployKeys();
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import ProtectedTagCreate from '~/protected_tags/protected_tag_create';
|
import ProtectedTagCreate from '~/protected_tags/protected_tag_create';
|
||||||
import ProtectedTagEditList from '~/protected_tags/protected_tag_edit_list';
|
import ProtectedTagEditList from '~/protected_tags/protected_tag_edit_list';
|
||||||
import initSettingsPanels from '~/settings_panels';
|
import initSettingsPanels from '~/settings_panels';
|
||||||
|
import initDeployKeys from '~/deploy_keys';
|
||||||
import ProtectedBranchCreate from '~/protected_branches/protected_branch_create';
|
import ProtectedBranchCreate from '~/protected_branches/protected_branch_create';
|
||||||
import ProtectedBranchEditList from '~/protected_branches/protected_branch_edit_list';
|
import ProtectedBranchEditList from '~/protected_branches/protected_branch_edit_list';
|
||||||
import DueDateSelectors from '~/due_date_select';
|
import DueDateSelectors from '~/due_date_select';
|
||||||
|
@ -11,6 +12,7 @@ import fileUpload from '~/lib/utils/file_upload';
|
||||||
export default () => {
|
export default () => {
|
||||||
new ProtectedTagCreate();
|
new ProtectedTagCreate();
|
||||||
new ProtectedTagEditList();
|
new ProtectedTagEditList();
|
||||||
|
initDeployKeys();
|
||||||
initSettingsPanels();
|
initSettingsPanels();
|
||||||
new ProtectedBranchCreate();
|
new ProtectedBranchCreate();
|
||||||
new ProtectedBranchEditList();
|
new ProtectedBranchEditList();
|
||||||
|
|
|
@ -108,14 +108,14 @@ export default {
|
||||||
return acc.concat({
|
return acc.concat({
|
||||||
name,
|
name,
|
||||||
path,
|
path,
|
||||||
to: `/-/tree/${joinPaths(escapeFileUrl(this.ref), path)}`,
|
to: `/-/tree/${joinPaths(this.escapedRef, path)}`,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: this.projectShortPath,
|
name: this.projectShortPath,
|
||||||
path: '/',
|
path: '/',
|
||||||
to: `/-/tree/${escapeFileUrl(this.ref)}/`,
|
to: `/-/tree/${this.escapedRef}/`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
|
@ -81,7 +81,7 @@ export default {
|
||||||
<tbody>
|
<tbody>
|
||||||
<parent-row
|
<parent-row
|
||||||
v-show="showParentRow"
|
v-show="showParentRow"
|
||||||
:commit-ref="ref"
|
:commit-ref="escapedRef"
|
||||||
:path="path"
|
:path="path"
|
||||||
:loading-path="loadingPath"
|
:loading-path="loadingPath"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlLoadingIcon } from '@gitlab/ui';
|
import { GlLoadingIcon } from '@gitlab/ui';
|
||||||
import { escapeFileUrl } from '~/lib/utils/url_utility';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -29,7 +28,7 @@ export default {
|
||||||
return splitArray.map(p => encodeURIComponent(p)).join('/');
|
return splitArray.map(p => encodeURIComponent(p)).join('/');
|
||||||
},
|
},
|
||||||
parentRoute() {
|
parentRoute() {
|
||||||
return { path: `/-/tree/${escapeFileUrl(this.commitRef)}/${this.parentPath}` };
|
return { path: `/-/tree/${this.commitRef}/${this.parentPath}` };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -99,7 +99,7 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
routerLinkTo() {
|
routerLinkTo() {
|
||||||
return this.isFolder
|
return this.isFolder
|
||||||
? { path: `/-/tree/${escapeFileUrl(this.ref)}/${escapeFileUrl(this.path)}` }
|
? { path: `/-/tree/${this.escapedRef}/${escapeFileUrl(this.path)}` }
|
||||||
: null;
|
: null;
|
||||||
},
|
},
|
||||||
isFolder() {
|
isFolder() {
|
||||||
|
|
|
@ -15,14 +15,15 @@ import { __ } from '../locale';
|
||||||
export default function setupVueRepositoryList() {
|
export default function setupVueRepositoryList() {
|
||||||
const el = document.getElementById('js-tree-list');
|
const el = document.getElementById('js-tree-list');
|
||||||
const { dataset } = el;
|
const { dataset } = el;
|
||||||
const { projectPath, projectShortPath, ref, fullName } = dataset;
|
const { projectPath, projectShortPath, ref, escapedRef, fullName } = dataset;
|
||||||
const router = createRouter(projectPath, ref);
|
const router = createRouter(projectPath, escapedRef);
|
||||||
|
|
||||||
apolloProvider.clients.defaultClient.cache.writeData({
|
apolloProvider.clients.defaultClient.cache.writeData({
|
||||||
data: {
|
data: {
|
||||||
projectPath,
|
projectPath,
|
||||||
projectShortPath,
|
projectShortPath,
|
||||||
ref,
|
ref,
|
||||||
|
escapedRef,
|
||||||
vueFileListLfsBadge: gon.features?.vueFileListLfsBadge || false,
|
vueFileListLfsBadge: gon.features?.vueFileListLfsBadge || false,
|
||||||
commits: [],
|
commits: [],
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,13 +23,13 @@ export function fetchLogsTree(client, path, offset, resolver = null) {
|
||||||
if (fetchpromise) return fetchpromise;
|
if (fetchpromise) return fetchpromise;
|
||||||
|
|
||||||
const { projectPath } = client.readQuery({ query: getProjectPath });
|
const { projectPath } = client.readQuery({ query: getProjectPath });
|
||||||
const { ref } = client.readQuery({ query: getRef });
|
const { escapedRef } = client.readQuery({ query: getRef });
|
||||||
|
|
||||||
fetchpromise = axios
|
fetchpromise = axios
|
||||||
.get(
|
.get(
|
||||||
`${gon.relative_url_root}/${projectPath}/-/refs/${encodeURIComponent(
|
`${gon.relative_url_root}/${projectPath}/-/refs/${escapedRef}/logs_tree/${encodeURIComponent(
|
||||||
ref,
|
path.replace(/^\//, ''),
|
||||||
)}/logs_tree/${encodeURIComponent(path.replace(/^\//, ''))}`,
|
)}`,
|
||||||
{
|
{
|
||||||
params: { format: 'json', offset },
|
params: { format: 'json', offset },
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,11 +4,19 @@ export default {
|
||||||
apollo: {
|
apollo: {
|
||||||
ref: {
|
ref: {
|
||||||
query: getRef,
|
query: getRef,
|
||||||
|
manual: true,
|
||||||
|
result({ data, loading }) {
|
||||||
|
if (!loading) {
|
||||||
|
this.ref = data.ref;
|
||||||
|
this.escapedRef = data.escapedRef;
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ref: '',
|
ref: '',
|
||||||
|
escapedRef: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
query getRef {
|
query getRef {
|
||||||
ref @client
|
ref @client
|
||||||
|
escapedRef @client
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ export default function createRouter(base, baseRef) {
|
||||||
base: joinPaths(gon.relative_url_root || '', base),
|
base: joinPaths(gon.relative_url_root || '', base),
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: `(/-)?/tree/(${encodeURIComponent(baseRef).replace(/%2F/g, '/')}|${baseRef})/:path*`,
|
path: `(/-)?/tree/${baseRef}/:path*`,
|
||||||
name: 'treePath',
|
name: 'treePath',
|
||||||
component: TreePage,
|
component: TreePage,
|
||||||
props: route => ({
|
props: route => ({
|
||||||
|
|
|
@ -497,7 +497,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_visibility_restricted?
|
def public_visibility_restricted?
|
||||||
Gitlab::CurrentSettings.restricted_visibility_levels.include? Gitlab::VisibilityLevel::PUBLIC
|
Gitlab::VisibilityLevel.public_visibility_restricted?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_usage_stats_consent_flag
|
def set_usage_stats_consent_flag
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Projects::DeployKeysController < Projects::ApplicationController
|
class Projects::DeployKeysController < Projects::ApplicationController
|
||||||
|
include RepositorySettingsRedirect
|
||||||
respond_to :html
|
respond_to :html
|
||||||
|
|
||||||
# Authorize
|
# Authorize
|
||||||
|
@ -11,7 +12,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to_ci_cd_settings }
|
format.html { redirect_to_repository }
|
||||||
format.json do
|
format.json do
|
||||||
render json: Projects::Settings::DeployKeysPresenter.new(@project, current_user: current_user).as_json
|
render json: Projects::Settings::DeployKeysPresenter.new(@project, current_user: current_user).as_json
|
||||||
end
|
end
|
||||||
|
@ -19,7 +20,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
redirect_to_ci_cd_settings
|
redirect_to_repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -29,7 +30,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||||
flash[:alert] = @key.errors.full_messages.join(', ').html_safe
|
flash[:alert] = @key.errors.full_messages.join(', ').html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to_ci_cd_settings
|
redirect_to_repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
@ -38,7 +39,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||||
def update
|
def update
|
||||||
if deploy_key.update(update_params)
|
if deploy_key.update(update_params)
|
||||||
flash[:notice] = _('Deploy key was successfully updated.')
|
flash[:notice] = _('Deploy key was successfully updated.')
|
||||||
redirect_to_ci_cd_settings
|
redirect_to_repository
|
||||||
else
|
else
|
||||||
render 'edit'
|
render 'edit'
|
||||||
end
|
end
|
||||||
|
@ -50,7 +51,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||||
return render_404 unless key
|
return render_404 unless key
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to_ci_cd_settings }
|
format.html { redirect_to_repository }
|
||||||
format.json { head :ok }
|
format.json { head :ok }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -61,7 +62,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||||
return render_404 unless deploy_key_project
|
return render_404 unless deploy_key_project
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to_ci_cd_settings }
|
format.html { redirect_to_repository }
|
||||||
format.json { head :ok }
|
format.json { head :ok }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -97,7 +98,9 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def redirect_to_ci_cd_settings
|
private
|
||||||
redirect_to project_settings_ci_cd_path(@project, anchor: 'js-deploy-keys-settings')
|
|
||||||
|
def redirect_to_repository
|
||||||
|
redirect_to_repository_settings(@project, anchor: 'js-deploy-keys-settings')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,10 @@ class Projects::RefsController < Projects::ApplicationController
|
||||||
before_action :assign_ref_vars
|
before_action :assign_ref_vars
|
||||||
before_action :authorize_download_code!
|
before_action :authorize_download_code!
|
||||||
|
|
||||||
|
before_action only: [:logs_tree] do
|
||||||
|
push_frontend_feature_flag(:vue_file_list_lfs_badge)
|
||||||
|
end
|
||||||
|
|
||||||
def switch
|
def switch
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
|
|
|
@ -88,7 +88,6 @@ module Projects
|
||||||
define_triggers_variables
|
define_triggers_variables
|
||||||
define_badges_variables
|
define_badges_variables
|
||||||
define_auto_devops_variables
|
define_auto_devops_variables
|
||||||
define_deploy_keys
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def define_runners_variables
|
def define_runners_variables
|
||||||
|
@ -135,10 +134,6 @@ module Projects
|
||||||
def define_auto_devops_variables
|
def define_auto_devops_variables
|
||||||
@auto_devops = @project.auto_devops || ProjectAutoDevops.new
|
@auto_devops = @project.auto_devops || ProjectAutoDevops.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def define_deploy_keys
|
|
||||||
@deploy_keys = DeployKeysPresenter.new(@project, current_user: current_user)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -63,6 +63,8 @@ module Projects
|
||||||
end
|
end
|
||||||
|
|
||||||
def define_variables
|
def define_variables
|
||||||
|
@deploy_keys = DeployKeysPresenter.new(@project, current_user: current_user)
|
||||||
|
|
||||||
define_deploy_token_variables
|
define_deploy_token_variables
|
||||||
define_protected_refs
|
define_protected_refs
|
||||||
remote_mirror
|
remote_mirror
|
||||||
|
|
|
@ -52,7 +52,7 @@ module ExploreHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_visibility_restricted?
|
def public_visibility_restricted?
|
||||||
Gitlab::CurrentSettings.restricted_visibility_levels&.include? Gitlab::VisibilityLevel::PUBLIC
|
Gitlab::VisibilityLevel.public_visibility_restricted?
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -194,6 +194,7 @@ module TreeHelper
|
||||||
project_path: project.full_path,
|
project_path: project.full_path,
|
||||||
project_short_path: project.path,
|
project_short_path: project.path,
|
||||||
ref: ref,
|
ref: ref,
|
||||||
|
escaped_ref: ActionDispatch::Journey::Router::Utils.escape_path(ref),
|
||||||
full_name: project.name_with_namespace
|
full_name: project.name_with_namespace
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -982,6 +982,8 @@ module Ci
|
||||||
|
|
||||||
jwt = Gitlab::Ci::Jwt.for_build(self)
|
jwt = Gitlab::Ci::Jwt.for_build(self)
|
||||||
variables.append(key: 'CI_JOB_JWT', value: jwt, public: false, masked: true)
|
variables.append(key: 'CI_JOB_JWT', value: jwt, public: false, masked: true)
|
||||||
|
rescue OpenSSL::PKey::RSAError => e
|
||||||
|
Gitlab::ErrorTracking.track_exception(e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,6 +17,7 @@ module Discussions
|
||||||
return unless result
|
return unless result
|
||||||
|
|
||||||
position = result[:position]
|
position = result[:position]
|
||||||
|
return unless position
|
||||||
|
|
||||||
# Currently position data is copied across all notes of a discussion
|
# Currently position data is copied across all notes of a discussion
|
||||||
# It makes sense to store a position only for the first note instead
|
# It makes sense to store a position only for the first note instead
|
||||||
|
|
|
@ -173,6 +173,10 @@ module Projects
|
||||||
def create_prometheus_service
|
def create_prometheus_service
|
||||||
service = @project.find_or_initialize_service(::PrometheusService.to_param)
|
service = @project.find_or_initialize_service(::PrometheusService.to_param)
|
||||||
|
|
||||||
|
# If the service has already been inserted in the database, that
|
||||||
|
# means it came from a template, and there's nothing more to do.
|
||||||
|
return if service.persisted?
|
||||||
|
|
||||||
if service.prometheus_available?
|
if service.prometheus_available?
|
||||||
service.save!
|
service.save!
|
||||||
else
|
else
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
.mobile-overlay
|
.mobile-overlay
|
||||||
.alert-wrapper
|
.alert-wrapper
|
||||||
= render 'shared/outdated_browser'
|
= render 'shared/outdated_browser'
|
||||||
- if Feature.enabled?(:subscribable_banner_license)
|
- if Feature.enabled?(:subscribable_banner_license, default_enabled: true)
|
||||||
= render_if_exists "layouts/header/ee_subscribable_banner"
|
= render_if_exists "layouts/header/ee_subscribable_banner"
|
||||||
= render "layouts/broadcast"
|
= render "layouts/broadcast"
|
||||||
= render "layouts/header/read_only_banner"
|
= render "layouts/header/read_only_banner"
|
||||||
|
|
|
@ -4,22 +4,21 @@
|
||||||
|
|
||||||
- commits = @commits
|
- commits = @commits
|
||||||
- hidden = @hidden_commit_count
|
- hidden = @hidden_commit_count
|
||||||
- commits_count = @commits.size
|
|
||||||
|
|
||||||
- commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, commits|
|
- commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, daily_commits|
|
||||||
%li.commit-header.js-commit-header{ data: { day: day } }
|
%li.commit-header.js-commit-header{ data: { day: day } }
|
||||||
%span.day= l(day, format: '%d %b, %Y')
|
%span.day= l(day, format: '%d %b, %Y')
|
||||||
%span.commits-count= n_("%d commit", "%d commits", commits_count) % commits_count
|
%span.commits-count= n_("%d commit", "%d commits", daily_commits.size) % daily_commits.size
|
||||||
|
|
||||||
%li.commits-row{ data: { day: day } }
|
%li.commits-row{ data: { day: day } }
|
||||||
%ul.content-list.commit-list.flex-list
|
%ul.content-list.commit-list.flex-list
|
||||||
= render partial: 'projects/commits/commit', collection: commits, locals: { project: project, ref: ref, merge_request: merge_request }
|
= render partial: 'projects/commits/commit', collection: daily_commits, locals: { project: project, ref: ref, merge_request: merge_request }
|
||||||
|
|
||||||
- if hidden > 0
|
- if hidden > 0
|
||||||
%li.alert.alert-warning
|
%li.alert.alert-warning
|
||||||
= n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden)
|
= n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden)
|
||||||
|
|
||||||
- if commits_count == 0
|
- if commits.size == 0
|
||||||
.mt-4.text-center
|
.mt-4.text-center
|
||||||
.bold
|
.bold
|
||||||
= _('Your search didn\'t match any commits.')
|
= _('Your search didn\'t match any commits.')
|
||||||
|
|
|
@ -51,8 +51,6 @@
|
||||||
.settings-content
|
.settings-content
|
||||||
= render 'ci/variables/index', save_endpoint: project_variables_path(@project)
|
= render 'ci/variables/index', save_endpoint: project_variables_path(@project)
|
||||||
|
|
||||||
= render @deploy_keys
|
|
||||||
|
|
||||||
%section.settings.no-animate#js-pipeline-triggers{ class: ('expanded' if expanded) }
|
%section.settings.no-animate#js-pipeline-triggers{ class: ('expanded' if expanded) }
|
||||||
.settings-header
|
.settings-header
|
||||||
%h4
|
%h4
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
-# reused in EE.
|
-# reused in EE.
|
||||||
= render "projects/settings/repository/protected_branches"
|
= render "projects/settings/repository/protected_branches"
|
||||||
= render "shared/deploy_tokens/index", group_or_project: @project, description: deploy_token_description
|
= render "shared/deploy_tokens/index", group_or_project: @project, description: deploy_token_description
|
||||||
|
= render @deploy_keys
|
||||||
= render "projects/cleanup/show"
|
= render "projects/cleanup/show"
|
||||||
|
|
||||||
= render_if_exists 'shared/promotions/promote_repository_features'
|
= render_if_exists 'shared/promotions/promote_repository_features'
|
||||||
|
|
|
@ -52,6 +52,9 @@ Rails.application.configure do
|
||||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
||||||
config.action_controller.asset_host = ENV['GITLAB_CDN_HOST'] if ENV['GITLAB_CDN_HOST'].present?
|
config.action_controller.asset_host = ENV['GITLAB_CDN_HOST'] if ENV['GITLAB_CDN_HOST'].present?
|
||||||
|
|
||||||
|
# Do not dump schema after migrations.
|
||||||
|
config.active_record.dump_schema_after_migration = false
|
||||||
|
|
||||||
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
||||||
# config.assets.precompile += %w( search.js )
|
# config.assets.precompile += %w( search.js )
|
||||||
|
|
||||||
|
|
|
@ -312,8 +312,8 @@ GET /projects?custom_attributes[key]=value&custom_attributes[other_key]=other_va
|
||||||
|
|
||||||
### Pagination limits
|
### Pagination limits
|
||||||
|
|
||||||
From GitLab 12.10, [offset-based pagination](README.md#offset-based-pagination) will be
|
From GitLab 13.0, [offset-based pagination](README.md#offset-based-pagination) will be
|
||||||
[limited to 10,000 records](https://gitlab.com/gitlab-org/gitlab/issues/34565).
|
[limited to 50,000 records](https://gitlab.com/gitlab-org/gitlab/issues/34565).
|
||||||
[Keyset pagination](README.md#keyset-based-pagination) will be required to retrieve projects
|
[Keyset pagination](README.md#keyset-based-pagination) will be required to retrieve projects
|
||||||
beyond this limit.
|
beyond this limit.
|
||||||
|
|
||||||
|
|
|
@ -288,14 +288,6 @@ https://example.gitlab.com/<namespace>/<project>/badges/<branch>/coverage.svg?st
|
||||||
|
|
||||||
[Environment variables](../variables/README.md#gitlab-cicd-environment-variables) can be set in an environment to be available to a runner.
|
[Environment variables](../variables/README.md#gitlab-cicd-environment-variables) can be set in an environment to be available to a runner.
|
||||||
|
|
||||||
## Deploy Keys
|
|
||||||
|
|
||||||
With Deploy Keys, GitLab allows you to import SSH public keys. You can then have
|
|
||||||
read only or read/write access to your project from the machines the keys were generated from.
|
|
||||||
|
|
||||||
SSH keys added to your project settings will be used for continuous integration,
|
|
||||||
staging, or production servers.
|
|
||||||
|
|
||||||
<!-- ## Troubleshooting
|
<!-- ## Troubleshooting
|
||||||
|
|
||||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||||
|
|
|
@ -384,9 +384,7 @@ If you don't have a key pair, you might want to use a
|
||||||
|
|
||||||
Project maintainers and owners can add a deploy key for a repository.
|
Project maintainers and owners can add a deploy key for a repository.
|
||||||
|
|
||||||
1. Navigate to the project's **Settings** page, then:
|
1. Navigate to the project's **Settings > Repository** page.
|
||||||
- On GitLab 12.8 and earlier, click **Repository**.
|
|
||||||
- On GitLab 12.9 and later, click **CI / CD**.
|
|
||||||
1. Expand the **Deploy Keys** section.
|
1. Expand the **Deploy Keys** section.
|
||||||
1. Specify a title for the new deploy key and paste a public SSH key.
|
1. Specify a title for the new deploy key and paste a public SSH key.
|
||||||
|
|
||||||
|
@ -432,9 +430,7 @@ your repository".
|
||||||
Once a GitLab administrator adds the Global Deployment key, project maintainers
|
Once a GitLab administrator adds the Global Deployment key, project maintainers
|
||||||
and owners can add it by:
|
and owners can add it by:
|
||||||
|
|
||||||
1. Navigating the settings page:
|
1. Navigate to the project's **Settings > Repository** page.
|
||||||
- On GitLab 12.8 and earlier, the project's **Settings > Repository** page.
|
|
||||||
- On GitLab 12.9 and later, the project's **Settings > CI / CD** page.
|
|
||||||
1. Expanding the **Deploy Keys** section.
|
1. Expanding the **Deploy Keys** section.
|
||||||
1. Clicking **Enable** next to the appropriate key listed under
|
1. Clicking **Enable** next to the appropriate key listed under
|
||||||
**Public deploy keys available to any project**.
|
**Public deploy keys available to any project**.
|
||||||
|
|
|
@ -9,6 +9,23 @@ is a performance optimization that "allows Git to function without having a
|
||||||
complete copy of the repository. The goal of this work is to allow Git better
|
complete copy of the repository. The goal of this work is to allow Git better
|
||||||
handle extremely large repositories."
|
handle extremely large repositories."
|
||||||
|
|
||||||
|
## Enabling partial clone
|
||||||
|
|
||||||
|
> [Introduced](https://gitlab.com/gitlab-org/gitaly/issues/1553) in GitLab 12.4.
|
||||||
|
|
||||||
|
To enable partial clone, use the [feature flags API](../../api/features.md).
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --data "value=true" --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/features/gitaly_upload_pack_filter
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, flip the switch and enable the feature flag:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Feature.enable(:gitaly_upload_pack_filter)
|
||||||
|
```
|
||||||
|
|
||||||
## Filter by file size
|
## Filter by file size
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/2553) in GitLab 12.10.
|
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/2553) in GitLab 12.10.
|
||||||
|
|
|
@ -46,7 +46,7 @@ module API
|
||||||
desc 'Add a new terraform state or update an existing one'
|
desc 'Add a new terraform state or update an existing one'
|
||||||
route_setting :authentication, basic_auth_personal_access_token: true
|
route_setting :authentication, basic_auth_personal_access_token: true
|
||||||
post do
|
post do
|
||||||
data = request.body.string
|
data = request.body.read
|
||||||
no_content! if data.empty?
|
no_content! if data.empty?
|
||||||
|
|
||||||
remote_state_handler.handle_with_lock do |state|
|
remote_state_handler.handle_with_lock do |state|
|
||||||
|
|
|
@ -82,15 +82,23 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def non_restricted_level?(level)
|
def non_restricted_level?(level)
|
||||||
|
!restricted_level?(level)
|
||||||
|
end
|
||||||
|
|
||||||
|
def restricted_level?(level)
|
||||||
restricted_levels = Gitlab::CurrentSettings.restricted_visibility_levels
|
restricted_levels = Gitlab::CurrentSettings.restricted_visibility_levels
|
||||||
|
|
||||||
if restricted_levels.nil?
|
if restricted_levels.nil?
|
||||||
true
|
false
|
||||||
else
|
else
|
||||||
!restricted_levels.include?(level)
|
restricted_levels.include?(level)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def public_visibility_restricted?
|
||||||
|
restricted_level?(PUBLIC)
|
||||||
|
end
|
||||||
|
|
||||||
def valid_level?(level)
|
def valid_level?(level)
|
||||||
options.value?(level)
|
options.value?(level)
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,16 +13,6 @@ module QA
|
||||||
element :variables_settings_content
|
element :variables_settings_content
|
||||||
end
|
end
|
||||||
|
|
||||||
view 'app/views/projects/deploy_keys/_index.html.haml' do
|
|
||||||
element :deploy_keys_settings
|
|
||||||
end
|
|
||||||
|
|
||||||
def expand_deploy_keys(&block)
|
|
||||||
expand_section(:deploy_keys_settings) do
|
|
||||||
Settings::DeployKeys.perform(&block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def expand_runners_settings(&block)
|
def expand_runners_settings(&block)
|
||||||
expand_section(:runners_settings_content) do
|
expand_section(:runners_settings_content) do
|
||||||
Settings::Runners.perform(&block)
|
Settings::Runners.perform(&block)
|
||||||
|
|
|
@ -19,12 +19,22 @@ module QA
|
||||||
element :deploy_tokens_settings
|
element :deploy_tokens_settings
|
||||||
end
|
end
|
||||||
|
|
||||||
|
view 'app/views/projects/deploy_keys/_index.html.haml' do
|
||||||
|
element :deploy_keys_settings
|
||||||
|
end
|
||||||
|
|
||||||
def expand_deploy_tokens(&block)
|
def expand_deploy_tokens(&block)
|
||||||
expand_section(:deploy_tokens_settings) do
|
expand_section(:deploy_tokens_settings) do
|
||||||
Settings::DeployTokens.perform(&block)
|
Settings::DeployTokens.perform(&block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def expand_deploy_keys(&block)
|
||||||
|
expand_section(:deploy_keys_settings) do
|
||||||
|
Settings::DeployKeys.perform(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def expand_protected_branches(&block)
|
def expand_protected_branches(&block)
|
||||||
expand_section(:protected_branches_settings) do
|
expand_section(:protected_branches_settings) do
|
||||||
ProtectedBranches.perform(&block)
|
ProtectedBranches.perform(&block)
|
||||||
|
|
|
@ -6,7 +6,7 @@ module QA
|
||||||
attr_accessor :title, :key
|
attr_accessor :title, :key
|
||||||
|
|
||||||
attribute :md5_fingerprint do
|
attribute :md5_fingerprint do
|
||||||
Page::Project::Settings::CICD.perform do |setting|
|
Page::Project::Settings::Repository.perform do |setting|
|
||||||
setting.expand_deploy_keys do |key|
|
setting.expand_deploy_keys do |key|
|
||||||
key.find_md5_fingerprint(title)
|
key.find_md5_fingerprint(title)
|
||||||
end
|
end
|
||||||
|
@ -23,9 +23,9 @@ module QA
|
||||||
def fabricate!
|
def fabricate!
|
||||||
project.visit!
|
project.visit!
|
||||||
|
|
||||||
Page::Project::Menu.perform(&:go_to_ci_cd_settings)
|
Page::Project::Menu.perform(&:go_to_repository_settings)
|
||||||
|
|
||||||
Page::Project::Settings::CICD.perform do |setting|
|
Page::Project::Settings::Repository.perform do |setting|
|
||||||
setting.expand_deploy_keys do |page|
|
setting.expand_deploy_keys do |page|
|
||||||
page.fill_key_title(title)
|
page.fill_key_title(title)
|
||||||
page.fill_key_value(key)
|
page.fill_key_value(key)
|
||||||
|
|
|
@ -17,7 +17,7 @@ module QA
|
||||||
|
|
||||||
expect(deploy_key.md5_fingerprint).to eq key.md5_fingerprint
|
expect(deploy_key.md5_fingerprint).to eq key.md5_fingerprint
|
||||||
|
|
||||||
Page::Project::Settings::CICD.perform do |setting|
|
Page::Project::Settings::Repository.perform do |setting|
|
||||||
setting.expand_deploy_keys do |keys|
|
setting.expand_deploy_keys do |keys|
|
||||||
expect(keys).to have_key(deploy_key_title, key.md5_fingerprint)
|
expect(keys).to have_key(deploy_key_title, key.md5_fingerprint)
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,10 +19,10 @@ describe Projects::DeployKeysController do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when html requested' do
|
context 'when html requested' do
|
||||||
it 'redirects to project ci / cd settings with the correct anchor' do
|
it 'redirects to project settings with the correct anchor' do
|
||||||
get :index, params: params
|
get :index, params: params
|
||||||
|
|
||||||
expect(response).to redirect_to(project_settings_ci_cd_path(project, anchor: 'js-deploy-keys-settings'))
|
expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -87,13 +87,13 @@ describe Projects::DeployKeysController do
|
||||||
it 'creates a new deploy key for the project' do
|
it 'creates a new deploy key for the project' do
|
||||||
expect { post :create, params: create_params }.to change(project.deploy_keys, :count).by(1)
|
expect { post :create, params: create_params }.to change(project.deploy_keys, :count).by(1)
|
||||||
|
|
||||||
expect(response).to redirect_to(project_settings_ci_cd_path(project, anchor: 'js-deploy-keys-settings'))
|
expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'redirects to project settings with the correct anchor' do
|
it 'redirects to project settings with the correct anchor' do
|
||||||
post :create, params: create_params
|
post :create, params: create_params
|
||||||
|
|
||||||
expect(response).to redirect_to(project_settings_ci_cd_path(project, anchor: 'js-deploy-keys-settings'))
|
expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the deploy key is invalid' do
|
context 'when the deploy key is invalid' do
|
||||||
|
@ -153,7 +153,7 @@ describe Projects::DeployKeysController do
|
||||||
|
|
||||||
expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
|
expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
|
||||||
expect(response).to have_gitlab_http_status(:found)
|
expect(response).to have_gitlab_http_status(:found)
|
||||||
expect(response).to redirect_to(namespace_project_settings_ci_cd_path(anchor: 'js-deploy-keys-settings'))
|
expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns 404' do
|
it 'returns 404' do
|
||||||
|
@ -175,7 +175,7 @@ describe Projects::DeployKeysController do
|
||||||
|
|
||||||
expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
|
expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
|
||||||
expect(response).to have_gitlab_http_status(:found)
|
expect(response).to have_gitlab_http_status(:found)
|
||||||
expect(response).to redirect_to(namespace_project_settings_ci_cd_path(anchor: 'js-deploy-keys-settings'))
|
expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -216,7 +216,7 @@ describe Projects::DeployKeysController do
|
||||||
put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
|
put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(:found)
|
expect(response).to have_gitlab_http_status(:found)
|
||||||
expect(response).to redirect_to(namespace_project_settings_ci_cd_path(anchor: 'js-deploy-keys-settings'))
|
expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
|
||||||
|
|
||||||
expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||||
end
|
end
|
||||||
|
@ -239,7 +239,7 @@ describe Projects::DeployKeysController do
|
||||||
end.to change { DeployKey.count }.by(-1)
|
end.to change { DeployKey.count }.by(-1)
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(:found)
|
expect(response).to have_gitlab_http_status(:found)
|
||||||
expect(response).to redirect_to(namespace_project_settings_ci_cd_path(anchor: 'js-deploy-keys-settings'))
|
expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
|
||||||
|
|
||||||
expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,7 @@ describe 'Project deploy keys', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'removes association between project and deploy key' do
|
it 'removes association between project and deploy key' do
|
||||||
visit project_settings_ci_cd_path(project)
|
visit project_settings_repository_path(project)
|
||||||
|
|
||||||
page.within(find('.qa-deploy-keys-settings')) do
|
page.within(find('.qa-deploy-keys-settings')) do
|
||||||
expect(page).to have_selector('.deploy-key', count: 1)
|
expect(page).to have_selector('.deploy-key', count: 1)
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe 'Projects > Settings > CI / CD settings' do
|
|
||||||
let_it_be(:project) { create(:project_empty_repo) }
|
|
||||||
let_it_be(:user) { create(:user) }
|
|
||||||
let_it_be(:role) { :maintainer }
|
|
||||||
|
|
||||||
context 'Deploy Keys', :js do
|
|
||||||
let_it_be(:private_deploy_key) { create(:deploy_key, title: 'private_deploy_key', public: false) }
|
|
||||||
let_it_be(:public_deploy_key) { create(:another_deploy_key, title: 'public_deploy_key', public: true) }
|
|
||||||
let(:new_ssh_key) { attributes_for(:key)[:key] }
|
|
||||||
|
|
||||||
before do
|
|
||||||
project.add_role(user, role)
|
|
||||||
sign_in(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'get list of keys' do
|
|
||||||
project.deploy_keys << private_deploy_key
|
|
||||||
project.deploy_keys << public_deploy_key
|
|
||||||
|
|
||||||
visit project_settings_ci_cd_path(project)
|
|
||||||
|
|
||||||
expect(page).to have_content('private_deploy_key')
|
|
||||||
expect(page).to have_content('public_deploy_key')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'add a new deploy key' do
|
|
||||||
visit project_settings_ci_cd_path(project)
|
|
||||||
|
|
||||||
fill_in 'deploy_key_title', with: 'new_deploy_key'
|
|
||||||
fill_in 'deploy_key_key', with: new_ssh_key
|
|
||||||
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
|
|
||||||
click_button 'Add key'
|
|
||||||
|
|
||||||
expect(page).to have_content('new_deploy_key')
|
|
||||||
expect(page).to have_content('Write access allowed')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'edit an existing deploy key' do
|
|
||||||
project.deploy_keys << private_deploy_key
|
|
||||||
visit project_settings_ci_cd_path(project)
|
|
||||||
|
|
||||||
find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click
|
|
||||||
|
|
||||||
fill_in 'deploy_key_title', with: 'updated_deploy_key'
|
|
||||||
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
|
|
||||||
click_button 'Save changes'
|
|
||||||
|
|
||||||
expect(page).to have_content('updated_deploy_key')
|
|
||||||
expect(page).to have_content('Write access allowed')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'edit an existing public deploy key to be writable' do
|
|
||||||
project.deploy_keys << public_deploy_key
|
|
||||||
visit project_settings_ci_cd_path(project)
|
|
||||||
|
|
||||||
find('.deploy-key', text: public_deploy_key.title).find('.ic-pencil').click
|
|
||||||
|
|
||||||
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
|
|
||||||
click_button 'Save changes'
|
|
||||||
|
|
||||||
expect(page).to have_content('public_deploy_key')
|
|
||||||
expect(page).to have_content('Write access allowed')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'edit a deploy key from projects user has access to' do
|
|
||||||
project2 = create(:project_empty_repo)
|
|
||||||
project2.add_role(user, role)
|
|
||||||
project2.deploy_keys << private_deploy_key
|
|
||||||
|
|
||||||
visit project_settings_ci_cd_path(project)
|
|
||||||
|
|
||||||
find('.js-deployKeys-tab-available_project_keys').click
|
|
||||||
|
|
||||||
find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click
|
|
||||||
|
|
||||||
fill_in 'deploy_key_title', with: 'updated_deploy_key'
|
|
||||||
click_button 'Save changes'
|
|
||||||
|
|
||||||
find('.js-deployKeys-tab-available_project_keys').click
|
|
||||||
|
|
||||||
expect(page).to have_content('updated_deploy_key')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'remove an existing deploy key' do
|
|
||||||
project.deploy_keys << private_deploy_key
|
|
||||||
visit project_settings_ci_cd_path(project)
|
|
||||||
|
|
||||||
accept_confirm { find('.deploy-key', text: private_deploy_key.title).find('.ic-remove').click }
|
|
||||||
|
|
||||||
expect(page).not_to have_content(private_deploy_key.title)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -39,6 +39,89 @@ describe 'Projects > Settings > Repository settings' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'Deploy Keys', :js do
|
||||||
|
let_it_be(:private_deploy_key) { create(:deploy_key, title: 'private_deploy_key', public: false) }
|
||||||
|
let_it_be(:public_deploy_key) { create(:another_deploy_key, title: 'public_deploy_key', public: true) }
|
||||||
|
let(:new_ssh_key) { attributes_for(:key)[:key] }
|
||||||
|
|
||||||
|
it 'get list of keys' do
|
||||||
|
project.deploy_keys << private_deploy_key
|
||||||
|
project.deploy_keys << public_deploy_key
|
||||||
|
|
||||||
|
visit project_settings_repository_path(project)
|
||||||
|
|
||||||
|
expect(page).to have_content('private_deploy_key')
|
||||||
|
expect(page).to have_content('public_deploy_key')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'add a new deploy key' do
|
||||||
|
visit project_settings_repository_path(project)
|
||||||
|
|
||||||
|
fill_in 'deploy_key_title', with: 'new_deploy_key'
|
||||||
|
fill_in 'deploy_key_key', with: new_ssh_key
|
||||||
|
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
|
||||||
|
click_button 'Add key'
|
||||||
|
|
||||||
|
expect(page).to have_content('new_deploy_key')
|
||||||
|
expect(page).to have_content('Write access allowed')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'edit an existing deploy key' do
|
||||||
|
project.deploy_keys << private_deploy_key
|
||||||
|
visit project_settings_repository_path(project)
|
||||||
|
|
||||||
|
find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click
|
||||||
|
|
||||||
|
fill_in 'deploy_key_title', with: 'updated_deploy_key'
|
||||||
|
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
|
||||||
|
click_button 'Save changes'
|
||||||
|
|
||||||
|
expect(page).to have_content('updated_deploy_key')
|
||||||
|
expect(page).to have_content('Write access allowed')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'edit an existing public deploy key to be writable' do
|
||||||
|
project.deploy_keys << public_deploy_key
|
||||||
|
visit project_settings_repository_path(project)
|
||||||
|
|
||||||
|
find('.deploy-key', text: public_deploy_key.title).find('.ic-pencil').click
|
||||||
|
|
||||||
|
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
|
||||||
|
click_button 'Save changes'
|
||||||
|
|
||||||
|
expect(page).to have_content('public_deploy_key')
|
||||||
|
expect(page).to have_content('Write access allowed')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'edit a deploy key from projects user has access to' do
|
||||||
|
project2 = create(:project_empty_repo)
|
||||||
|
project2.add_role(user, role)
|
||||||
|
project2.deploy_keys << private_deploy_key
|
||||||
|
|
||||||
|
visit project_settings_repository_path(project)
|
||||||
|
|
||||||
|
find('.js-deployKeys-tab-available_project_keys').click
|
||||||
|
|
||||||
|
find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click
|
||||||
|
|
||||||
|
fill_in 'deploy_key_title', with: 'updated_deploy_key'
|
||||||
|
click_button 'Save changes'
|
||||||
|
|
||||||
|
find('.js-deployKeys-tab-available_project_keys').click
|
||||||
|
|
||||||
|
expect(page).to have_content('updated_deploy_key')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'remove an existing deploy key' do
|
||||||
|
project.deploy_keys << private_deploy_key
|
||||||
|
visit project_settings_repository_path(project)
|
||||||
|
|
||||||
|
accept_confirm { find('.deploy-key', text: private_deploy_key.title).find('.ic-remove').click }
|
||||||
|
|
||||||
|
expect(page).not_to have_content(private_deploy_key.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'remote mirror settings' do
|
context 'remote mirror settings' do
|
||||||
before do
|
before do
|
||||||
visit project_settings_repository_path(project)
|
visit project_settings_repository_path(project)
|
||||||
|
|
|
@ -20,7 +20,7 @@ describe "User interacts with deploy keys", :js do
|
||||||
click_button("Enable")
|
click_button("Enable")
|
||||||
|
|
||||||
expect(page).not_to have_selector(".fa-spinner")
|
expect(page).not_to have_selector(".fa-spinner")
|
||||||
expect(current_path).to eq(project_settings_ci_cd_path(project))
|
expect(current_path).to eq(project_settings_repository_path(project))
|
||||||
|
|
||||||
find(".js-deployKeys-tab-enabled_keys").click
|
find(".js-deployKeys-tab-enabled_keys").click
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ describe "User interacts with deploy keys", :js do
|
||||||
|
|
||||||
click_button("Add key")
|
click_button("Add key")
|
||||||
|
|
||||||
expect(current_path).to eq(project_settings_ci_cd_path(project))
|
expect(current_path).to eq(project_settings_repository_path(project))
|
||||||
|
|
||||||
page.within(".deploy-keys") do
|
page.within(".deploy-keys") do
|
||||||
expect(page).to have_content(DEPLOY_KEY_TITLE)
|
expect(page).to have_content(DEPLOY_KEY_TITLE)
|
||||||
|
|
|
@ -26,7 +26,7 @@ function factory(propsData = {}) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
vm.setData({ ref: 'master' });
|
vm.setData({ escapedRef: 'master' });
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Repository table row component', () => {
|
describe('Repository table row component', () => {
|
||||||
|
|
|
@ -53,7 +53,7 @@ describe('fetchLogsTree', () => {
|
||||||
client = {
|
client = {
|
||||||
readQuery: () => ({
|
readQuery: () => ({
|
||||||
projectPath: 'gitlab-org/gitlab-foss',
|
projectPath: 'gitlab-org/gitlab-foss',
|
||||||
ref: 'master',
|
escapedRef: 'master',
|
||||||
commits: [],
|
commits: [],
|
||||||
}),
|
}),
|
||||||
writeQuery: jest.fn(),
|
writeQuery: jest.fn(),
|
||||||
|
@ -86,16 +86,18 @@ describe('fetchLogsTree', () => {
|
||||||
|
|
||||||
it('calls entry resolver', () =>
|
it('calls entry resolver', () =>
|
||||||
fetchLogsTree(client, '', '0', resolver).then(() => {
|
fetchLogsTree(client, '', '0', resolver).then(() => {
|
||||||
expect(resolver.resolve).toHaveBeenCalledWith({
|
expect(resolver.resolve).toHaveBeenCalledWith(
|
||||||
__typename: 'LogTreeCommit',
|
expect.objectContaining({
|
||||||
commitPath: 'https://test.com',
|
__typename: 'LogTreeCommit',
|
||||||
committedDate: '2019-01-01',
|
commitPath: 'https://test.com',
|
||||||
fileName: 'index.js',
|
committedDate: '2019-01-01',
|
||||||
filePath: '/index.js',
|
fileName: 'index.js',
|
||||||
message: 'testing message',
|
filePath: '/index.js',
|
||||||
sha: '123',
|
message: 'testing message',
|
||||||
type: 'blob',
|
sha: '123',
|
||||||
});
|
type: 'blob',
|
||||||
|
}),
|
||||||
|
);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('writes query to client', () =>
|
it('writes query to client', () =>
|
||||||
|
@ -104,7 +106,7 @@ describe('fetchLogsTree', () => {
|
||||||
query: expect.anything(),
|
query: expect.anything(),
|
||||||
data: {
|
data: {
|
||||||
commits: [
|
commits: [
|
||||||
{
|
expect.objectContaining({
|
||||||
__typename: 'LogTreeCommit',
|
__typename: 'LogTreeCommit',
|
||||||
commitPath: 'https://test.com',
|
commitPath: 'https://test.com',
|
||||||
committedDate: '2019-01-01',
|
committedDate: '2019-01-01',
|
||||||
|
@ -113,7 +115,7 @@ describe('fetchLogsTree', () => {
|
||||||
message: 'testing message',
|
message: 'testing message',
|
||||||
sha: '123',
|
sha: '123',
|
||||||
type: 'blob',
|
type: 'blob',
|
||||||
},
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,13 +4,12 @@ import createRouter from '~/repository/router';
|
||||||
|
|
||||||
describe('Repository router spec', () => {
|
describe('Repository router spec', () => {
|
||||||
it.each`
|
it.each`
|
||||||
path | branch | component | componentName
|
path | branch | component | componentName
|
||||||
${'/'} | ${'master'} | ${IndexPage} | ${'IndexPage'}
|
${'/'} | ${'master'} | ${IndexPage} | ${'IndexPage'}
|
||||||
${'/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'}
|
${'/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'}
|
||||||
${'/-/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'}
|
${'/-/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'}
|
||||||
${'/-/tree/master/app/assets'} | ${'master'} | ${TreePage} | ${'TreePage'}
|
${'/-/tree/master/app/assets'} | ${'master'} | ${TreePage} | ${'TreePage'}
|
||||||
${'/-/tree/feature/test-%23/app/assets'} | ${'feature/test-#'} | ${TreePage} | ${'TreePage'}
|
${'/-/tree/123/app/assets'} | ${'master'} | ${null} | ${'null'}
|
||||||
${'/-/tree/123/app/assets'} | ${'master'} | ${null} | ${'null'}
|
|
||||||
`('sets component as $componentName for path "$path"', ({ path, component, branch }) => {
|
`('sets component as $componentName for path "$path"', ({ path, component, branch }) => {
|
||||||
const router = createRouter('', branch);
|
const router = createRouter('', branch);
|
||||||
|
|
||||||
|
|
|
@ -19,23 +19,10 @@ describe ExploreHelper do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#public_visibility_restricted?' do
|
describe '#public_visibility_restricted?' do
|
||||||
using RSpec::Parameterized::TableSyntax
|
it 'delegates to Gitlab::VisibilityLevel' do
|
||||||
|
expect(Gitlab::VisibilityLevel).to receive(:public_visibility_restricted?).and_call_original
|
||||||
|
|
||||||
where(:visibility_levels, :expected_status) do
|
helper.public_visibility_restricted?
|
||||||
nil | nil
|
|
||||||
[Gitlab::VisibilityLevel::PRIVATE] | false
|
|
||||||
[Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL] | false
|
|
||||||
[Gitlab::VisibilityLevel::PUBLIC] | true
|
|
||||||
end
|
|
||||||
|
|
||||||
with_them do
|
|
||||||
before do
|
|
||||||
stub_application_setting(restricted_visibility_levels: visibility_levels)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the expected status' do
|
|
||||||
expect(helper.public_visibility_restricted?).to eq(expected_status)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -96,6 +96,30 @@ describe Gitlab::VisibilityLevel do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.restricted_level?, .non_restricted_level?, and .public_level_restricted?' do
|
||||||
|
using RSpec::Parameterized::TableSyntax
|
||||||
|
|
||||||
|
where(:visibility_levels, :expected_status) do
|
||||||
|
nil | false
|
||||||
|
[Gitlab::VisibilityLevel::PRIVATE] | false
|
||||||
|
[Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL] | false
|
||||||
|
[Gitlab::VisibilityLevel::PUBLIC] | true
|
||||||
|
[Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL] | true
|
||||||
|
end
|
||||||
|
|
||||||
|
with_them do
|
||||||
|
before do
|
||||||
|
stub_application_setting(restricted_visibility_levels: visibility_levels)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the expected status' do
|
||||||
|
expect(described_class.restricted_level?(Gitlab::VisibilityLevel::PUBLIC)).to eq(expected_status)
|
||||||
|
expect(described_class.non_restricted_level?(Gitlab::VisibilityLevel::PUBLIC)).to eq(!expected_status)
|
||||||
|
expect(described_class.public_visibility_restricted?).to eq(expected_status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#visibility_level_decreased?' do
|
describe '#visibility_level_decreased?' do
|
||||||
let(:project) { create(:project, :internal) }
|
let(:project) { create(:project, :internal) }
|
||||||
|
|
||||||
|
|
|
@ -2350,6 +2350,16 @@ describe Ci::Build do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when CI_JOB_JWT generation fails' do
|
||||||
|
it 'CI_JOB_JWT is not included' do
|
||||||
|
expect(Gitlab::Ci::Jwt).to receive(:for_build).and_raise(OpenSSL::PKey::RSAError, 'Neither PUB key nor PRIV key: not enough data')
|
||||||
|
expect(Gitlab::ErrorTracking).to receive(:track_exception)
|
||||||
|
|
||||||
|
expect { subject }.not_to raise_error
|
||||||
|
expect(subject.pluck(:key)).not_to include('CI_JOB_JWT')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'variables ordering' do
|
describe 'variables ordering' do
|
||||||
context 'when variables hierarchy is stubbed' do
|
context 'when variables hierarchy is stubbed' do
|
||||||
let(:build_pre_var) { { key: 'build', value: 'value', public: true, masked: false } }
|
let(:build_pre_var) { { key: 'build', value: 'value', public: true, masked: false } }
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Discussions::CaptureDiffNotePositionService do
|
describe Discussions::CaptureDiffNotePositionService do
|
||||||
|
subject { described_class.new(note.noteable, paths) }
|
||||||
|
|
||||||
context 'image note on diff' do
|
context 'image note on diff' do
|
||||||
let!(:note) { create(:image_diff_note_on_merge_request) }
|
let!(:note) { create(:image_diff_note_on_merge_request) }
|
||||||
|
let(:paths) { ['files/images/any_image.png'] }
|
||||||
subject { described_class.new(note.noteable, ['files/images/any_image.png']) }
|
|
||||||
|
|
||||||
it 'is note affected by the service' do
|
it 'is note affected by the service' do
|
||||||
expect(Gitlab::Diff::PositionTracer).not_to receive(:new)
|
expect(Gitlab::Diff::PositionTracer).not_to receive(:new)
|
||||||
|
@ -18,8 +19,7 @@ describe Discussions::CaptureDiffNotePositionService do
|
||||||
|
|
||||||
context 'when empty paths are passed as a param' do
|
context 'when empty paths are passed as a param' do
|
||||||
let!(:note) { create(:diff_note_on_merge_request) }
|
let!(:note) { create(:diff_note_on_merge_request) }
|
||||||
|
let(:paths) { [] }
|
||||||
subject { described_class.new(note.noteable, []) }
|
|
||||||
|
|
||||||
it 'does not calculate positons' do
|
it 'does not calculate positons' do
|
||||||
expect(Gitlab::Diff::PositionTracer).not_to receive(:new)
|
expect(Gitlab::Diff::PositionTracer).not_to receive(:new)
|
||||||
|
@ -28,4 +28,19 @@ describe Discussions::CaptureDiffNotePositionService do
|
||||||
expect(note.diff_note_positions).to be_empty
|
expect(note.diff_note_positions).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when position tracer returned nil position' do
|
||||||
|
let!(:note) { create(:diff_note_on_merge_request) }
|
||||||
|
let(:paths) { ['files/any_file.txt'] }
|
||||||
|
|
||||||
|
it 'does not create diff note position' do
|
||||||
|
expect(note.noteable).to receive(:merge_ref_head).and_return(double.as_null_object)
|
||||||
|
expect_next_instance_of(Gitlab::Diff::PositionTracer) do |tracer|
|
||||||
|
expect(tracer).to receive(:trace).and_return({ position: nil })
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(subject.execute(note.discussion)).to eq(nil)
|
||||||
|
expect(note.diff_note_positions).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -348,6 +348,7 @@ describe Projects::CreateService, '#execute' do
|
||||||
project = create_project(user, opts)
|
project = create_project(user, opts)
|
||||||
|
|
||||||
expect(project.services.count).to eq 1
|
expect(project.services.count).to eq 1
|
||||||
|
expect(project.errors).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue