Commit 747646b7 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'ce-to-ee' into 'master'

CE Upstream - Monday

Closes gitlab-ce#39776, gitlab-ce#39771 et #3544

See merge request gitlab-org/gitlab-ee!3277
parents b1e572b3 2f8a25d2
...@@ -479,7 +479,7 @@ db:migrate:reset-mysql: ...@@ -479,7 +479,7 @@ db:migrate:reset-mysql:
variables: variables:
SETUP_DB: "false" SETUP_DB: "false"
script: script:
- git fetch origin v9.3.0-ee - git fetch https://gitlab.com/gitlab-org/gitlab-ee.git v9.3.0-ee
- git checkout -f FETCH_HEAD - git checkout -f FETCH_HEAD
- bundle install $BUNDLE_INSTALL_FLAGS - bundle install $BUNDLE_INSTALL_FLAGS
- cp config/gitlab.yml.example config/gitlab.yml - cp config/gitlab.yml.example config/gitlab.yml
......
...@@ -112,7 +112,7 @@ linters: ...@@ -112,7 +112,7 @@ linters:
# Reports when you define the same selector twice in a single sheet. # Reports when you define the same selector twice in a single sheet.
MergeableSelector: MergeableSelector:
enabled: false enabled: true
# Functions, mixins, variables, and placeholders should be declared # Functions, mixins, variables, and placeholders should be declared
# with all lowercase letters and hyphens instead of underscores. # with all lowercase letters and hyphens instead of underscores.
......
...@@ -4,7 +4,6 @@ entry. ...@@ -4,7 +4,6 @@ entry.
## 10.1.1 (2017-10-31) ## 10.1.1 (2017-10-31)
- No changes.
- [FIXED] Auto Devops kubernetes default namespace is now correctly built out of gitlab project group-name. !14642 (Mircea Danila Dumitrescu) - [FIXED] Auto Devops kubernetes default namespace is now correctly built out of gitlab project group-name. !14642 (Mircea Danila Dumitrescu)
- [FIXED] Forbid the usage of `Redis#keys`. !14889 - [FIXED] Forbid the usage of `Redis#keys`. !14889
- [FIXED] Make the circuitbreaker more robust by adding higher thresholds, and multiple access attempts. !14933 - [FIXED] Make the circuitbreaker more robust by adding higher thresholds, and multiple access attempts. !14933
......
/* globals Flash */ /* globals Flash */
import Visibility from 'visibilityjs'; import Visibility from 'visibilityjs';
import axios from 'axios'; import axios from 'axios';
import setAxiosCsrfToken from './lib/utils/axios_utils';
import Poll from './lib/utils/poll'; import Poll from './lib/utils/poll';
import { s__ } from './locale'; import { s__ } from './locale';
import initSettingsPanels from './settings_panels'; import initSettingsPanels from './settings_panels';
...@@ -17,6 +18,7 @@ import Flash from './flash'; ...@@ -17,6 +18,7 @@ import Flash from './flash';
class ClusterService { class ClusterService {
constructor(options = {}) { constructor(options = {}) {
this.options = options; this.options = options;
setAxiosCsrfToken();
} }
fetchData() { fetchData() {
return axios.get(this.options.endpoint); return axios.get(this.options.endpoint);
......
import axios from 'axios';
import csrf from './csrf';
export default function setAxiosCsrfToken() {
axios.defaults.headers.common[csrf.headerKey] = csrf.token;
}
...@@ -40,6 +40,10 @@ ...@@ -40,6 +40,10 @@
&.top-block { &.top-block {
border-top: 0; border-top: 0;
.container-fluid {
background-color: inherit;
}
} }
&.middle-block { &.middle-block {
...@@ -98,10 +102,6 @@ ...@@ -98,10 +102,6 @@
background-color: $white-light; background-color: $white-light;
border-top: 0; border-top: 0;
} }
&.top-block .container-fluid {
background-color: inherit;
}
} }
.sub-header-block { .sub-header-block {
......
...@@ -12,15 +12,15 @@ ...@@ -12,15 +12,15 @@
border-left: 3px solid $border-color; border-left: 3px solid $border-color;
color: $text-color; color: $text-color;
background: $gray-light; background: $gray-light;
}
.bs-callout h4 { h4 {
margin-top: 0; margin-top: 0;
margin-bottom: 5px; margin-bottom: 5px;
} }
.bs-callout p:last-child { p:last-child {
margin-bottom: 0; margin-bottom: 0;
}
} }
/* Variations */ /* Variations */
......
...@@ -56,6 +56,14 @@ hr { ...@@ -56,6 +56,14 @@ hr {
.str-truncated { .str-truncated {
@include str-truncated; @include str-truncated;
&-60 {
@include str-truncated(60%);
}
&-100 {
@include str-truncated(100%);
}
} }
.block-truncated { .block-truncated {
...@@ -85,10 +93,17 @@ hr { ...@@ -85,10 +93,17 @@ hr {
font-size: 14px; font-size: 14px;
} }
table a code { table {
position: relative; a code {
top: -2px; position: relative;
margin-right: 3px; top: -2px;
margin-right: 3px;
}
td.permission-x {
background: $table-permission-x-bg !important;
text-align: center;
}
} }
.loading { .loading {
...@@ -277,13 +292,6 @@ img.emoji { ...@@ -277,13 +292,6 @@ img.emoji {
margin: 5px 0; margin: 5px 0;
} }
table {
td.permission-x {
background: $table-permission-x-bg !important;
text-align: center;
}
}
.btn-sign-in { .btn-sign-in {
text-shadow: none; text-shadow: none;
...@@ -349,10 +357,11 @@ table { ...@@ -349,10 +357,11 @@ table {
.dropzone .dz-preview .dz-progress { .dropzone .dz-preview .dz-progress {
border-color: $border-color !important; border-color: $border-color !important;
}
.dropzone .dz-preview .dz-progress .dz-upload { .dz-upload {
background: $gl-success !important; background: $gl-success !important;
}
} }
.dz-message { .dz-message {
...@@ -413,16 +422,6 @@ table { ...@@ -413,16 +422,6 @@ table {
border-radius: $border-radius-default; border-radius: $border-radius-default;
} }
.str-truncated {
&-60 {
@include str-truncated(60%);
}
&-100 {
@include str-truncated(100%);
}
}
.tooltip { .tooltip {
.tooltip-inner { .tooltip-inner {
word-wrap: break-word; word-wrap: break-word;
......
...@@ -141,15 +141,15 @@ ...@@ -141,15 +141,15 @@
svg { svg {
fill: $gl-text-color-secondary; fill: $gl-text-color-secondary;
} }
}
.nav-item-name { .nav-item-name {
flex: 1; flex: 1;
} }
li.active { &.active {
> a { > a {
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
}
} }
} }
......
...@@ -728,11 +728,11 @@ ...@@ -728,11 +728,11 @@
.pika-single.animate-picker.is-bound { .pika-single.animate-picker.is-bound {
@include set-visible; @include set-visible;
}
.pika-single.animate-picker.is-bound.is-hidden { &.is-hidden {
@include set-invisible; @include set-invisible;
overflow: hidden; overflow: hidden;
}
} }
@mixin dropdown-item-hover { @mixin dropdown-item-hover {
...@@ -939,9 +939,7 @@ header.header-content .dropdown-menu.projects-dropdown-menu { ...@@ -939,9 +939,7 @@ header.header-content .dropdown-menu.projects-dropdown-menu {
border-right: 0; border-right: 0;
} }
} }
}
.projects-dropdown-container {
.projects-list-frequent-container, .projects-list-frequent-container,
.projects-list-search-container, { .projects-list-search-container, {
padding: 8px 0; padding: 8px 0;
...@@ -952,11 +950,6 @@ header.header-content .dropdown-menu.projects-dropdown-menu { ...@@ -952,11 +950,6 @@ header.header-content .dropdown-menu.projects-dropdown-menu {
.projects-list-frequent-container li.section-empty, .projects-list-frequent-container li.section-empty,
.projects-list-search-container li.section-empty { .projects-list-search-container li.section-empty {
padding: 0 15px; padding: 0 15px;
}
.section-header,
.projects-list-frequent-container li.section-empty,
.projects-list-search-container li.section-empty {
color: $gl-text-color-secondary; color: $gl-text-color-secondary;
font-size: $gl-font-size; font-size: $gl-font-size;
} }
......
...@@ -165,22 +165,36 @@ ...@@ -165,22 +165,36 @@
&:last-child { &:last-child {
border-right: 0; border-right: 0;
} }
}
td.blame-commit { &.blame-commit {
padding: 5px 10px; padding: 5px 10px;
min-width: 400px; min-width: 400px;
max-width: 400px; max-width: 400px;
background: $gray-light; background: $gray-light;
border-left: 3px solid; border-left: 3px solid;
.commit-row-title {
display: flex;
}
.item-title {
flex: 1;
margin-right: 0.5em;
}
}
&.line-numbers {
float: none;
border-left: 1px solid $blame-line-numbers-border;
.commit-row-title { i {
display: flex; float: none;
margin-right: 0;
}
} }
.item-title { &.lines {
flex: 1; padding: 0;
margin-right: 0.5em;
} }
} }
...@@ -195,20 +209,6 @@ ...@@ -195,20 +209,6 @@
border-left-color: mix($blame-gray, $blame-cyan, $i / 4.0 * 100%); border-left-color: mix($blame-gray, $blame-cyan, $i / 4.0 * 100%);
} }
} }
td.line-numbers {
float: none;
border-left: 1px solid $blame-line-numbers-border;
i {
float: none;
margin-right: 0;
}
}
td.lines {
padding: 0;
}
} }
&.logs { &.logs {
......
...@@ -463,10 +463,10 @@ ...@@ -463,10 +463,10 @@
word-break: break-all; word-break: break-all;
} }
} }
}
.filter-dropdown-item.droplab-item-active .btn { &.droplab-item-active .btn {
@extend %filter-dropdown-item-btn-hover; @extend %filter-dropdown-item-btn-hover;
}
} }
.filter-dropdown-loading { .filter-dropdown-loading {
......
...@@ -352,7 +352,77 @@ ...@@ -352,7 +352,77 @@
.header-user .dropdown-menu-nav, .header-user .dropdown-menu-nav,
.header-new .dropdown-menu-nav { .header-new .dropdown-menu-nav {
margin-top: $dropdown-vertical-offset; margin-top: 4px;
}
.search {
margin: 4px 8px 0;
form {
height: 32px;
border: 0;
border-radius: $border-radius-default;
transition: border-color ease-in-out 0.15s, background-color ease-in-out 0.15s;
&:hover {
box-shadow: none;
}
}
.search-input {
color: $white-light;
background: none;
transition: color ease-in-out 0.15s;
}
.search-input::placeholder {
transition: color ease-in-out 0.15s;
}
.location-badge {
font-size: 12px;
margin: -4px 4px -4px -4px;
line-height: 25px;
padding: 4px 8px;
border-radius: 2px 0 0 2px;
height: 32px;
transition: border-color ease-in-out 0.15s;
}
&.search-active {
form {
background-color: rgba($indigo-200, .3);
box-shadow: none;
.search-input {
color: $gl-text-color;
transition: color ease-in-out 0.15s;
}
.search-input::placeholder {
color: $gl-text-color-tertiary;
}
.search-input-wrap {
.search-icon,
.clear-icon {
color: $gl-text-color-tertiary;
transition: color ease-in-out 0.15s;
}
}
}
.location-badge {
background-color: $nav-badge-bg;
border-color: $border-color;
}
.search-input-wrap {
.clear-icon {
color: $white-light;
}
}
}
} }
.breadcrumbs { .breadcrumbs {
......
...@@ -30,10 +30,10 @@ body { ...@@ -30,10 +30,10 @@ body {
.container { .container {
padding-top: 0; padding-top: 0;
z-index: 5; z-index: 5;
}
.container .content { .content {
margin: 0; margin: 0;
}
} }
.navless-container { .navless-container {
...@@ -82,26 +82,26 @@ body { ...@@ -82,26 +82,26 @@ body {
transition: background-color 0.15s, border-color 0.15s; transition: background-color 0.15s, border-color 0.15s;
background-color: $orange-500; background-color: $orange-500;
border-color: $orange-500; border-color: $orange-500;
}
.alert-warning + .alert-warning { &:only-of-type {
background-color: $orange-600; background-color: $orange-500;
border-color: $orange-600; border-color: $orange-500;
} }
.alert-warning + .alert-warning + .alert-warning { + .alert-warning {
background-color: $orange-700; background-color: $orange-600;
border-color: $orange-700; border-color: $orange-600;
}
.alert-warning + .alert-warning + .alert-warning + .alert-warning { + .alert-warning {
background-color: $orange-800; background-color: $orange-700;
border-color: $orange-800; border-color: $orange-700;
}
.alert-warning:only-of-type { + .alert-warning {
background-color: $orange-500; background-color: $orange-800;
border-color: $orange-500; border-color: $orange-800;
}
}
}
} }
} }
......
...@@ -305,40 +305,40 @@ ul.indent-list { ...@@ -305,40 +305,40 @@ ul.indent-list {
} }
} }
.group-list-tree .avatar-container.content-loading { .group-list-tree {
position: relative; .avatar-container.content-loading {
position: relative;
> a, > a,
> a .avatar { > a .avatar {
height: 100%; height: 100%;
border-radius: 50%; border-radius: 50%;
} }
> a { > a {
padding: 2px; padding: 2px;
}
> a .avatar { .avatar {
border: 2px solid $white-normal; border: 2px solid $white-normal;
&.identicon { &.identicon {
line-height: 30px; line-height: 30px;
}
}
} }
}
&::after { &::after {
content: ""; content: "";
position: absolute; position: absolute;
height: 100%; height: 100%;
width: 100%; width: 100%;
background-color: transparent; background-color: transparent;
border: 2px outset $kdb-border; border: 2px outset $kdb-border;
border-radius: 50%; border-radius: 50%;
animation: spin-avatar 3s infinite linear; animation: spin-avatar 3s infinite linear;
}
} }
}
.group-list-tree {
.folder-toggle-wrap { .folder-toggle-wrap {
float: left; float: left;
line-height: $list-text-height; line-height: $list-text-height;
......
...@@ -173,21 +173,8 @@ ...@@ -173,21 +173,8 @@
ul > li { ul > li {
white-space: nowrap; white-space: nowrap;
} }
}
@media(max-width: $screen-xs-max) {
.atwho-view-ul {
width: 350px;
}
.atwho-view ul li {
overflow: hidden;
text-overflow: ellipsis;
}
}
// TODO: fallback to global style // TODO: fallback to global style
.atwho-view {
.atwho-view-ul { .atwho-view-ul {
padding: 8px 1px; padding: 8px 1px;
...@@ -220,3 +207,14 @@ ...@@ -220,3 +207,14 @@
} }
} }
} }
@media(max-width: $screen-xs-max) {
.atwho-view-ul {
width: 350px;
}
.atwho-view ul li {
overflow: hidden;
text-overflow: ellipsis;
}
}
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
.modal-body { .modal-body {
position: relative; position: relative;
padding: #{3 * $grid-size} #{2 * $grid-size}; padding: #{3 * $grid-size} #{2 * $grid-size};
background-color: $modal-body-bg;
.form-actions { .form-actions {
margin: #{2 * $grid-size} #{-2 * $grid-size} #{-2 * $grid-size}; margin: #{2 * $grid-size} #{-2 * $grid-size} #{-2 * $grid-size};
...@@ -46,7 +47,3 @@ body.modal-open { ...@@ -46,7 +47,3 @@ body.modal-open {
.modal.popup-dialog { .modal.popup-dialog {
display: block; display: block;
} }
.modal-body {
background-color: $modal-body-bg;
}
...@@ -367,11 +367,64 @@ ...@@ -367,11 +367,64 @@
} }
} }
.project-item-select-holder.btn-group { .page-with-layout-nav {
display: flex; .right-sidebar {
max-width: 350px; top: ($header-height + 1) * 2;
overflow: hidden; }
float: right;
&.page-with-sub-nav {
.right-sidebar {
top: ($header-height + 1) * 3;
&.affix {
top: $header-height;
}
}
}
}
.with-performance-bar .page-with-layout-nav {
.right-sidebar {
top: ($header-height + 1) * 2 + $performance-bar-height;
}
&.page-with-sub-nav {
.right-sidebar {
top: ($header-height + 1) * 3 + $performance-bar-height;
&.affix {
top: $header-height + $performance-bar-height;
}
}
}
}
@media (max-width: $screen-xs-max) {
.top-area {
flex-flow: row wrap;
.nav-controls {
$controls-margin: $btn-xs-side-margin - 2px;
flex: 0 0 100%;
&.controls-flex {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
padding: 0 0 $gl-padding-top;
}
.controls-item,
.controls-item-full,
.controls-item:last-child {
flex: 1 1 35%;
display: block;
width: 100%;
margin: $controls-margin;
}
}
}
.new-project-item-link { .new-project-item-link {
white-space: nowrap; white-space: nowrap;
......
...@@ -60,22 +60,12 @@ ...@@ -60,22 +60,12 @@
border-radius: $border-radius-base; border-radius: $border-radius-base;
border: 1px solid $dropdown-border-color; border: 1px solid $dropdown-border-color;
min-width: 175px; min-width: 175px;
color: $gl-text-color; color: $gl-grayish-blue;
z-index: 999;
} }
.select2-drop-mask { .select2-results .select2-result-label,
z-index: 998; .select2-more-results {
} padding: 10px 15px;
.select2-drop.select2-drop-above.select2-drop-active {
border-top: 1px solid $dropdown-border-color;
margin-top: -6px;
}
.select2-results li.select2-result-with-children > .select2-result-label {
font-weight: $gl-font-weight-bold;
color: $gl-text-color;
} }
.select2-container-active { .select2-container-active {
...@@ -144,58 +134,46 @@ ...@@ -144,58 +134,46 @@
.select2-drop-auto-width & { .select2-drop-auto-width & {
padding: 15px 15px 5px; padding: 15px 15px 5px;
} }
}
.select2-search input { input {
padding: 2px 25px 2px 5px; padding: 2px 25px 2px 5px;
background: $white-light image-url('select2.png'); background: $white-light image-url('select2.png');
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: right 0 bottom 6px; background-position: right 0 bottom 6px;
border: 1px solid $input-border; border: 1px solid $input-border;
border-radius: $border-radius-default; border-radius: $border-radius-default;
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
&:focus { &:focus {
border-color: $input-border-focus; border-color: $input-border-focus;
}
&.select2-active {
background-color: $white-light;
background-image: image-url('select2-spinner.gif') !important;
background-repeat: no-repeat;
background-position: right 5px center !important;
background-size: 16px 16px !important;
}
} }
} }
.select2-search input.select2-active { .select2-results .select2-no-results,
background-color: $white-light; .select2-results .select2-searching,
background-image: image-url('select2-spinner.gif') !important; .select2-results .select2-ajax-error,
background-repeat: no-repeat; .select2-results .select2-selection-limit {
background-position: right 5px center !important; background: $gray-light;
background-size: 16px 16px !important; display: list-item;
padding: 10px 15px;
} }
.select2-results { .select2-results {
margin: 0; margin: 0;
padding: #{$gl-padding / 2} 0; padding: 10px 0;
.select2-no-results,
.select2-searching,
.select2-ajax-error,
.select2-selection-limit {
background: transparent;
padding: #{$gl-padding / 2} $gl-padding;
}
.select2-result-label,
.select2-more-results {
padding: #{$gl-padding / 2} $gl-padding;
}
.select2-highlighted { li.select2-result-with-children > .select2-result-label {
background: transparent; font-weight: $gl-font-weight-bold;
color: $gl-text-color; color: $gl-text-color;
.select2-result-label {
background: $dropdown-item-hover-bg;
}
}
.select2-result {
padding: 0 1px;
} }
} }
...@@ -212,6 +190,8 @@ ...@@ -212,6 +190,8 @@
} }
.select2-highlighted { .select2-highlighted {
background: $gl-link-color !important;
.group-result { .group-result {
.group-path { .group-path {
color: $white-light; color: $white-light;
......
...@@ -217,13 +217,31 @@ $white-gc-bg: #eaf2f5; ...@@ -217,13 +217,31 @@ $white-gc-bg: #eaf2f5;
.cp { color: $white-cp; font-weight: $gl-font-weight-bold; } .cp { color: $white-cp; font-weight: $gl-font-weight-bold; }
.c1 { color: $white-c1; font-style: italic; } .c1 { color: $white-c1; font-style: italic; }
.cs { color: $white-cs; font-weight: $gl-font-weight-bold; font-style: italic; } .cs { color: $white-cs; font-weight: $gl-font-weight-bold; font-style: italic; }
.gd { color: $white-gd; background-color: $white-gd-bg; }
.gd .x { color: $white-gd-x; background-color: $white-gd-x-bg; } .gd {
color: $white-gd;
background-color: $white-gd-bg;
.x {
color: $white-gd-x;
background-color: $white-gd-x-bg;
}
}
.ge { font-style: italic; } .ge { font-style: italic; }
.gr { color: $white-gr; } .gr { color: $white-gr; }
.gh { color: $white-gh; } .gh { color: $white-gh; }
.gi { color: $white-gi; background-color: $white-gi-bg; }
.gi .x { color: $white-gi-x; background-color: $white-gi-x-bg; } .gi {
color: $white-gi;
background-color: $white-gi-bg;
.x {
color: $white-gi-x;
background-color: $white-gi-x-bg;
}
}
.go { color: $white-go; } .go { color: $white-go; }
.gp { color: $white-gp; } .gp { color: $white-gp; }
.gs { font-weight: $gl-font-weight-bold; } .gs { font-weight: $gl-font-weight-bold; }
......
...@@ -158,13 +158,31 @@ span.highlight_word { ...@@ -158,13 +158,31 @@ span.highlight_word {
.cp { color: $highlighted-cp; font-weight: $gl-font-weight-bold; } .cp { color: $highlighted-cp; font-weight: $gl-font-weight-bold; }
.c1 { color: $highlighted-c1; font-style: italic; } .c1 { color: $highlighted-c1; font-style: italic; }
.cs { color: $highlighted-cs; font-weight: $gl-font-weight-bold; font-style: italic; } .cs { color: $highlighted-cs; font-weight: $gl-font-weight-bold; font-style: italic; }
.gd { color: $highlighted-gd; background-color: $highlighted-gd-bg; }
.gd .x { color: $highlighted-gd; background-color: $highlighted-gd-x-bg; } .gd {
color: $highlighted-gd;
background-color: $highlighted-gd-bg;
.x {
color: $highlighted-gd;
background-color: $highlighted-gd-x-bg;
}
}
.ge { font-style: italic; } .ge { font-style: italic; }
.gr { color: $highlighted-gr; } .gr { color: $highlighted-gr; }
.gh { color: $highlighted-gh; } .gh { color: $highlighted-gh; }
.gi { color: $highlighted-gi; background-color: $highlighted-gi-bg; }
.gi .x { color: $highlighted-gi; background-color: $highlighted-gi-x-bg; } .gi {
color: $highlighted-gi;
background-color: $highlighted-gi-bg;
.x {
color: $highlighted-gi;
background-color: $highlighted-gi-x-bg;
}
}
.go { color: $highlighted-go; } .go { color: $highlighted-go; }
.gp { color: $highlighted-gp; } .gp { color: $highlighted-gp; }
.gs { font-weight: $gl-font-weight-bold; } .gs { font-weight: $gl-font-weight-bold; }
......
...@@ -107,7 +107,7 @@ ...@@ -107,7 +107,7 @@
} }
.boards-list { .boards-list {
height: calc(100vh - 152px); height: calc(100vh - 105px);
width: 100%; width: 100%;
padding-top: 25px; padding-top: 25px;
padding-bottom: 25px; padding-bottom: 25px;
...@@ -116,8 +116,12 @@ ...@@ -116,8 +116,12 @@
overflow-x: scroll; overflow-x: scroll;
white-space: nowrap; white-space: nowrap;
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
height: calc(100vh - 222px); height: calc(100vh - 90px);
}
@media (min-width: $screen-md-min) {
height: calc(100vh - 160px);
min-height: 475px; min-height: 475px;
} }
} }
......
...@@ -68,18 +68,18 @@ ...@@ -68,18 +68,18 @@
&.affix { &.affix {
top: $header-height; top: $header-height;
}
// with sidebar // with sidebar
&.affix.sidebar-expanded { &.sidebar-expanded {
right: 306px; right: 306px;
left: 16px; left: 16px;
} }
// without sidebar // without sidebar
&.affix.sidebar-collapsed { &.sidebar-collapsed {
right: 16px; right: 16px;
left: 16px; left: 16px;
}
} }
&.affix-top { &.affix-top {
......
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
} }
} }
} }
svg {
width: 136px;
height: 136px;
}
} }
.col-headers { .col-headers {
...@@ -155,11 +160,6 @@ ...@@ -155,11 +160,6 @@
} }
} }
.landing svg {
width: 136px;
height: 136px;
}
.fa-spinner { .fa-spinner {
font-size: 28px; font-size: 28px;
position: relative; position: relative;
......
...@@ -380,6 +380,10 @@ ...@@ -380,6 +380,10 @@
} }
} }
} }
.line_content {
white-space: pre-wrap;
}
} }
.file-content .diff-file { .file-content .diff-file {
...@@ -387,10 +391,6 @@ ...@@ -387,10 +391,6 @@
border: 0; border: 0;
} }
.diff-file .line_content {
white-space: pre-wrap;
}
.diff-wrap-lines .line_content { .diff-wrap-lines .line_content {
white-space: pre-wrap; white-space: pre-wrap;
} }
......
...@@ -415,23 +415,6 @@ ...@@ -415,23 +415,6 @@
width: 100%; width: 100%;
padding: 0; padding: 0;
padding-bottom: 100%; padding-bottom: 100%;
}
.prometheus-svg-container > svg {
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
text {
fill: $gl-text-color;
stroke-width: 0;
}
.text-metric-bold {
font-weight: $gl-font-weight-bold;
}
.label-axis-text { .label-axis-text {
fill: $black; fill: $black;
...@@ -446,42 +429,51 @@ ...@@ -446,42 +429,51 @@
font-size: 12px; font-size: 12px;
} }
.legend-axis-text { > svg {
fill: $black; position: absolute;
} height: 100%;
width: 100%;
left: 0;
top: 0;
.tick { .label-axis-text,
> line { .text-metric-usage {
stroke: $gray-darker; fill: $black;
font-weight: $gl-font-weight-normal;
font-size: 12px;
} }
> text { .legend-axis-text {
font-size: 12px; fill: $black;
} }
}
.text-metric-title { .tick > text {
font-size: 12px; font-size: 12px;
} }
.y-label-text, .text-metric-title {
.x-label-text { font-size: 12px;
fill: $gray-darkest; }
}
.axis-tick { .y-label-text,
stroke: $gray-darker; .x-label-text {
} fill: $gray-darkest;
}
@media (max-width: $screen-sm-max) { .axis-tick {
.label-axis-text, stroke: $gray-darker;
.text-metric-usage,
.legend-axis-text {
font-size: 8px;
} }
.tick > text { @media (max-width: $screen-sm-max) {
font-size: 8px; .label-axis-text,
.text-metric-usage,
.legend-axis-text {
font-size: 8px;
}
.tick > text {
font-size: 8px;
}
} }
} }
} }
...@@ -127,7 +127,16 @@ ...@@ -127,7 +127,16 @@
} }
.right-sidebar { .right-sidebar {
a:not(.btn-retry), position: absolute;
top: $header-height;
bottom: 0;
right: 0;
transition: width .3s;
background: $gray-light;
z-index: 200;
overflow: hidden;
a,
.btn-link { .btn-link {
color: inherit; color: inherit;
} }
...@@ -228,17 +237,6 @@ ...@@ -228,17 +237,6 @@
.btn-clipboard:hover { .btn-clipboard:hover {
color: $gl-text-color; color: $gl-text-color;
} }
}
.right-sidebar {
position: absolute;
top: $header-height;
bottom: 0;
right: 0;
transition: width $right-sidebar-transition-duration;
background: $gray-light;
z-index: 200;
overflow: hidden;
.issuable-sidebar { .issuable-sidebar {
width: calc(100% + 100px); width: calc(100% + 100px);
......
...@@ -109,6 +109,30 @@ ...@@ -109,6 +109,30 @@
border-top-right-radius: $border-radius-default; border-top-right-radius: $border-radius-default;
border-top-left-radius: $border-radius-default; border-top-left-radius: $border-radius-default;
// Ldap configurations may need more tabs & the tab labels are user generated (arbitrarily long).
// These styles prevent this from breaking the layout, and only applied when providers are configured.
&.custom-provider-tabs {
flex-wrap: wrap;
li {
min-width: 85px;
flex-basis: auto;
// This styles tab elements that have wrapped to a second line. We cannot easily predict when this will happen.
// We are making somewhat of an assumption about the configuration here: that users do not have more than
// 3 LDAP servers configured (in addition to standard login) and they are not using especially long names for any
// of them. If either condition is false, this will work as expected. If both are true, there may be a missing border
// above one of the bottom row elements. If you know a better way, please implement it!
&:nth-child(n+5) {
border-top: 1px solid $border-color;
}
}
a {
font-size: 16px;
}
}
li { li {
flex: 1; flex: 1;
text-align: center; text-align: center;
...@@ -154,32 +178,6 @@ ...@@ -154,32 +178,6 @@
} }
} }
// Ldap configurations may need more tabs & the tab labels are user generated (arbitrarily long).
// These styles prevent this from breaking the layout, and only applied when providers are configured.
.new-session-tabs.custom-provider-tabs {
flex-wrap: wrap;
li {
min-width: 85px;
flex-basis: auto;
// This styles tab elements that have wrapped to a second line. We cannot easily predict when this will happen.
// We are making somewhat of an assumption about the configuration here: that users do not have more than
// 3 LDAP servers configured (in addition to standard login) and they are not using especially long names for any
// of them. If either condition is false, this will work as expected. If both are true, there may be a missing border
// above one of the bottom row elements. If you know a better way, please implement it!
&:nth-child(n+5) {
border-top: 1px solid $border-color;
}
}
a {
font-size: 16px;
}
}
.form-control { .form-control {
&:active, &:active,
&:focus { &:focus {
...@@ -231,35 +229,35 @@ ...@@ -231,35 +229,35 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 100%; height: 100%;
}
// Fixes footer container to bottom of viewport // Fixes footer container to bottom of viewport
.devise-layout-html body { body {
// offset height of fixed header + 1 to avoid scroll // offset height of fixed header + 1 to avoid scroll
height: calc(100% - 51px); height: calc(100% - 51px);
margin: 0; margin: 0;
padding: 0; padding: 0;
.page-wrap { .page-wrap {
min-height: 100%; min-height: 100%;
position: relative; position: relative;
} }
.footer-container, .footer-container,
hr.footer-fixed { hr.footer-fixed {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
height: 40px; height: 40px;
background: $white-light; background: $white-light;
} }
.navless-container { .navless-container {
padding: 65px 15px; // height of footer + bottom padding of email confirmation link padding: 65px 15px; // height of footer + bottom padding of email confirmation link
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
padding: 0 15px 65px; padding: 0 15px 65px;
}
} }
} }
} }
...@@ -55,9 +55,17 @@ ...@@ -55,9 +55,17 @@
width: auto; width: auto;
} }
} }
&.existing-title {
@media (min-width: $screen-sm-min) {
float: left;
}
}
} }
.member-form-control { .member-form-control {
@include new-style-dropdown;
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
padding-bottom: 5px; padding-bottom: 5px;
margin-left: 0; margin-left: 0;
...@@ -70,12 +78,6 @@ ...@@ -70,12 +78,6 @@
line-height: 43px; line-height: 43px;
} }
.member.existing-title {
@media (min-width: $screen-sm-min) {
float: left;
}
}
.member-search-form { .member-search-form {
@include new-style-dropdown; @include new-style-dropdown;
...@@ -331,7 +333,3 @@ ...@@ -331,7 +333,3 @@
} }
} }
} }
.member-form-control {
@include new-style-dropdown;
}
...@@ -155,6 +155,10 @@ ...@@ -155,6 +155,10 @@
&.media > *:first-child { &.media > *:first-child {
margin-right: 10px; margin-right: 10px;
} }
.approve-btn {
margin-right: 5px;
}
} }
.mr-widget-pipeline-graph { .mr-widget-pipeline-graph {
...@@ -190,6 +194,10 @@ ...@@ -190,6 +194,10 @@
overflow: hidden; overflow: hidden;
word-break: break-all; word-break: break-all;
&.media > *:first-child {
margin-right: 10px;
}
&.label-truncated { &.label-truncated {
position: relative; position: relative;
display: inline-block; display: inline-block;
...@@ -207,14 +215,7 @@ ...@@ -207,14 +215,7 @@
background-color: $gray-light; background-color: $gray-light;
} }
} }
}
.mr-widget-help {
padding: 10px 16px 10px 48px;
font-style: italic;
}
.mr-widget-body {
h4 { h4 {
float: left; float: left;
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
...@@ -237,6 +238,10 @@ ...@@ -237,6 +238,10 @@
margin-right: 7px; margin-right: 7px;
} }
.approve-btn {
margin-right: 5px;
}
label { label {
font-weight: $gl-font-weight-normal; font-weight: $gl-font-weight-normal;
} }
...@@ -329,6 +334,22 @@ ...@@ -329,6 +334,22 @@
} }
} }
.mini-pipeline-graph-dropdown-menu .mini-pipeline-graph-dropdown-item {
display: flex;
align-items: center;
.ci-status-text,
.ci-status-icon {
top: 0;
margin-right: 10px;
}
}
.mr-widget-help {
padding: 10px 16px 10px 48px;
font-style: italic;
}
.ci-coverage { .ci-coverage {
float: right; float: right;
} }
...@@ -347,10 +368,6 @@ ...@@ -347,10 +368,6 @@
flex-wrap: wrap; flex-wrap: wrap;
} }
.mr-widget-body-controls {
flex-wrap: wrap;
}
.mr_source_commit, .mr_source_commit,
.mr_target_commit { .mr_target_commit {
margin-bottom: 0; margin-bottom: 0;
...@@ -460,16 +477,16 @@ ...@@ -460,16 +477,16 @@
padding-bottom: 0; padding-bottom: 0;
} }
} }
}
.mr-info-list.mr-memory-usage { &.mr-memory-usage {
p { p {
float: left; float: left;
} }
.memory-graph-container { .memory-graph-container {
float: left; float: left;
margin-left: 5px; margin-left: 5px;
}
} }
} }
......
...@@ -66,6 +66,15 @@ ...@@ -66,6 +66,15 @@
height: 6px; height: 6px;
margin: 0; margin: 0;
} }
.sidebar-collapsed-icon {
clear: both;
padding: 15px 5px 5px;
.progress {
margin: 5px 0;
}
}
} }
.collapsed-milestone-date { .collapsed-milestone-date {
...@@ -93,17 +102,6 @@ ...@@ -93,17 +102,6 @@
margin-right: 0; margin-right: 0;
} }
.milestone-progress {
.sidebar-collapsed-icon {
clear: both;
padding: 15px 5px 5px;
.progress {
margin: 5px 0;
}
}
}
.right-sidebar-collapsed & { .right-sidebar-collapsed & {
.reference { .reference {
border-top: 1px solid $border-gray-normal; border-top: 1px solid $border-gray-normal;
...@@ -156,18 +154,16 @@ ...@@ -156,18 +154,16 @@
.status-box { .status-box {
margin-top: 0; margin-top: 0;
}
.milestone-buttons {
margin-left: auto;
}
.status-box {
order: 1; order: 1;
} }
.milestone-buttons { .milestone-buttons {
margin-left: auto;
order: 2; order: 2;
.verbose {
display: none;
}
} }
.header-text-content { .header-text-content {
...@@ -175,10 +171,6 @@ ...@@ -175,10 +171,6 @@
width: 100%; width: 100%;
} }
.milestone-buttons .verbose {
display: none;
}
@media (min-width: $screen-xs-min) { @media (min-width: $screen-xs-min) {
.milestone-buttons .verbose { .milestone-buttons .verbose {
display: inline; display: inline;
......
...@@ -111,24 +111,9 @@ ...@@ -111,24 +111,9 @@
margin: auto; margin: auto;
align-items: center; align-items: center;
.icon { .md-area {
margin-right: $issuable-warning-icon-margin; border-top-left-radius: 0;
} border-top-right-radius: 0;
}
.disabled-comment .issuable-note-warning {
border: 0;
border-radius: $label-border-radius;
padding-top: $gl-vert-padding;
padding-bottom: $gl-vert-padding;
.icon svg {
position: relative;
top: 2px;
margin-right: $btn-xs-side-margin;
width: $gl-font-size;
height: $gl-font-size;
fill: $orange-600;
} }
} }
...@@ -155,11 +140,6 @@ ...@@ -155,11 +140,6 @@
} }
} }
.issuable-note-warning + .md-area {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.discussion-form { .discussion-form {
background-color: $white-light; background-color: $white-light;
} }
......
...@@ -312,57 +312,72 @@ ul.notes { ...@@ -312,57 +312,72 @@ ul.notes {
} }
} }
.diff-file .notes_holder { .diff-file {
font-family: $regular_font; .is-over {
.add-diff-note {
display: inline-block;
}
}
td { // Merge request notes in diffs
border: 1px solid $white-normal; // Diff is inline
border-left: 0; .notes_content .note-header .note-headline-light {
display: inline-block;
position: relative;
}
&.notes_line { .notes_holder {
vertical-align: middle; font-family: $regular_font;
text-align: center;
padding: 10px 0;
background: $gray-light;
color: $text-color;
}
&.notes_line2 { td {
text-align: center; border: 1px solid $white-normal;
padding: 10px 0; border-left: 0;
border-left: 1px solid $note-line2-border !important;
}
&.notes_content { &.notes_line {
background-color: $gray-light; vertical-align: middle;
border-width: 1px 0; text-align: center;
padding: 0; padding: 10px 0;
vertical-align: top; background: $gray-light;
white-space: normal; color: $text-color;
}
&.parallel { &.notes_line2 {
border-width: 1px; text-align: center;
padding: 10px 0;
border-left: 1px solid $note-line2-border !important;
} }
.discussion-notes { &.notes_content {
&:not(:first-child) { background-color: $gray-light;
border-top: 1px solid $white-normal; border-width: 1px 0;
margin-top: 20px; padding: 0;
vertical-align: top;
white-space: normal;
&.parallel {
border-width: 1px;
} }
&:not(:last-child) { .discussion-notes {
border-bottom: 1px solid $white-normal; &:not(:first-child) {
margin-bottom: 20px; border-top: 1px solid $white-normal;
margin-top: 20px;
}
&:not(:last-child) {
border-bottom: 1px solid $white-normal;
margin-bottom: 20px;
}
} }
}
.notes { .notes {
background-color: $white-light; background-color: $white-light;
} }
a code { a code {
top: 0; top: 0;
margin-right: 0; margin-right: 0;
}
} }
} }
} }
...@@ -457,8 +472,9 @@ ul.notes { ...@@ -457,8 +472,9 @@ ul.notes {
margin-left: 10px; margin-left: 10px;
color: $gray-darkest; color: $gray-darkest;
.btn-group > .discussion-next-btn { @include notes-media('max', $screen-md-max) {
margin-left: -1px; float: none;
margin-left: 0;
} }
} }
...@@ -499,13 +515,6 @@ ul.notes { ...@@ -499,13 +515,6 @@ ul.notes {
min-width: 180px; min-width: 180px;
} }
.discussion-actions {
@include notes-media('max', $screen-md-max) {
float: none;
margin-left: 0;
}
}
.note-actions-item { .note-actions-item {
margin-left: 12px; margin-left: 12px;
display: flex; display: flex;
...@@ -662,14 +671,6 @@ ul.notes { ...@@ -662,14 +671,6 @@ ul.notes {
} }
} }
.diff-file {
.is-over {
.add-diff-note {
display: inline-block;
}
}
}
.disabled-comment { .disabled-comment {
background-color: $gray-light; background-color: $gray-light;
border-radius: $border-radius-base; border-radius: $border-radius-base;
...@@ -711,20 +712,20 @@ ul.notes { ...@@ -711,20 +712,20 @@ ul.notes {
svg path { svg path {
fill: $gray-darkest; fill: $gray-darkest;
} }
}
.btn.discussion-create-issue-btn { &.discussion-create-issue-btn {
margin-left: -4px; margin-left: -4px;
border-radius: 0; border-radius: 0;
border-right: 0; border-right: 0;
a { a {
padding: 0; padding: 0;
line-height: 0; line-height: 0;
&:hover { &:hover {
text-decoration: none; text-decoration: none;
border: 0; border: 0;
}
} }
} }
} }
...@@ -798,12 +799,3 @@ ul.notes { ...@@ -798,12 +799,3 @@ ul.notes {
.line-resolve-text { .line-resolve-text {
vertical-align: middle; vertical-align: middle;
} }
// Merge request notes in diffs
.diff-file {
// Diff is inline
.notes_content .note-header .note-headline-light {
display: inline-block;
position: relative;
}
}
...@@ -202,6 +202,25 @@ ...@@ -202,6 +202,25 @@
} }
} }
/**
* Play button with icon in dropdowns
*/
.no-btn {
border: 0;
background: none;
outline: none;
width: 100%;
text-align: left;
.icon-play {
position: relative;
top: 2px;
margin-right: 5px;
height: 13px;
width: 12px;
}
}
.duration, .duration,
.finished-at { .finished-at {
color: $gl-text-color-secondary; color: $gl-text-color-secondary;
...@@ -481,6 +500,9 @@ ...@@ -481,6 +500,9 @@
// Action Icons in big pipeline-graph nodes // Action Icons in big pipeline-graph nodes
.ci-action-icon-container.ci-action-icon-wrapper { .ci-action-icon-container.ci-action-icon-wrapper {
position: absolute;
right: 5px;
top: 5px;
height: 30px; height: 30px;
width: 30px; width: 30px;
background: $white-light; background: $white-light;
...@@ -491,6 +513,10 @@ ...@@ -491,6 +513,10 @@
&:hover { &:hover {
background-color: $stage-hover-bg; background-color: $stage-hover-bg;
border: 1px solid $dropdown-toggle-active-border-color; border: 1px solid $dropdown-toggle-active-border-color;
svg {
fill: $gl-text-color;
}
} }
svg { svg {
...@@ -509,16 +535,6 @@ ...@@ -509,16 +535,6 @@
left: 8px; left: 8px;
} }
} }
&:hover svg {
fill: $gl-text-color;
}
}
.ci-action-icon-container {
position: absolute;
right: 5px;
top: 5px;
} }
.ci-status-icon svg { .ci-status-icon svg {
...@@ -765,6 +781,28 @@ a.linked-pipeline-mini-item { ...@@ -765,6 +781,28 @@ a.linked-pipeline-mini-item {
left: -3px; left: -3px;
position: relative; position: relative;
top: -2px; top: -2px;
&.icon-action-stop,
&.icon-action-cancel {
width: 12px;
height: 12px;
top: 1px;
left: -1px;
}
&.icon-action-play {
width: 11px;
height: 11px;
top: 1px;
left: 1px;
}
&.icon-action-retry {
width: 16px;
height: 16px;
top: 0;
left: -3px;
}
} }
&:hover svg, &:hover svg,
...@@ -781,27 +819,6 @@ a.linked-pipeline-mini-item { ...@@ -781,27 +819,6 @@ a.linked-pipeline-mini-item {
} }
} }
svg.icon-action-stop,
svg.icon-action-cancel {
width: 12px;
height: 12px;
top: 1px;
left: -1px;
}
svg.icon-action-play {
width: 11px;
height: 11px;
top: 1px;
left: 1px;
}
svg.icon-action-retry {
width: 16px;
height: 16px;
top: 0;
left: -3px;
}
} }
...@@ -870,13 +887,10 @@ a.linked-pipeline-mini-item { ...@@ -870,13 +887,10 @@ a.linked-pipeline-mini-item {
left: 100%; left: 100%;
top: -10px; top: -10px;
box-shadow: 0 1px 5px $black-transparent; box-shadow: 0 1px 5px $black-transparent;
}
/**
* Top arrow in the dropdown in the big pipeline graph
*/
.big-pipeline-graph-dropdown-menu {
/**
* Top arrow in the dropdown in the big pipeline graph
*/
&::before, &::before,
&::after { &::after {
content: ''; content: '';
...@@ -938,22 +952,23 @@ a.linked-pipeline-mini-item { ...@@ -938,22 +952,23 @@ a.linked-pipeline-mini-item {
margin-top: 1px; margin-top: 1px;
border-bottom-color: $white-light; border-bottom-color: $white-light;
} }
}
/** /**
* Center dropdown menu in mini graph * Center dropdown menu in mini graph
*/ */
.mini-pipeline-graph-dropdown-menu.dropdown-menu { &.dropdown-menu {
transform: translate(-80%, 0); transform: translate(-80%, 0);
min-width: 150px; min-width: 150px;
@media(min-width: $screen-md-min) { @media(min-width: $screen-md-min) {
transform: translate(-50%, 0); transform: translate(-50%, 0);
right: auto; right: auto;
left: 50%; left: 50%;
min-width: 240px; min-width: 240px;
}
} }
} }
/** /**
* Terminal * Terminal
*/ */
...@@ -977,25 +992,6 @@ a.linked-pipeline-mini-item { ...@@ -977,25 +992,6 @@ a.linked-pipeline-mini-item {
} }
} }
/**
* Play button with icon in dropdowns
*/
.ci-table .no-btn {
border: 0;
background: none;
outline: none;
width: 100%;
text-align: left;
.icon-play {
position: relative;
top: 2px;
margin-right: 5px;
height: 13px;
width: 12px;
}
}
.linked-pipeline-mini-list { .linked-pipeline-mini-list {
display: inline-block; display: inline-block;
......
...@@ -96,7 +96,8 @@ ...@@ -96,7 +96,8 @@
transition: background 2s ease-out; transition: background 2s ease-out;
&:disabled { &:disabled {
opacity: 0.75; opacity: 0.5;
pointer-events: none;
} }
.highlight-changes & { .highlight-changes & {
...@@ -785,35 +786,35 @@ a.deploy-project-label { ...@@ -785,35 +786,35 @@ a.deploy-project-label {
.nav { .nav {
padding-top: 12px; padding-top: 12px;
padding-bottom: 12px; padding-bottom: 12px;
}
.nav > li { > li {
display: inline-block; display: inline-block;
&:not(:last-child) { &:not(:last-child) {
margin-right: $gl-padding; margin-right: $gl-padding;
} }
&.right { &.right {
vertical-align: top; vertical-align: top;
margin-top: 0; margin-top: 0;
@media (min-width: $screen-lg-min) { @media (min-width: $screen-lg-min) {
float: right; float: right;
}
} }
}
}
.nav > li > a { > a {
padding: 0; padding: 0;
background-color: transparent; background-color: transparent;
font-size: 14px; font-size: 14px;
line-height: 29px; line-height: 29px;
color: $notes-light-color; color: $notes-light-color;
&:hover, &:hover,
&:focus { &:focus {
color: $gl-text-color; color: $gl-text-color;
}
}
} }
} }
...@@ -1202,13 +1203,6 @@ a.allowed-to-push { ...@@ -1202,13 +1203,6 @@ a.allowed-to-push {
} }
} }
.project-repo-select {
&.disabled {
opacity: 0.5;
pointer-events: none;
}
}
.variables-table { .variables-table {
table-layout: fixed; table-layout: fixed;
......
...@@ -78,6 +78,10 @@ input[type="checkbox"]:hover { ...@@ -78,6 +78,10 @@ input[type="checkbox"]:hover {
} }
.search-input-wrap { .search-input-wrap {
// Fallback if flexbox is not supported
display: inline-block;
width: 100%;
.search-icon, .search-icon,
.clear-icon { .clear-icon {
position: absolute; position: absolute;
......
...@@ -266,11 +266,11 @@ ...@@ -266,11 +266,11 @@
margin-left: 5px; margin-left: 5px;
background: $badge-bg; background: $badge-bg;
} }
}
/* Ensure we don't add border if there's only single li */ /* Ensure we don't add border if there's only single li */
li + li { + li {
border-top: 1px solid $border-color; border-top: 1px solid $border-color;
}
} }
} }
} }
...@@ -5,10 +5,10 @@ table .sherlock-code { ...@@ -5,10 +5,10 @@ table .sherlock-code {
.sherlock-code { .sherlock-code {
pre { pre {
word-wrap: normal; word-wrap: normal;
}
pre code { code {
white-space: pre; white-space: pre;
}
} }
} }
...@@ -21,13 +21,13 @@ table .sherlock-code { ...@@ -21,13 +21,13 @@ table .sherlock-code {
text-align: right; text-align: right;
padding: 0 10px !important; padding: 0 10px !important;
} }
.slow {
color: $red-500;
font-weight: $gl-font-weight-bold;
}
} }
.sherlock-file-sample pre { .sherlock-file-sample pre {
padding-top: 28px !important; padding-top: 28px !important;
} }
.sherlock-line-samples-table .slow {
color: $red-500;
font-weight: $gl-font-weight-bold;
}
...@@ -40,16 +40,16 @@ ...@@ -40,16 +40,16 @@
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
width: 100%; width: 100%;
} }
}
.person .spark { .spark {
display: block; display: block;
background: $stat-graph-common-bg; background: $stat-graph-common-bg;
width: 100%; width: 100%;
} }
.person .area-contributor { .area-contributor {
fill: $stat-graph-orange-fill; fill: $stat-graph-orange-fill;
}
} }
} }
......
...@@ -161,10 +161,10 @@ ul.wiki-pages-list.content-list { ...@@ -161,10 +161,10 @@ ul.wiki-pages-list.content-list {
list-style: none; list-style: none;
margin-left: 0; margin-left: 0;
padding-left: 15px; padding-left: 15px;
}
ul li { li {
padding: 5px 0; padding: 5px 0;
}
} }
} }
......
...@@ -95,10 +95,9 @@ module LfsRequest ...@@ -95,10 +95,9 @@ module LfsRequest
@storage_project ||= begin @storage_project ||= begin
result = project result = project
loop do # TODO: Make this go to the fork_network root immeadiatly
break unless result.forked? # dependant on the discussion in: https://gitlab.com/gitlab-org/gitlab-ce/issues/39769
result = result.forked_from_project result = result.fork_source while result.forked?
end
result result
end end
......
...@@ -4,6 +4,7 @@ module NotesActions ...@@ -4,6 +4,7 @@ module NotesActions
included do included do
before_action :set_polling_interval_header, only: [:index] before_action :set_polling_interval_header, only: [:index]
before_action :noteable, only: :index
before_action :authorize_admin_note!, only: [:update, :destroy] before_action :authorize_admin_note!, only: [:update, :destroy]
before_action :note_project, only: [:create] before_action :note_project, only: [:create]
end end
...@@ -188,7 +189,7 @@ module NotesActions ...@@ -188,7 +189,7 @@ module NotesActions
end end
def noteable def noteable
@noteable ||= notes_finder.target @noteable ||= notes_finder.target || render_404
end end
def last_fetched_at def last_fetched_at
......
...@@ -112,7 +112,15 @@ module ProjectsHelper ...@@ -112,7 +112,15 @@ module ProjectsHelper
def remove_fork_project_message(project) def remove_fork_project_message(project)
_("You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?") % _("You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?") %
{ forked_from_project: @project.forked_from_project.name_with_namespace } { forked_from_project: fork_source_name(project) }
end
def fork_source_name(project)
if @project.fork_source
@project.fork_source.full_name
else
@project.fork_network&.deleted_root_project_name
end
end end
def project_nav_tabs def project_nav_tabs
...@@ -142,8 +150,8 @@ module ProjectsHelper ...@@ -142,8 +150,8 @@ module ProjectsHelper
def can_change_visibility_level?(project, current_user) def can_change_visibility_level?(project, current_user)
return false unless can?(current_user, :change_visibility_level, project) return false unless can?(current_user, :change_visibility_level, project)
if project.forked? if project.fork_source
project.forked_from_project.visibility_level > Gitlab::VisibilityLevel::PRIVATE project.fork_source.visibility_level > Gitlab::VisibilityLevel::PRIVATE
else else
true true
end end
......
...@@ -110,7 +110,7 @@ class Environment < ActiveRecord::Base ...@@ -110,7 +110,7 @@ class Environment < ActiveRecord::Base
end end
def ref_path def ref_path
"refs/#{Repository::REF_ENVIRONMENTS}/#{generate_slug}" "refs/#{Repository::REF_ENVIRONMENTS}/#{slug}"
end end
def formatted_external_url def formatted_external_url
...@@ -168,6 +168,10 @@ class Environment < ActiveRecord::Base ...@@ -168,6 +168,10 @@ class Environment < ActiveRecord::Base
end end
end end
def slug
super.presence || generate_slug
end
# An environment name is not necessarily suitable for use in URLs, DNS # An environment name is not necessarily suitable for use in URLs, DNS
# or other third-party contexts, so provide a slugified version. A slug has # or other third-party contexts, so provide a slugified version. A slug has
# the following properties: # the following properties:
......
...@@ -12,4 +12,8 @@ class ForkNetwork < ActiveRecord::Base ...@@ -12,4 +12,8 @@ class ForkNetwork < ActiveRecord::Base
def find_forks_in(other_projects) def find_forks_in(other_projects)
projects.where(id: other_projects) projects.where(id: other_projects)
end end
def merge_requests
MergeRequest.where(target_project: projects)
end
end end
...@@ -1039,6 +1039,10 @@ class Project < ActiveRecord::Base ...@@ -1039,6 +1039,10 @@ class Project < ActiveRecord::Base
!(forked_project_link.nil? || forked_project_link.forked_from_project.nil?) !(forked_project_link.nil? || forked_project_link.forked_from_project.nil?)
end end
def fork_source
forked_from_project || fork_network&.root_project
end
def personal? def personal?
!group !group
end end
...@@ -1488,7 +1492,8 @@ class Project < ActiveRecord::Base ...@@ -1488,7 +1492,8 @@ class Project < ActiveRecord::Base
{ key: 'CI_PROJECT_PATH', value: full_path, public: true }, { key: 'CI_PROJECT_PATH', value: full_path, public: true },
{ key: 'CI_PROJECT_PATH_SLUG', value: full_path_slug, public: true }, { key: 'CI_PROJECT_PATH_SLUG', value: full_path_slug, public: true },
{ key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path, public: true }, { key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path, public: true },
{ key: 'CI_PROJECT_URL', value: web_url, public: true } { key: 'CI_PROJECT_URL', value: web_url, public: true },
{ key: 'CI_PROJECT_VISIBILITY', value: Gitlab::VisibilityLevel.string_level(visibility_level), public: true }
] ]
end end
......
...@@ -3,18 +3,24 @@ module Projects ...@@ -3,18 +3,24 @@ module Projects
def execute def execute
return unless @project.forked? return unless @project.forked?
@project.forked_from_project.lfs_objects.find_each do |lfs_object| if fork_source = @project.fork_source
lfs_object.projects << @project fork_source.lfs_objects.find_each do |lfs_object|
lfs_object.projects << @project
end
refresh_forks_count(fork_source)
end end
merge_requests = @project.forked_from_project.merge_requests.opened.from_project(@project) merge_requests = @project.fork_network
.merge_requests
.opened
.where.not(target_project: @project)
.from_project(@project)
merge_requests.each do |mr| merge_requests.each do |mr|
::MergeRequests::CloseService.new(@project, @current_user).execute(mr) ::MergeRequests::CloseService.new(@project, @current_user).execute(mr)
end end
refresh_forks_count(@project.forked_from_project)
@project.fork_network_member.destroy @project.fork_network_member.destroy
@project.forked_project_link.destroy @project.forked_project_link.destroy
end end
......
- empty_repo = @project.empty_repo? - empty_repo = @project.empty_repo?
- fork_network = @project.fork_network - fork_network = @project.fork_network
- forked_from_project = @project.forked_from_project || fork_network&.root_project
.project-home-panel.text-center{ class: ("empty-project" if empty_repo) } .project-home-panel.text-center{ class: ("empty-project" if empty_repo) }
.limit-container-width{ class: container_class } .limit-container-width{ class: container_class }
.avatar-container.s70.project-avatar .avatar-container.s70.project-avatar
...@@ -16,13 +15,13 @@ ...@@ -16,13 +15,13 @@
- if @project.forked? - if @project.forked?
%p %p
- if forked_from_project - if @project.fork_source
#{ s_('ForkedFromProjectPath|Forked from') } #{ s_('ForkedFromProjectPath|Forked from') }
= link_to project_path(forked_from_project) do = link_to project_path(@project.fork_source) do
= forked_from_project.full_name = fork_source_name(@project)
- else - else
- deleted_message = s_('ForkedFromProjectPath|Forked from %{project_name} (deleted)') - deleted_message = s_('ForkedFromProjectPath|Forked from %{project_name} (deleted)')
= deleted_message % { project_name: fork_network.deleted_root_project_name } = deleted_message % { project_name: fork_source_name(@project) }
- if @project.mirror? - if @project.mirror?
- import_url = @project.safe_import_url - import_url = @project.safe_import_url
......
...@@ -185,7 +185,10 @@ ...@@ -185,7 +185,10 @@
%p %p
This will remove the fork relationship to source project This will remove the fork relationship to source project
= succeed "." do = succeed "." do
= link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project) - if @project.fork_source
= link_to(fork_source_name(@project), project_path(@project.fork_source))
- else
= fork_source_name(@project)
= form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_project_path(@project), method: :delete, remote: true, html: { class: 'transfer-project' }) do |f| = form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_project_path(@project), method: :delete, remote: true, html: { class: 'transfer-project' }) do |f|
%p %p
%strong Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source. %strong Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source.
......
---
title: Expose project visibility as CI variable - CI_PROJECT_VISIBILITY
merge_request: 15193
author:
type: added
---
title: Stop merge requests with thousands of commits from timing out
merge_request: 15063
author:
type: performance
---
title: Fix issues with forked projects of which the source was deleted
merge_request: 15150
author:
type: fixed
---
title: Enable MergeableSelector in scss-lint
merge_request: 12810
author: Takuya Noguchi
--- ---
title: Fix widget of locked merge requests not being presented title: Fix a migration that adds merge_requests_ff_only_enabled column to MR table
merge_request: merge_request:
author: author:
type: fixed type: fixed
--- ---
title: Adds callback functions for initial request in clusters page title: Render 404 when polling commit notes without having permissions
merge_request: merge_request:
author: author:
type: fixed type: fixed
--- ---
title: Normalize LDAP DN when looking up identity title: Avoid regenerating the ref path for the environment
merge_request: merge_request:
author: author:
type: fixed type: fixed
...@@ -615,7 +615,7 @@ production: &base ...@@ -615,7 +615,7 @@ production: &base
# Gitaly settings # Gitaly settings
gitaly: gitaly:
# Path to the directory containing Gitaly client executables. # Path to the directory containing Gitaly client executables.
client_path: /home/git/gitaly client_path: /home/git/gitaly/bin
# Default Gitaly authentication token. Can be overriden per storage. Can # Default Gitaly authentication token. Can be overriden per storage. Can
# be left blank when Gitaly is running locally on a Unix socket, which # be left blank when Gitaly is running locally on a Unix socket, which
# is the normal way to deploy Gitaly. # is the normal way to deploy Gitaly.
......
...@@ -8,7 +8,11 @@ class AddFastForwardOptionToProject < ActiveRecord::Migration ...@@ -8,7 +8,11 @@ class AddFastForwardOptionToProject < ActiveRecord::Migration
disable_ddl_transaction! disable_ddl_transaction!
def up def up
add_column_with_default(:projects, :merge_requests_ff_only_enabled, :boolean, default: false) # We put condition here because of a mistake we made a couple of years ago
# see https://gitlab.com/gitlab-org/gitlab-ce/issues/39382#note_45716103
unless column_exists?(:projects, :merge_requests_ff_only_enabled)
add_column_with_default(:projects, :merge_requests_ff_only_enabled, :boolean, default: false)
end
end end
def down def down
......
...@@ -67,6 +67,7 @@ future GitLab releases.** ...@@ -67,6 +67,7 @@ future GitLab releases.**
| **CI_PROJECT_PATH** | 8.10 | 0.5 | The namespace with project name | | **CI_PROJECT_PATH** | 8.10 | 0.5 | The namespace with project name |
| **CI_PROJECT_PATH_SLUG** | 9.3 | all | `$CI_PROJECT_PATH` lowercased and with everything except `0-9` and `a-z` replaced with `-`. Use in URLs and domain names. | | **CI_PROJECT_PATH_SLUG** | 9.3 | all | `$CI_PROJECT_PATH` lowercased and with everything except `0-9` and `a-z` replaced with `-`. Use in URLs and domain names. |
| **CI_PROJECT_URL** | 8.10 | 0.5 | The HTTP address to access project | | **CI_PROJECT_URL** | 8.10 | 0.5 | The HTTP address to access project |
| **CI_PROJECT_VISIBILITY** | 10.3 | all | The project visibility (internal, private, public) |
| **CI_REGISTRY** | 8.10 | 0.5 | If the Container Registry is enabled it returns the address of GitLab's Container Registry | | **CI_REGISTRY** | 8.10 | 0.5 | If the Container Registry is enabled it returns the address of GitLab's Container Registry |
| **CI_REGISTRY_IMAGE** | 8.10 | 0.5 | If the Container Registry is enabled for the project it returns the address of the registry tied to the specific project | | **CI_REGISTRY_IMAGE** | 8.10 | 0.5 | If the Container Registry is enabled for the project it returns the address of the registry tied to the specific project |
| **CI_REGISTRY_PASSWORD** | 9.0 | all | The password to use to push containers to the GitLab Container Registry | | **CI_REGISTRY_PASSWORD** | 9.0 | all | The password to use to push containers to the GitLab Container Registry |
......
...@@ -144,6 +144,12 @@ has a `.gitlab-ci.yml` or not: ...@@ -144,6 +144,12 @@ has a `.gitlab-ci.yml` or not:
All you need to do is remove your existing `.gitlab-ci.yml`, and you can even All you need to do is remove your existing `.gitlab-ci.yml`, and you can even
do that in a branch to test Auto DevOps before committing to `master`. do that in a branch to test Auto DevOps before committing to `master`.
NOTE: **Note:**
If you are a GitLab Administrator, you can enable Auto DevOps instance wide
in **Admin Area > Settings > Continuous Integration and Deployment**. Doing that,
all the projects that haven't explicitly set an option will have Auto DevOps
enabled by default.
## Stages of Auto DevOps ## Stages of Auto DevOps
The following sections describe the stages of Auto DevOps. Read them carefully The following sections describe the stages of Auto DevOps. Read them carefully
......
...@@ -46,14 +46,14 @@ module Gitlab ...@@ -46,14 +46,14 @@ module Gitlab
# Returns the current real time in a given precision. # Returns the current real time in a given precision.
# #
# Returns the time as a Float. # Returns the time as a Fixnum.
def self.real_time(precision = :millisecond) def self.real_time(precision = :millisecond)
Process.clock_gettime(Process::CLOCK_REALTIME, precision) Process.clock_gettime(Process::CLOCK_REALTIME, precision)
end end
# Returns the current monotonic clock time in a given precision. # Returns the current monotonic clock time in a given precision.
# #
# Returns the time as a Float. # Returns the time as a Fixnum.
def self.monotonic_time(precision = :millisecond) def self.monotonic_time(precision = :millisecond)
Process.clock_gettime(Process::CLOCK_MONOTONIC, precision) Process.clock_gettime(Process::CLOCK_MONOTONIC, precision)
end end
......
...@@ -36,7 +36,7 @@ module Gitlab ...@@ -36,7 +36,7 @@ module Gitlab
end end
def track_query(raw_query, bindings, start, finish) def track_query(raw_query, bindings, start, finish)
duration = finish - start duration = (finish - start) * 1000.0
query_info = { duration: duration.round(3), sql: raw_query } query_info = { duration: duration.round(3), sql: raw_query }
PEEK_DB_CLIENT.query_details << query_info PEEK_DB_CLIENT.query_details << query_info
......
...@@ -89,7 +89,9 @@ module Gitlab ...@@ -89,7 +89,9 @@ module Gitlab
ActiveSupport::Notifications.subscribe('sql.active_record') do |_, start, finish, _, data| ActiveSupport::Notifications.subscribe('sql.active_record') do |_, start, finish, _, data|
next unless same_thread? next unless same_thread?
track_query(data[:sql].strip, data[:binds], start, finish) unless data.fetch(:cached, data[:name] == 'CACHE')
track_query(data[:sql].strip, data[:binds], start, finish)
end
end end
end end
......
require 'spec_helper'
describe LfsRequest do
include ProjectForksHelper
controller(Projects::GitHttpClientController) do
# `described_class` is not available in this context
include LfsRequest # rubocop:disable RSpec/DescribedClass
def show
storage_project
render nothing: true
end
def project
@project ||= Project.find(params[:id])
end
def download_request?
true
end
def ci?
false
end
end
let(:project) { create(:project, :public) }
before do
stub_lfs_setting(enabled: true)
end
describe '#storage_project' do
it 'assigns the project as storage project' do
get :show, id: project.id
expect(assigns(:storage_project)).to eq(project)
end
it 'assigns the source of a forked project' do
forked_project = fork_project(project)
get :show, id: forked_project.id
expect(assigns(:storage_project)).to eq(project)
end
end
end
...@@ -105,6 +105,19 @@ describe Projects::NotesController do ...@@ -105,6 +105,19 @@ describe Projects::NotesController do
expect(note_json[:discussion_html]).to be_nil expect(note_json[:discussion_html]).to be_nil
expect(note_json[:diff_discussion_html]).to be_nil expect(note_json[:diff_discussion_html]).to be_nil
end end
context 'when user cannot read commit' do
before do
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user, :download_code, project).and_return(false)
end
it 'renders 404' do
get :index, params
expect(response).to have_gitlab_http_status(404)
end
end
end end
end end
......
require 'spec_helper'
feature 'Settings for a forked project', :js do
include ProjectForksHelper
let(:user) { create(:user) }
let(:original_project) { create(:project) }
let(:forked_project) { fork_project(original_project, user) }
before do
original_project.add_master(user)
forked_project.add_master(user)
sign_in(user)
end
shared_examples 'project settings for a forked projects' do
it 'allows deleting the link to the forked project' do
visit edit_project_path(forked_project)
click_button 'Remove fork relationship'
wait_for_requests
fill_in('confirm_name_input', with: forked_project.name)
click_button('Confirm')
expect(page).to have_content('The fork relationship has been removed.')
expect(forked_project.reload.forked?).to be_falsy
end
end
it_behaves_like 'project settings for a forked projects'
context 'when the original project is deleted' do
before do
original_project.destroy!
end
it_behaves_like 'project settings for a forked projects'
end
end
...@@ -77,8 +77,20 @@ describe Gitlab::Ci::CronParser do ...@@ -77,8 +77,20 @@ describe Gitlab::Ci::CronParser do
it_behaves_like "returns time in the future" it_behaves_like "returns time in the future"
it 'converts time in server time zone' do context 'when PST (Pacific Standard Time)' do
expect(subject.hour).to eq(hour_in_utc) it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 1, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end
context 'when PDT (Pacific Daylight Time)' do
it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 6, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end end
end end
end end
...@@ -100,8 +112,20 @@ describe Gitlab::Ci::CronParser do ...@@ -100,8 +112,20 @@ describe Gitlab::Ci::CronParser do
it_behaves_like "returns time in the future" it_behaves_like "returns time in the future"
it 'converts time in server time zone' do context 'when CET (Central European Time)' do
expect(subject.hour).to eq(hour_in_utc) it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 1, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end
context 'when CEST (Central European Summer Time)' do
it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 6, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end end
end end
...@@ -111,8 +135,20 @@ describe Gitlab::Ci::CronParser do ...@@ -111,8 +135,20 @@ describe Gitlab::Ci::CronParser do
it_behaves_like "returns time in the future" it_behaves_like "returns time in the future"
it 'converts time in server time zone' do context 'when EST (Eastern Standard Time)' do
expect(subject.hour).to eq(hour_in_utc) it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 1, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end
context 'when EDT (Eastern Daylight Time)' do
it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 6, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end end
end end
end end
......
...@@ -1290,6 +1290,7 @@ describe Ci::Build do ...@@ -1290,6 +1290,7 @@ describe Ci::Build do
{ key: 'CI_PROJECT_PATH_SLUG', value: project.full_path_slug, public: true }, { key: 'CI_PROJECT_PATH_SLUG', value: project.full_path_slug, public: true },
{ key: 'CI_PROJECT_NAMESPACE', value: project.namespace.full_path, public: true }, { key: 'CI_PROJECT_NAMESPACE', value: project.namespace.full_path, public: true },
{ key: 'CI_PROJECT_URL', value: project.web_url, public: true }, { key: 'CI_PROJECT_URL', value: project.web_url, public: true },
{ key: 'CI_PROJECT_VISIBILITY', value: 'private', public: true },
{ key: 'CI_PIPELINE_ID', value: pipeline.id.to_s, public: true }, { key: 'CI_PIPELINE_ID', value: pipeline.id.to_s, public: true },
{ key: 'CI_CONFIG_PATH', value: pipeline.ci_yaml_file_path, public: true }, { key: 'CI_CONFIG_PATH', value: pipeline.ci_yaml_file_path, public: true },
{ key: 'CI_REGISTRY_USER', value: 'gitlab-ci-token', public: true }, { key: 'CI_REGISTRY_USER', value: 'gitlab-ci-token', public: true },
......
...@@ -635,6 +635,15 @@ describe Environment do ...@@ -635,6 +635,15 @@ describe Environment do
expect(environment.slug).to eq(original_slug) expect(environment.slug).to eq(original_slug)
end end
it "regenerates the slug if nil" do
environment = build(:environment, slug: nil)
new_slug = environment.slug
expect(new_slug).not_to be_nil
expect(environment.slug).to eq(new_slug)
end
end end
describe '#generate_slug' do describe '#generate_slug' do
...@@ -671,6 +680,12 @@ describe Environment do ...@@ -671,6 +680,12 @@ describe Environment do
it 'returns a path that uses the slug and does not have spaces' do it 'returns a path that uses the slug and does not have spaces' do
expect(environment.ref_path).to start_with('refs/environments/staging-review-1-') expect(environment.ref_path).to start_with('refs/environments/staging-review-1-')
end end
it "doesn't change when the slug is nil initially" do
environment.slug = nil
expect(environment.ref_path).to eq(environment.ref_path)
end
end end
describe '#external_url_for' do describe '#external_url_for' do
......
...@@ -24,6 +24,16 @@ describe ForkNetwork do ...@@ -24,6 +24,16 @@ describe ForkNetwork do
end end
end end
describe '#merge_requests' do
it 'finds merge requests within the fork network' do
project = create(:project)
forked_project = fork_project(project)
merge_request = create(:merge_request, source_project: forked_project, target_project: project)
expect(project.fork_network.merge_requests).to include(merge_request)
end
end
context 'for a deleted project' do context 'for a deleted project' do
it 'keeps the fork network' do it 'keeps the fork network' do
project = create(:project, :public) project = create(:project, :public)
......
...@@ -2256,6 +2256,20 @@ describe Project do ...@@ -2256,6 +2256,20 @@ describe Project do
expect(forked_project.in_fork_network_of?(other_project)).to be_falsy expect(forked_project.in_fork_network_of?(other_project)).to be_falsy
end end
end end
describe '#fork_source' do
let!(:second_fork) { fork_project(forked_project) }
it 'returns the direct source if it exists' do
expect(second_fork.fork_source).to eq(forked_project)
end
it 'returns the root of the fork network when the directs source was deleted' do
forked_project.destroy
expect(second_fork.fork_source).to eq(project)
end
end
end end
describe '#pushes_since_gc' do describe '#pushes_since_gc' do
......
...@@ -12,6 +12,9 @@ describe Projects::UnlinkForkService do ...@@ -12,6 +12,9 @@ describe Projects::UnlinkForkService do
context 'with opened merge request on the source project' do context 'with opened merge request on the source project' do
let(:merge_request) { create(:merge_request, source_project: forked_project, target_project: fork_link.forked_from_project) } let(:merge_request) { create(:merge_request, source_project: forked_project, target_project: fork_link.forked_from_project) }
let(:merge_request2) { create(:merge_request, source_project: forked_project, target_project: fork_project(project)) }
let(:merge_request_in_fork) { create(:merge_request, source_project: forked_project, target_project: forked_project) }
let(:mr_close_service) { MergeRequests::CloseService.new(forked_project, user) } let(:mr_close_service) { MergeRequests::CloseService.new(forked_project, user) }
before do before do
...@@ -22,9 +25,14 @@ describe Projects::UnlinkForkService do ...@@ -22,9 +25,14 @@ describe Projects::UnlinkForkService do
it 'close all pending merge requests' do it 'close all pending merge requests' do
expect(mr_close_service).to receive(:execute).with(merge_request) expect(mr_close_service).to receive(:execute).with(merge_request)
expect(mr_close_service).to receive(:execute).with(merge_request2)
subject.execute subject.execute
end end
it 'does not close merge requests for the project being unlinked' do
expect(mr_close_service).not_to receive(:execute).with(merge_request_in_fork)
end
end end
it 'remove fork relation' do it 'remove fork relation' do
...@@ -53,4 +61,14 @@ describe Projects::UnlinkForkService do ...@@ -53,4 +61,14 @@ describe Projects::UnlinkForkService do
expect(source.forks_count).to be_zero expect(source.forks_count).to be_zero
end end
context 'when the original project was deleted' do
it 'does not fail when the original project is deleted' do
source = forked_project.forked_from_project
source.destroy
forked_project.reload
expect { subject.execute }.not_to raise_error
end
end
end end
...@@ -48,6 +48,10 @@ module StubConfiguration ...@@ -48,6 +48,10 @@ module StubConfiguration
allow(Gitlab.config.backup).to receive_messages(to_settings(messages)) allow(Gitlab.config.backup).to receive_messages(to_settings(messages))
end end
def stub_lfs_setting(messages)
allow(Gitlab.config.lfs).to receive_messages(to_settings(messages))
end
def stub_storage_settings(messages) def stub_storage_settings(messages)
# Default storage is always required # Default storage is always required
messages['default'] ||= Gitlab.config.repositories.storages.default messages['default'] ||= Gitlab.config.repositories.storages.default
......
/*
* This is a modified version of https://github.com/peek/peek/blob/master/app/assets/javascripts/peek.js
*
* - Removed the dependency on jquery.tipsy
* - Removed the initializeTipsy and toggleBar functions
* - Customized updatePerformanceBar to handle SQL queries report specificities
* - Changed /peek/results to /-/peek/results
* - Removed the keypress, pjax:end, page:change, and turbolinks:load handlers
*/
(function($) { (function($) {
var fetchRequestResults, getRequestId, peekEnabled, toggleBar, updatePerformanceBar; var fetchRequestResults, getRequestId, peekEnabled, updatePerformanceBar;
getRequestId = function() { getRequestId = function() {
return $('#peek').data('request-id'); return $('#peek').data('request-id');
}; };
...@@ -41,22 +50,6 @@ ...@@ -41,22 +50,6 @@
}); });
return $(document).trigger('peek:render', [getRequestId(), results]); return $(document).trigger('peek:render', [getRequestId(), results]);
}; };
toggleBar = function(event) {
var wrapper;
if ($(event.target).is(':input')) {
return;
}
if (event.which === 96 && !event.metaKey) {
wrapper = $('#peek');
if (wrapper.hasClass('disabled')) {
wrapper.removeClass('disabled');
return document.cookie = "peek=true; path=/";
} else {
wrapper.addClass('disabled');
return document.cookie = "peek=false; path=/";
}
}
};
fetchRequestResults = function() { fetchRequestResults = function() {
return $.ajax('/-/peek/results', { return $.ajax('/-/peek/results', {
data: { data: {
...@@ -68,7 +61,6 @@ ...@@ -68,7 +61,6 @@
error: function(xhr, textStatus, error) {} error: function(xhr, textStatus, error) {}
}); });
}; };
$(document).on('keypress', toggleBar);
$(document).on('peek:update', fetchRequestResults); $(document).on('peek:update', fetchRequestResults);
return $(function() { return $(function() {
if (peekEnabled()) { if (peekEnabled()) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment