...
 
Commits (135)
# Backend Maintainers are the default for all ruby files
*.rb @ayufan @DouweM @dzaporozhets @grzesiek @nick.thomas @rspeicher @rymai @smcgivern
*.rake @ayufan @DouweM @dzaporozhets @grzesiek @nick.thomas @rspeicher @rymai @smcgivern
# Technical writing team are the default reviewers for everything in `doc/`
/doc/ @axil @marcia
# Frontend maintainers should see everything in `app/assets/`
app/assets/ @annabeldunstone @ClemMakesApps @fatihacet @filipa @iamphill @mikegreiling @timzallmann
# Someone from the database team should review changes in `db/`
db/ @abrandl @NikolayS
# Feature specific owners
/ee/lib/gitlab/code_owners/ @reprazent
......@@ -71,7 +71,7 @@ gem 'u2f', '~> 0.2.1'
gem 'validates_hostname', '~> 1.0.6'
# Browser detection
gem 'browser', '~> 2.2'
gem 'browser', '~> 2.5'
# GPG
gem 'gpgme'
......@@ -110,7 +110,9 @@ gem 'kaminari', '~> 1.0'
gem 'hamlit', '~> 2.8.8'
# Files attachments
gem 'carrierwave', '~> 1.2'
# Locked until https://github.com/carrierwaveuploader/carrierwave/pull/2332/files is merged.
# config/initializers/carrierwave_patch.rb can be removed once that change is released.
gem 'carrierwave', '= 1.2.3'
gem 'mini_magick'
# Drag and Drop UI
......
......@@ -98,7 +98,7 @@ GEM
msgpack (~> 1.0)
bootstrap_form (2.7.0)
brakeman (4.2.1)
browser (2.2.0)
browser (2.5.3)
builder (3.2.3)
bullet (5.5.1)
activesupport (>= 3.0.0)
......@@ -1021,12 +1021,12 @@ DEPENDENCIES
bootsnap (~> 1.3)
bootstrap_form (~> 2.7.0)
brakeman (~> 4.2)
browser (~> 2.2)
browser (~> 2.5)
bullet (~> 5.5.0)
bundler-audit (~> 0.5.0)
capybara (~> 2.15)
capybara-screenshot (~> 1.0.0)
carrierwave (~> 1.2)
carrierwave (= 1.2.3)
charlock_holmes (~> 0.7.5)
chronic (~> 0.10.2)
chronic_duration (~> 0.10.6)
......
......@@ -101,7 +101,7 @@ GEM
msgpack (~> 1.0)
bootstrap_form (2.7.0)
brakeman (4.2.1)
browser (2.2.0)
browser (2.5.3)
builder (3.2.3)
bullet (5.5.1)
activesupport (>= 3.0.0)
......@@ -1030,12 +1030,12 @@ DEPENDENCIES
bootsnap (~> 1.3)
bootstrap_form (~> 2.7.0)
brakeman (~> 4.2)
browser (~> 2.2)
browser (~> 2.5)
bullet (~> 5.5.0)
bundler-audit (~> 0.5.0)
capybara (~> 2.15)
capybara-screenshot (~> 1.0.0)
carrierwave (~> 1.2)
carrierwave (= 1.2.3)
charlock_holmes (~> 0.7.5)
chronic (~> 0.10.2)
chronic_duration (~> 0.10.6)
......
......@@ -33,7 +33,7 @@ Documentation:
http://doc.gitlab.com/ee/
To upgrade from CE, just perform a normal upgrade, but use an EE package:
https://about.gitlab.com/update/#ee
https://about.gitlab.com/upgrade/
If you need help with your GitLab installation and for any technical questions please see the [support page](https://about.gitlab.com/support/)
......
app/assets/images/auth_buttons/azure_64.png

695 Bytes | W: | H:

app/assets/images/auth_buttons/azure_64.png

199 Bytes | W: | H:

app/assets/images/auth_buttons/azure_64.png
app/assets/images/auth_buttons/azure_64.png
app/assets/images/auth_buttons/azure_64.png
app/assets/images/auth_buttons/azure_64.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -63,7 +63,7 @@ export default {
v-else
role="button"
class="fa fa-times dropdown-input-search"
@click="clearSearch"
@click.stop.prevent="clearSearch"
></i>
</div>
<div class="dropdown-content">
......
......@@ -13,45 +13,57 @@ export default class Project {
constructor() {
const $cloneOptions = $('ul.clone-options-dropdown');
const $projectCloneField = $('#project_clone');
const $cloneBtnText = $('a.clone-dropdown-btn span');
const $cloneBtnLabel = $('.js-git-clone-holder .js-clone-dropdown-label');
const selectedCloneOption = $cloneBtnText.text().trim();
const selectedCloneOption = $cloneBtnLabel.text().trim();
if (selectedCloneOption.length > 0) {
$(`a:contains('${selectedCloneOption}')`, $cloneOptions).addClass('is-active');
}
$('a', $cloneOptions).on('click', (e) => {
$('a', $cloneOptions).on('click', e => {
e.preventDefault();
const $this = $(e.currentTarget);
const url = $this.attr('href');
const activeText = $this.find('.dropdown-menu-inner-title').text();
const cloneType = $this.data('cloneType');
e.preventDefault();
$('.is-active', $cloneOptions).removeClass('is-active');
$(`a[data-clone-type="${cloneType}"]`).each(function() {
const $el = $(this);
const activeText = $el.find('.dropdown-menu-inner-title').text();
const $container = $el.closest('.project-clone-holder');
const $label = $container.find('.js-clone-dropdown-label');
$('.is-active', $cloneOptions).not($this).removeClass('is-active');
$this.toggleClass('is-active');
$projectCloneField.val(url);
$cloneBtnText.text(activeText);
$el.toggleClass('is-active');
$label.text(activeText);
});
$('#modal-geo-info').data({
cloneUrlSecondary: $this.attr('href'),
cloneUrlPrimary: $this.data('primaryUrl') || '',
});
return $('.clone').text(url);
$projectCloneField.val(url);
$('.js-git-empty .js-clone').text(url);
});
// Ref switcher
Project.initRefSwitcher();
$('.project-refs-select').on('change', function() {
return $(this).parents('form').submit();
return $(this)
.parents('form')
.submit();
});
$('.hide-no-ssh-message').on('click', function(e) {
Cookies.set('hide_no_ssh_message', 'false');
$(this).parents('.no-ssh-key-message').remove();
$(this)
.parents('.no-ssh-key-message')
.remove();
return e.preventDefault();
});
$('.hide-no-password-message').on('click', function(e) {
Cookies.set('hide_no_password_message', 'false');
$(this).parents('.no-password-message').remove();
$(this)
.parents('.no-password-message')
.remove();
return e.preventDefault();
});
$('.hide-shared-runner-limit-message').on('click', function(e) {
......@@ -70,7 +82,7 @@ export default class Project {
}
static changeProject(url) {
return window.location = url;
return (window.location = url);
}
static initRefSwitcher() {
......@@ -85,14 +97,15 @@ export default class Project {
selected = $dropdown.data('selected');
return $dropdown.glDropdown({
data(term, callback) {
axios.get($dropdown.data('refsUrl'), {
params: {
ref: $dropdown.data('ref'),
search: term,
},
})
.then(({ data }) => callback(data))
.catch(() => flash(__('An error occurred while getting projects')));
axios
.get($dropdown.data('refsUrl'), {
params: {
ref: $dropdown.data('ref'),
search: term,
},
})
.then(({ data }) => callback(data))
.catch(() => flash(__('An error occurred while getting projects')));
},
selectable: true,
filterable: true,
......
......@@ -8,15 +8,18 @@ import BlobViewer from '~/blob/viewer/index';
import Activities from '~/activities';
import { ajaxGet } from '~/lib/utils/common_utils';
import GpgBadges from '~/gpg_badges';
import initReadMore from '~/read_more';
import Star from '../../../star';
import notificationsDropdown from '../../../notifications_dropdown';
document.addEventListener('DOMContentLoaded', () => {
initReadMore();
new Star(); // eslint-disable-line no-new
notificationsDropdown();
new ShortcutsNavigation(); // eslint-disable-line no-new
new NotificationsForm(); // eslint-disable-line no-new
new UserCallout({ // eslint-disable-line no-new
// eslint-disable-next-line no-new
new UserCallout({
setCalloutPerProject: false,
className: 'js-autodevops-banner',
});
......
/**
* ReadMore
*
* Adds "read more" functionality to elements.
*
* Specifically, it looks for a trigger, by default ".js-read-more-trigger", and adds the class
* "is-expanded" to the previous element in order to provide a click to expand functionality.
*
* This is useful for long text elements that you would like to truncate, especially for mobile.
*
* Example Markup
* <div class="read-more-container">
* <p>Some text that should be long enough to have to truncate within a specified container.</p>
* <p>This text will not appear in the container, as only the first line can be truncated.</p>
* <p>This should also not appear, if everything is working correctly!</p>
* </div>
* <button class="js-read-more-trigger">Read more</button>
*
*/
export default function initReadMore(triggerSelector = '.js-read-more-trigger') {
const triggerEls = document.querySelectorAll(triggerSelector);
if (!triggerEls) return;
triggerEls.forEach(triggerEl => {
const targetEl = triggerEl.previousElementSibling;
if (!targetEl) {
return;
}
triggerEl.addEventListener(
'click',
e => {
targetEl.classList.add('is-expanded');
e.target.remove();
},
{ once: true },
);
});
}
......@@ -66,3 +66,4 @@
@import 'framework/ci_variable_list';
@import 'framework/feature_highlight';
@import 'framework/terms';
@import 'framework/read_more';
......@@ -229,8 +229,8 @@
svg {
margin-bottom: 1px;
height: 18px;
width: 18px;
height: $default-icon-size;
width: $default-icon-size;
border-radius: 50%;
path {
......
......@@ -149,7 +149,8 @@
&.btn-success,
&.btn-new,
&.btn-create,
&.btn-save {
&.btn-save,
&.btn-register {
@include btn-green;
}
......@@ -172,8 +173,7 @@
}
&.btn-info,
&.btn-primary,
&.btn-register {
&.btn-primary {
@include btn-blue;
}
......@@ -248,7 +248,7 @@
.btn-terminal {
svg {
height: 14px;
width: 18px;
width: $default-icon-size;
}
}
......
......@@ -216,8 +216,8 @@
vertical-align: inherit;
img {
height: 18px;
width: 18px;
height: $default-icon-size;
width: $default-icon-size;
}
}
......
......@@ -44,12 +44,8 @@
.project-repo-buttons {
display: block;
.count-buttons .btn {
margin: 0 10px;
}
.count-buttons .count-with-arrow {
display: none;
.count-buttons .count-badge {
margin-top: $gl-padding-8;
}
}
}
......
.read-more-container {
@include media-breakpoint-down(md) {
&:not(.is-expanded) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
> * {
display: inline;
}
}
}
}
......@@ -56,8 +56,8 @@
&,
.toggle-icon-svg {
width: 18px;
height: 18px;
width: $default-icon-size;
height: $default-icon-size;
}
.toggle-icon-svg {
......
......@@ -252,7 +252,7 @@ $container-text-max-width: 540px;
$gl-avatar-size: 40px;
$border-radius-default: 4px;
$border-radius-small: 2px;
$settings-icon-size: 18px;
$default-icon-size: 18px;
$layout-link-gray: #7e7c7c;
$btn-side-margin: 10px;
$btn-sm-side-margin: 7px;
......@@ -274,6 +274,7 @@ $performance-bar-height: 35px;
$flash-height: 52px;
$context-header-height: 60px;
$breadcrumb-min-height: 48px;
$project-title-row-height: 24px;
// EE-only CSS variables START
$system-header-height: 35px;
......
......@@ -749,6 +749,10 @@
left: $gl-padding;
}
.dropdown-input .dropdown-input-search {
pointer-events: all;
}
.diff-changed-file {
display: flex;
padding-top: 8px;
......
......@@ -100,6 +100,22 @@
p {
margin: 0;
}
.omniauth-btn {
margin-bottom: $gl-padding;
width: 48%;
padding: $gl-padding-8;
@include media-breakpoint-down(md) {
width: 100%;
}
img {
width: $default-icon-size;
height: $default-icon-size;
margin-right: $gl-padding;
}
}
}
.new-session-tabs {
......@@ -169,10 +185,6 @@
}
}
label {
font-weight: $gl-font-weight-normal;
}
.submit-container {
margin-top: 16px;
}
......@@ -200,15 +212,6 @@
}
}
.oauth-image-link {
margin-right: 10px;
img {
width: 32px;
height: 32px;
}
}
.devise-layout-html {
margin: 0;
padding: 0;
......
......@@ -115,7 +115,7 @@
.project-feature-controls {
display: flex;
align-items: center;
margin: 8px 0;
margin: $gl-padding-8 0;
max-width: 432px;
.toggle-wrapper {
......@@ -144,12 +144,8 @@
.group-home-panel {
padding-top: 24px;
padding-bottom: 24px;
border-bottom: 1px solid $border-color;
@include media-breakpoint-up(sm) {
border-bottom: 1px solid $border-color;
}
.project-avatar,
.group-avatar {
float: none;
margin: 0 auto;
......@@ -175,7 +171,6 @@
}
}
.project-home-desc,
.group-home-desc {
margin-left: auto;
margin-right: auto;
......@@ -199,6 +194,62 @@
}
}
.project-home-panel {
padding-top: $gl-padding-8;
padding-bottom: $gl-padding-24;
.project-title-row {
margin-right: $gl-padding-8;
}
.project-avatar {
width: $project-title-row-height;
height: $project-title-row-height;
flex-shrink: 0;
flex-basis: $project-title-row-height;
margin: 0 $gl-padding-8 0 0;
}
.project-title {
font-size: 20px;
line-height: $project-title-row-height;
font-weight: bold;
}
.project-metadata {
font-weight: normal;
font-size: 14px;
line-height: $gl-btn-line-height;
color: $gl-text-color-secondary;
.icon {
margin-right: $gl-padding-4;
font-size: 16px;
}
.project-visibility,
.project-license,
.project-tag-list {
margin-right: $gl-padding-8;
}
.project-license {
.btn {
line-height: 0;
border-width: 0;
}
}
.project-tag-list,
.project-license {
.icon {
position: relative;
top: 2px;
}
}
}
}
.nav > .project-repo-buttons {
margin-top: 0;
}
......@@ -206,8 +257,6 @@
.project-repo-buttons,
.group-buttons {
.btn {
padding: 3px 10px;
&:last-child {
margin-left: 0;
}
......@@ -222,11 +271,15 @@
.fa-caret-down {
margin-left: 3px;
&.dropdown-btn-icon {
margin-left: 0;
}
}
}
.project-action-button {
margin: 15px 5px 0;
margin: $gl-padding $gl-padding-8 0 0;
vertical-align: top;
}
......@@ -243,82 +296,45 @@
.count-buttons {
display: inline-block;
vertical-align: top;
margin-top: 15px;
}
margin-top: $gl-padding;
.project-clone-holder {
display: inline-block;
margin: 15px 5px 0 0;
.count-badge {
height: $input-height;
input {
height: 28px;
.icon {
top: -1px;
}
}
}
.count-with-arrow {
display: inline-block;
position: relative;
margin-left: 4px;
.count-badge-count,
.count-badge-button {
border: 1px solid $border-color;
line-height: 1;
}
.arrow {
&::before {
content: '';
display: inline-block;
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
top: 50%;
left: 0;
margin-top: -6px;
border-width: 7px 5px 7px 0;
border-right-color: $count-arrow-border;
pointer-events: none;
}
.count,
.count-badge-button {
color: $gl-text-color;
}
&::after {
content: '';
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
top: 50%;
left: 1px;
margin-top: -9px;
border-width: 10px 7px 10px 0;
border-right-color: $white-light;
pointer-events: none;
}
.count-badge-count {
padding: 0 12px;
border-right: 0;
border-radius: $border-radius-base 0 0 $border-radius-base;
background: $gray-light;
}
.count {
@include btn-white;
display: inline-block;
background: $white-light;
border-radius: 2px;
border-width: 1px;
border-style: solid;
font-size: 13px;
font-weight: $gl-font-weight-bold;
line-height: 13px;
letter-spacing: 0.4px;
padding: 6px 14px;
text-align: center;
vertical-align: middle;
touch-action: manipulation;
background-image: none;
white-space: nowrap;
margin: 0 10px 0 4px;
.count-badge-button {
border-radius: 0 $border-radius-base $border-radius-base 0;
}
}
a {
color: inherit;
}
.project-clone-holder {
display: inline-block;
margin: $gl-padding $gl-padding-8 0 0;
&:hover {
background: $white-light;
}
input {
height: $input-height;
}
}
......@@ -333,6 +349,14 @@
min-width: 320px;
}
}
.mobile-git-clone {
margin-top: $gl-padding-8;
.dropdown-menu-inner-content {
@extend .monospace;
}
}
}
.split-one {
......@@ -512,7 +536,6 @@
.controls {
margin-left: auto;
}
}
.choose-template {
......@@ -575,7 +598,7 @@
flex-wrap: wrap;
.btn {
padding: 8px;
padding: $gl-padding-8;
margin-right: 10px;
}
......@@ -652,7 +675,7 @@
left: -10px;
top: 50%;
z-index: 10;
padding: 8px 0;
padding: $gl-padding-8 0;
text-align: center;
background-color: $white-light;
color: $gl-text-color-tertiary;
......@@ -666,7 +689,7 @@
left: 50%;
top: 0;
transform: translateX(-50%);
padding: 0 8px;
padding: 0 $gl-padding-8;
}
}
......@@ -700,17 +723,51 @@
.project-stats {
font-size: 0;
text-align: center;
max-width: 100%;
border-bottom: 1px solid $border-color;
.nav {
margin-top: $gl-padding-8;
margin-bottom: $gl-padding-8;
.scrolling-tabs-container {
.scrolling-tabs {
margin-top: $gl-padding-8;
margin-bottom: $gl-padding-8;
flex-wrap: wrap;
border-bottom: 0;
}
.fade-left,
.fade-right {
top: 0;
height: 100%;
.fa {
top: 50%;
margin-top: -$gl-padding-8;
}
}
.nav {
flex-basis: 100%;
+ .nav {
margin: $gl-padding-8 0;
}
}
@include media-breakpoint-down(md) {
flex-direction: column;
.nav {
flex-wrap: nowrap;
}
.nav:first-child {
margin-right: $gl-padding-8;
}
}
}
.nav {
> li {
display: inline-block;
margin-top: $gl-padding-4;
margin-bottom: $gl-padding-4;
&:not(:last-child) {
margin-right: $gl-padding;
......@@ -733,13 +790,17 @@
font-size: $gl-font-size;
line-height: $gl-btn-line-height;
color: $gl-text-color-secondary;
white-space: nowrap;
}
.stat-link {
border-bottom: 0;
&:hover,
&:focus {
color: $gl-text-color;
text-decoration: underline;
border-bottom: 0;
}
}
......@@ -869,7 +930,7 @@ pre.light-well {
}
.git-clone-holder {
width: 380px;
width: 320px;
.btn-clipboard {
border: 1px solid $border-color;
......
......@@ -106,7 +106,7 @@
.settings-list-icon {
color: $gl-text-color-secondary;
font-size: $settings-icon-size;
font-size: $default-icon-size;
line-height: 42px;
}
......
......@@ -110,6 +110,7 @@ class ApplicationController < ActionController::Base
def append_info_to_payload(payload)
super
payload[:ua] = request.env["HTTP_USER_AGENT"]
payload[:remote_ip] = request.remote_ip
logged_user = auth_user
......
module SendFileUpload
def send_upload(file_upload, send_params: {}, redirect_params: {}, attachment: nil, disposition: 'attachment')
if attachment
redirect_params[:query] = { "response-content-disposition" => "#{disposition};filename=#{attachment.inspect}" }
# Response-Content-Type will not override an existing Content-Type in
# Google Cloud Storage, so the metadata needs to be cleared on GCS for
# this to work. However, this override works with AWS.
redirect_params[:query] = { "response-content-disposition" => "#{disposition};filename=#{attachment.inspect}",
"response-content-type" => guess_content_type(attachment) }
# By default, Rails will send uploads with an extension of .js with a
# content-type of text/javascript, which will trigger Rails'
# cross-origin JavaScript protection.
......@@ -18,4 +22,14 @@ module SendFileUpload
redirect_to file_upload.url(**redirect_params)
end
end
def guess_content_type(filename)
types = MIME::Types.type_for(filename)
if types.present?
types.first.content_type
else
"application/octet-stream"
end
end
end
......@@ -159,7 +159,8 @@ class Projects::ClustersController < Projects::ApplicationController
:namespace,
:api_url,
:token,
:ca_cert
:ca_cert,
:authorization_type
]).merge(
provider_type: :user,
platform_type: :kubernetes
......
class Projects::RefsController < Projects::ApplicationController
include ExtractsPath
include TreeHelper
include PathLocksHelper
before_action :require_non_empty_project
before_action :validate_ref_id
......@@ -37,58 +36,47 @@ class Projects::RefsController < Projects::ApplicationController
end
def logs_tree
@offset = if params[:offset].present?
params[:offset].to_i
else
0
end
summary = ::Gitlab::TreeSummary.new(
@commit,
@project,
path: @path,
offset: params[:offset],
limit: 25
)
@limit = 25
@path = params[:path]
contents = []
contents.push(*tree.trees)
contents.push(*tree.blobs)
contents.push(*tree.submodules)
# n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37433
@logs = Gitlab::GitalyClient.allow_n_plus_1_calls do
contents[@offset, @limit].to_a.map do |content|
file = @path ? File.join(@path, content.name) : content.name
last_commit = @repo.last_commit_for_path(@commit.id, file)
commit_path = project_commit_path(@project, last_commit) if last_commit
path_lock = @project.find_path_lock(file)
{
file_name: content.name,
commit: last_commit,
type: content.type,
commit_path: commit_path,
lock_label: path_lock && text_label_for_lock(path_lock, file)
}
end
end
offset = @offset + @limit
if contents.size > offset
@more_log_url = logs_file_project_ref_path(@project, @ref, @path || '', offset: offset)
end
@logs, commits = summary.summarize
@more_log_url = more_url(summary.next_offset) if summary.more?
respond_to do |format|
format.html { render_404 }
format.json do
response.headers["More-Logs-Url"] = @more_log_url
response.headers["More-Logs-Url"] = @more_log_url if summary.more?
render json: @logs
end
format.js
# The commit titles must be rendered and redacted before being shown.
# Doing it here allows us to apply performance optimizations that avoid
# N+1 problems
format.js do
prerender_commit_full_titles!(commits)
end
end
end
private
def more_url(offset)
logs_file_project_ref_path(@project, @ref, @path, offset: offset)
end
def prerender_commit_full_titles!(commits)
# Preload commit authors as they are used in rendering
commits.each(&:lazy_author)
renderer = Banzai::ObjectRenderer.new(user: current_user, default_project: @project)
renderer.render(commits, :full_title)
end
def validate_ref_id
return not_found! if params[:id].present? && params[:id] !~ Gitlab::PathRegex.git_reference_regex
end
......
......@@ -60,9 +60,8 @@ module ButtonHelper
protocol = gitlab_config.protocol.upcase
dropdown_description = http_dropdown_description(protocol)
append_url = project.http_url_to_repo if append_link
geo_url = geo_primary_http_url_to_repo(project) if Gitlab::Geo.secondary?
dropdown_item_with_description(protocol, dropdown_description, href: append_url, geo_url: geo_url)
dropdown_item_with_description(protocol, dropdown_description, href: append_url, data: { clone_type: 'http' })
end
def http_dropdown_description(protocol)
......@@ -80,12 +79,11 @@ module ButtonHelper
end
append_url = project.ssh_url_to_repo if append_link
geo_url = geo_primary_ssh_url_to_repo(project) if Gitlab::Geo.secondary?
dropdown_item_with_description('SSH', dropdown_description, href: append_url, geo_url: geo_url)
dropdown_item_with_description('SSH', dropdown_description, href: append_url, data: { clone_type: 'ssh' })
end
def dropdown_item_with_description(title, description, href: nil, geo_url: nil)
def dropdown_item_with_description(title, description, href: nil, data: nil)
button_content = content_tag(:strong, title, class: 'dropdown-menu-inner-title')
button_content << content_tag(:span, description, class: 'dropdown-menu-inner-content') if description
......@@ -93,9 +91,7 @@ module ButtonHelper
(href ? button_content : title),
class: "#{title.downcase}-selector",
href: (href if href),
data: {
primary_url: (geo_url if geo_url)
}
data: (data if data)
end
def kerberos_clone_button(project)
......
......@@ -11,4 +11,8 @@ module ClustersHelper
render 'projects/clusters/gcp_signup_offer_banner'
end
end
def rbac_clusters_feature_enabled?
Feature.enabled?(:rbac_clusters)
end
end
......@@ -86,7 +86,7 @@ module IconsHelper
end
end
def visibility_level_icon(level, fw: true)
def visibility_level_icon(level, fw: true, options: {})
name =
case level
when Gitlab::VisibilityLevel::PRIVATE
......@@ -99,7 +99,7 @@ module IconsHelper
name << " fw" if fw
icon(name)
icon(name, options)
end
def file_type_icon_class(type, mode, name)
......
......@@ -107,23 +107,23 @@ module MarkupHelper
def markup(file_name, text, context = {})
context[:project] ||= @project
context[:markdown_engine] ||= :redcarpet
context[:markdown_engine] ||= :redcarpet unless commonmark_for_repositories_enabled?
html = context.delete(:rendered) || markup_unsafe(file_name, text, context)
prepare_for_rendering(html, context)
end
def render_wiki_content(wiki_page)
def render_wiki_content(wiki_page, context = {})
text = wiki_page.content
return '' unless text.present?
context = {
context.merge!(
pipeline: :wiki,
project: @project,
project_wiki: @project_wiki,
page_slug: wiki_page.slug,
issuable_state_filter_enabled: true,
markdown_engine: :redcarpet
}
issuable_state_filter_enabled: true
)
context[:markdown_engine] ||= :redcarpet unless commonmark_for_repositories_enabled?
html =
case wiki_page.format
......@@ -178,6 +178,10 @@ module MarkupHelper
end
end
def commonmark_for_repositories_enabled?
Feature.enabled?(:commonmark_for_repositories, default_enabled: true)
end
private
# Return +text+, truncated to +max_chars+ characters, excluding any HTML
......
......@@ -254,6 +254,10 @@ module ProjectsHelper
"xcode://clone?repo=#{CGI.escape(default_url_to_repo(project))}"
end
def legacy_render_context(params)
params[:legacy_render] ? { markdown_engine: :redcarpet } : {}
end
private
def get_project_nav_tabs(project, current_user)
......@@ -353,6 +357,10 @@ module ProjectsHelper
end
end
def default_clone_label
_("Copy %{protocol} clone URL") % { protocol: default_clone_protocol.upcase }
end
def default_clone_protocol
if allowed_protocols_present?
enabled_protocol
......
......@@ -138,7 +138,7 @@ module VisibilityLevelHelper
end
def project_visibility_icon_description(level)
"#{visibility_level_label(level)} - #{project_visibility_level_description(level)}"
"#{project_visibility_level_description(level)}"
end
def visibility_level_label(level)
......
......@@ -2,6 +2,8 @@
# Blob is a Rails-specific wrapper around Gitlab::Git::Blob objects
class Blob < SimpleDelegator
prepend EE::Blob
CACHE_TIME = 60 # Cache raw blobs referred to by a (mutable) ref for 1 minute
CACHE_TIME_IMMUTABLE = 3600 # Cache blobs referred to by an immutable reference for 1 hour
......
......@@ -90,7 +90,9 @@ module Ci
end
def hashed_path?
super || self.try(:file_location).nil?
return true if trace? # ArchiveLegacyTraces background migration might not have `file_location` column
super || self.file_location.nil?
end
def expire_in
......
......@@ -32,7 +32,8 @@ module Clusters
def install_command
Gitlab::Kubernetes::Helm::InitCommand.new(
name: name,
files: files
files: files,
rbac: cluster.platform_kubernetes_rbac?
)
end
......
......@@ -39,6 +39,7 @@ module Clusters
Gitlab::Kubernetes::Helm::InstallCommand.new(
name: name,
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
files: files
)
......
......@@ -40,6 +40,7 @@ module Clusters
Gitlab::Kubernetes::Helm::InstallCommand.new(
name: name,
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
files: files,
repository: repository
......
......@@ -50,6 +50,7 @@ module Clusters
Gitlab::Kubernetes::Helm::InstallCommand.new(
name: name,
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
files: files
)
......@@ -73,7 +74,7 @@ module Clusters
private
def kube_client
cluster&.kubeclient
cluster&.kubeclient&.core_client
end
end
end
......
......@@ -33,6 +33,7 @@ module Clusters
Gitlab::Kubernetes::Helm::InstallCommand.new(
name: name,
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
files: files,
repository: repository
......
......@@ -44,6 +44,7 @@ module Clusters
delegate :on_creation?, to: :provider, allow_nil: true
delegate :active?, to: :platform_kubernetes, prefix: true, allow_nil: true
delegate :rbac?, to: :platform_kubernetes, prefix: true, allow_nil: true
delegate :installed?, to: :application_helm, prefix: true, allow_nil: true
delegate :installed?, to: :application_ingress, prefix: true, allow_nil: true
......