Commit 51b4241b authored by Ruben Davila's avatar Ruben Davila

Merge remote-tracking branch 'ce/master' into ce-to-ee

Conflicts:
	app/assets/javascripts/project_new.js
	app/views/projects/_merge_request_settings.html.haml
	spec/javascripts/datetime_utility_spec.js.coffee
parents 513ff0ce 2aaab34b
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
(What you should see instead) (What you should see instead)
### Actual behaviour ### Actual behavior
(What actually happens) (What actually happens)
......
...@@ -6,6 +6,7 @@ v 8.11.1 ...@@ -6,6 +6,7 @@ v 8.11.1
- Fix file links on project page when default view is Files !5933 - Fix file links on project page when default view is Files !5933
- Fixed enter key in search input not working !5888 - Fixed enter key in search input not working !5888
v 8.12.0 (unreleased) v 8.12.0 (unreleased)
- Prepend blank line to `Closes` message on merge request linked to issue (lukehowell)
- Filter tags by name !6121 - Filter tags by name !6121
- Make push events have equal vertical spacing. - Make push events have equal vertical spacing.
- Add two-factor recovery endpoint to internal API !5510 - Add two-factor recovery endpoint to internal API !5510
...@@ -20,11 +21,14 @@ v 8.12.0 (unreleased) ...@@ -20,11 +21,14 @@ v 8.12.0 (unreleased)
- Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling) - Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling)
- Fix bug where pagination is still displayed despite all todos marked as done (ClemMakesApps) - Fix bug where pagination is still displayed despite all todos marked as done (ClemMakesApps)
- Center build stage columns in pipeline overview (ClemMakesApps) - Center build stage columns in pipeline overview (ClemMakesApps)
- Rename behaviour to behavior in bug issue template for consistency (ClemMakesApps)
- Remove suggested colors hover underline (ClemMakesApps)
- Shorten task status phrase (ClemMakesApps) - Shorten task status phrase (ClemMakesApps)
- Add hover color to emoji icon (ClemMakesApps) - Add hover color to emoji icon (ClemMakesApps)
- Fix branches page dropdown sort alignment (ClemMakesApps) - Fix branches page dropdown sort alignment (ClemMakesApps)
- Add white background for no readme container (ClemMakesApps) - Add white background for no readme container (ClemMakesApps)
- API: Expose issue confidentiality flag. (Robert Schilling) - API: Expose issue confidentiality flag. (Robert Schilling)
- Fix markdown anchor icon interaction (ClemMakesApps)
- Optimistic locking for Issues and Merge Requests (title and description overriding prevention) - Optimistic locking for Issues and Merge Requests (title and description overriding prevention)
- Add `wiki_page_events` to project hook APIs (Ben Boeckel) - Add `wiki_page_events` to project hook APIs (Ben Boeckel)
- Remove Gitorious import - Remove Gitorious import
...@@ -46,12 +50,14 @@ v 8.12.0 (unreleased) ...@@ -46,12 +50,14 @@ v 8.12.0 (unreleased)
- Remove redundant js-timeago-pending from user activity log (ClemMakesApps) - Remove redundant js-timeago-pending from user activity log (ClemMakesApps)
- Ability to manage project issues, snippets, wiki, merge requests and builds access level - Ability to manage project issues, snippets, wiki, merge requests and builds access level
- Remove inconsistent font weight for sidebar's labels (ClemMakesApps) - Remove inconsistent font weight for sidebar's labels (ClemMakesApps)
- Align add button on repository view (ClemMakesApps)
- Added tests for diff notes - Added tests for diff notes
- Add a button to download latest successful artifacts for branches and tags !5142 - Add a button to download latest successful artifacts for branches and tags !5142
- Remove redundant pipeline tooltips (ClemMakesApps) - Remove redundant pipeline tooltips (ClemMakesApps)
- Expire commit info views after one day, instead of two weeks, to allow for user email updates - Expire commit info views after one day, instead of two weeks, to allow for user email updates
- Add delimiter to project stars and forks count (ClemMakesApps) - Add delimiter to project stars and forks count (ClemMakesApps)
- Fix badge count alignment (ClemMakesApps) - Fix badge count alignment (ClemMakesApps)
- Remove green outline from `New branch unavailable` button on issue page !5858 (winniehell)
- Fix repo title alignment (ClemMakesApps) - Fix repo title alignment (ClemMakesApps)
- Fix branch title trailing space on hover (ClemMakesApps) - Fix branch title trailing space on hover (ClemMakesApps)
- Award emoji tooltips containing more than 10 usernames are now truncated !4780 (jlogandavison) - Award emoji tooltips containing more than 10 usernames are now truncated !4780 (jlogandavison)
...@@ -63,11 +69,13 @@ v 8.12.0 (unreleased) ...@@ -63,11 +69,13 @@ v 8.12.0 (unreleased)
- Move to project dropdown with infinite scroll for better performance - Move to project dropdown with infinite scroll for better performance
- Fix leaking of submit buttons outside the width of a main container !18731 (originally by @pavelloz) - Fix leaking of submit buttons outside the width of a main container !18731 (originally by @pavelloz)
- Load branches asynchronously in Cherry Pick and Revert dialogs. - Load branches asynchronously in Cherry Pick and Revert dialogs.
- Convert datetime coffeescript spec to ES6 (ClemMakesApps)
- Add merge request versions !5467 - Add merge request versions !5467
- Change using size to use count and caching it for number of group members. !5935 - Change using size to use count and caching it for number of group members. !5935
- Replace play icon font with svg (ClemMakesApps) - Replace play icon font with svg (ClemMakesApps)
- Added 'only_allow_merge_if_build_succeeds' project setting in the API. !5930 (Duck) - Added 'only_allow_merge_if_build_succeeds' project setting in the API. !5930 (Duck)
- Reduce number of database queries on builds tab - Reduce number of database queries on builds tab
- Wrap text in commit message containers
- Capitalize mentioned issue timeline notes (ClemMakesApps) - Capitalize mentioned issue timeline notes (ClemMakesApps)
- Fix inconsistent checkbox alignment (ClemMakesApps) - Fix inconsistent checkbox alignment (ClemMakesApps)
- Use the default branch for displaying the project icon instead of master !5792 (Hannes Rosenögger) - Use the default branch for displaying the project icon instead of master !5792 (Hannes Rosenögger)
...@@ -75,10 +83,13 @@ v 8.12.0 (unreleased) ...@@ -75,10 +83,13 @@ v 8.12.0 (unreleased)
- Fix hover leading space bug in pipeline graph !5980 - Fix hover leading space bug in pipeline graph !5980
- User can edit closed MR with deleted fork (Katarzyna Kobierska Ula Budziszewska) !5496 - User can edit closed MR with deleted fork (Katarzyna Kobierska Ula Budziszewska) !5496
- Fixed invisible scroll controls on build page on iPhone - Fixed invisible scroll controls on build page on iPhone
- Fix error on raw build trace download for old builds stored in database !4822
v 8.11.5 (unreleased) v 8.11.5 (unreleased)
- Optimize branch lookups and force a repository reload for Repository#find_branch - Optimize branch lookups and force a repository reload for Repository#find_branch
- Fix member expiration date picker after update
- Fix suggested colors options for new labels in the admin area. !6138 - Fix suggested colors options for new labels in the admin area. !6138
- Fix GitLab import button
v 8.11.4 v 8.11.4
- Fix resolving conflicts on forks. !6082 - Fix resolving conflicts on forks. !6082
...@@ -177,6 +188,7 @@ v 8.11.0 ...@@ -177,6 +188,7 @@ v 8.11.0
- Get issue and merge request description templates from repositories - Get issue and merge request description templates from repositories
- Add hover state to todos !5361 (winniehell) - Add hover state to todos !5361 (winniehell)
- Fix icon alignment of star and fork buttons !5451 (winniehell) - Fix icon alignment of star and fork buttons !5451 (winniehell)
- Fix alignment of icon buttons !5887 (winniehell)
- Enforce 2FA restrictions on API authentication endpoints !5820 - Enforce 2FA restrictions on API authentication endpoints !5820
- Limit git rev-list output count to one in forced push check - Limit git rev-list output count to one in forced push check
- Show deployment status on merge requests with external URLs - Show deployment status on merge requests with external URLs
......
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="#333" fill-rule="evenodd" d="M9.683 6.676l-.047-.048C8.27 5.26 6.07 5.243 4.726 6.588l-2.29 2.29c-1.344 1.344-1.328 3.544.04 4.91 1.366 1.368 3.564 1.385 4.908.04l1.753-1.752c-.695.074-1.457-.078-2.176-.444L5.934 12.66c-.634.634-1.67.625-2.312-.017-.642-.643-.65-1.677-.017-2.312L6.035 7.9c.634-.634 1.67-.625 2.312.017.024.024.048.05.07.075l.003-.002c.36.36.943.366 1.3.01.355-.356.35-.938-.01-1.3l-.027-.024zM6.58 9.586l.048.05c1.367 1.366 3.565 1.384 4.91.04l2.29-2.292c1.344-1.343 1.328-3.542-.04-4.91-1.366-1.366-3.564-1.384-4.908-.04L7.127 4.187c.695-.074 1.457.078 2.176.444l1.028-1.027c.635-.634 1.67-.624 2.313.017.643.644.652 1.678.018 2.312l-2.43 2.432c-.635.634-1.67.624-2.313-.018-.024-.024-.048-.05-.07-.075l-.003.004c-.36-.362-.943-.367-1.3-.01-.355.355-.35.937.01 1.3.01.007.018.015.027.023z"/></svg>
\ No newline at end of file
...@@ -127,7 +127,7 @@ ...@@ -127,7 +127,7 @@
Issue.prototype.initCanCreateBranch = function() { Issue.prototype.initCanCreateBranch = function() {
var $container; var $container;
$container = $('div#new-branch'); $container = $('#new-branch');
if ($container.length === 0) { if ($container.length === 0) {
return; return;
} }
...@@ -139,7 +139,6 @@ ...@@ -139,7 +139,6 @@
if (data.can_create_branch) { if (data.can_create_branch) {
$container.find('.checking').hide(); $container.find('.checking').hide();
$container.find('.available').show(); $container.find('.available').show();
return $container.find('a').attr('disabled', false);
} else { } else {
$container.find('.checking').hide(); $container.find('.checking').hide();
return $container.find('.unavailable').show(); return $container.find('.unavailable').show();
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
this.ProjectNew = (function() { this.ProjectNew = (function() {
function ProjectNew() { function ProjectNew() {
this.toggleSettings = bind(this.toggleSettings, this); this.toggleSettings = bind(this.toggleSettings, this);
this.$selects = $('.features select');
$('.project-edit-container').on('ajax:before', (function(_this) { $('.project-edit-container').on('ajax:before', (function(_this) {
return function() { return function() {
$('.project-edit-container').hide(); $('.project-edit-container').hide();
...@@ -15,6 +17,7 @@ ...@@ -15,6 +17,7 @@
} }
ProjectNew.prototype.toggleSettings = function() { ProjectNew.prototype.toggleSettings = function() {
<<<<<<< HEAD
this._showOrHide('#project_builds_enabled', '.builds-feature'); this._showOrHide('#project_builds_enabled', '.builds-feature');
this._showOrHide('#project_merge_requests_enabled', '.merge-requests-feature'); this._showOrHide('#project_merge_requests_enabled', '.merge-requests-feature');
return this._showOrHide('#project_issues_enabled', '.issues-feature'); return this._showOrHide('#project_issues_enabled', '.issues-feature');
...@@ -22,12 +25,26 @@ ...@@ -22,12 +25,26 @@
ProjectNew.prototype.toggleSettingsOnclick = function() { ProjectNew.prototype.toggleSettingsOnclick = function() {
return $('#project_builds_enabled, #project_merge_requests_enabled, #project_issues_enabled').on('click', this.toggleSettings); return $('#project_builds_enabled, #project_merge_requests_enabled, #project_issues_enabled').on('click', this.toggleSettings);
=======
var self = this;
this.$selects.each(function () {
var $select = $(this),
className = $select.data('field').replace(/_/g, '-')
.replace('access-level', 'feature');
self._showOrHide($select, '.' + className);
});
};
ProjectNew.prototype.toggleSettingsOnclick = function() {
this.$selects.on('change', this.toggleSettings);
>>>>>>> ce/master
}; };
ProjectNew.prototype._showOrHide = function(checkElement, container) { ProjectNew.prototype._showOrHide = function(checkElement, container) {
var $container; var $container = $(container);
$container = $(container);
if ($(checkElement).prop('checked')) { if ($(checkElement).val() !== '0') {
return $container.show(); return $container.show();
} else { } else {
return $container.hide(); return $container.hide();
......
...@@ -206,7 +206,9 @@ ...@@ -206,7 +206,9 @@
} }
svg, .fa { svg, .fa {
margin-right: 3px; &:not(:last-child) {
margin-right: 3px;
}
} }
} }
......
...@@ -53,7 +53,7 @@ pre { ...@@ -53,7 +53,7 @@ pre {
&.well-pre { &.well-pre {
border: 1px solid #eee; border: 1px solid #eee;
background: #f9f9f9; background: $gray-light;
border-radius: 0; border-radius: 0;
color: #555; color: #555;
} }
...@@ -225,7 +225,7 @@ li.note { ...@@ -225,7 +225,7 @@ li.note {
.milestone { .milestone {
&.milestone-closed { &.milestone-closed {
background: #f9f9f9; background: $gray-light;
} }
.progress { .progress {
margin-bottom: 0; margin-bottom: 0;
......
...@@ -115,7 +115,7 @@ ...@@ -115,7 +115,7 @@
padding: 0; padding: 0;
} }
td.blame-commit { td.blame-commit {
background: #f9f9f9; background: $gray-light;
min-width: 350px; min-width: 350px;
.commit-author-link { .commit-author-link {
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
} }
&.active { &.active {
background: #f9f9f9; background: $gray-light;
a { a {
font-weight: 600; font-weight: 600;
} }
......
...@@ -125,7 +125,7 @@ $panel-inner-border: $border-color; ...@@ -125,7 +125,7 @@ $panel-inner-border: $border-color;
// //
//## //##
$well-bg: #f9f9f9; $well-bg: $gray-light;
$well-border: #eee; $well-border: #eee;
//== Code //== Code
......
...@@ -159,25 +159,18 @@ ...@@ -159,25 +159,18 @@
position: relative; position: relative;
a.anchor { a.anchor {
// Setting `display: none` would prevent the anchor being scrolled to, so left: -16px;
// instead we set the height to 0 and it gets updated on hover. position: absolute;
height: 0; text-decoration: none;
&:after {
content: url('icon_anchor.svg');
visibility: hidden;
}
} }
&:hover > a.anchor { &:hover > a.anchor:after {
$size: 14px; visibility: visible;
position: absolute;
right: 100%;
top: 50%;
margin-top: -11px;
margin-right: 0;
padding-right: 15px;
display: inline-block;
width: $size;
height: $size;
background-image: image-url("icon-link.png");
background-size: contain;
background-repeat: no-repeat;
} }
} }
} }
......
...@@ -9,13 +9,79 @@ $gutter_inner_width: 258px; ...@@ -9,13 +9,79 @@ $gutter_inner_width: 258px;
$sidebar-transition-duration: .15s; $sidebar-transition-duration: .15s;
$sidebar-breakpoint: 1024px; $sidebar-breakpoint: 1024px;
/*
* Color schema
*/
$white-light: #fff;
$white-normal: #ededed;
$white-dark: #ececec;
$gray-light: #fafafa;
$gray-normal: #f5f5f5;
$gray-dark: #ededed;
$gray-darkest: #c9c9c9;
$green-light: #38ae67;
$green-normal: #2faa60;
$green-dark: #2ca05b;
$blue-light: #2ea8e5;
$blue-normal: #2d9fd8;
$blue-dark: #2897ce;
$blue-medium-light: #3498cb;
$blue-medium: #2f8ebf;
$blue-medium-dark: #2d86b4;
$orange-light: #fc8a51;
$orange-normal: #e75e40;
$orange-dark: #ce5237;
$red-light: #e52c5a;
$red-normal: #d22852;
$red-dark: darken($red-normal, 5%);
$black: #000;
$black-transparent: rgba(0, 0, 0, 0.3);
$border-white-light: #f1f2f4;
$border-white-normal: #d6dae2;
$border-white-dark: #c6cacf;
$border-gray-light: #dcdcdc;
$border-gray-normal: #d7d7d7;
$border-gray-dark: #c6cacf;
$border-green-light: #2faa60;
$border-green-normal: #2ca05b;
$border-green-dark: #279654;
$border-blue-light: #2d9fd8;
$border-blue-normal: #2897ce;
$border-blue-dark: #258dc1;
$border-orange-light: #fc6d26;
$border-orange-normal: #ce5237;
$border-orange-dark: #c14e35;
$border-red-light: #d22852;
$border-red-normal: #ca264f;
$border-red-dark: darken($border-red-normal, 5%);
$help-well-bg: $gray-light;
$help-well-border: #e5e5e5;
$warning-message-bg: #fbf2d9;
$warning-message-color: #9e8e60;
$warning-message-border: #f0e2bb;
/* /*
* UI elements * UI elements
*/ */
$border-color: #e5e5e5; $border-color: #e5e5e5;
$focus-border-color: #3aabf0; $focus-border-color: #3aabf0;
$table-border-color: #f0f0f0; $table-border-color: #f0f0f0;
$background-color: #fafafa; $background-color: $gray-light;
$dark-background-color: #f5f5f5; $dark-background-color: #f5f5f5;
$table-text-gray: #8f8f8f; $table-text-gray: #8f8f8f;
...@@ -90,73 +156,6 @@ $btn-side-margin: 10px; ...@@ -90,73 +156,6 @@ $btn-side-margin: 10px;
$btn-sm-side-margin: 7px; $btn-sm-side-margin: 7px;
$btn-xs-side-margin: 5px; $btn-xs-side-margin: 5px;
/*
* Color schema
*/
$white-light: #fff;
$white-normal: #ededed;
$white-dark: #ececec;
$gray-light: #faf9f9;
$gray-normal: #f5f5f5;
$gray-dark: #ededed;
$gray-darkest: #c9c9c9;
$green-light: #38ae67;
$green-normal: #2faa60;
$green-dark: #2ca05b;
$blue-light: #2ea8e5;
$blue-normal: #2d9fd8;
$blue-dark: #2897ce;
$blue-medium-light: #3498cb;
$blue-medium: #2f8ebf;
$blue-medium-dark: #2d86b4;
$orange-light: #fc8a51;
$orange-normal: #e75e40;
$orange-dark: #ce5237;
$red-light: #e52c5a;
$red-normal: #d22852;
$red-dark: darken($red-normal, 5%);
$black: #000;
$black-transparent: rgba(0, 0, 0, 0.3);
$border-white-light: #f1f2f4;
$border-white-normal: #d6dae2;
$border-white-dark: #c6cacf;
$border-gray-light: #dcdcdc;
$border-gray-normal: #d7d7d7;
$border-gray-dark: #c6cacf;
$border-green-light: #2faa60;
$border-green-normal: #2ca05b;
$border-green-dark: #279654;
$border-blue-light: #2d9fd8;
$border-blue-normal: #2897ce;
$border-blue-dark: #258dc1;
$border-orange-light: #fc6d26;
$border-orange-normal: #ce5237;
$border-orange-dark: #c14e35;
$border-red-light: #d22852;
$border-red-normal: #ca264f;
$border-red-dark: darken($border-red-normal, 5%);
$help-well-bg: #fafafa;
$help-well-border: #e5e5e5;
$warning-message-bg: #fbf2d9;
$warning-message-color: #9e8e60;
$warning-message-border: #f0e2bb;
/* tanuki logo colors */ /* tanuki logo colors */
$tanuki-red: #e24329; $tanuki-red: #e24329;
$tanuki-orange: #fc6d26; $tanuki-orange: #fc6d26;
...@@ -186,7 +185,7 @@ $line-removed-dark: #fac5cd; ...@@ -186,7 +185,7 @@ $line-removed-dark: #fac5cd;
$line-number-old: #f9d7dc; $line-number-old: #f9d7dc;
$line-number-new: #ddfbe6; $line-number-new: #ddfbe6;
$line-number-select: #fbf2da; $line-number-select: #fbf2da;
$match-line: #fafafa; $match-line: $gray-light;
$table-border-gray: #f0f0f0; $table-border-gray: #f0f0f0;
$line-target-blue: #eaf3fc; $line-target-blue: #eaf3fc;
$line-select-yellow: #fcf8e7; $line-select-yellow: #fcf8e7;
...@@ -267,7 +266,7 @@ $zen-control-hover-color: #111; ...@@ -267,7 +266,7 @@ $zen-control-hover-color: #111;
$calendar-header-color: #b8b8b8; $calendar-header-color: #b8b8b8;
$calendar-hover-bg: #ecf3fe; $calendar-hover-bg: #ecf3fe;
$calendar-border-color: rgba(#000, .1); $calendar-border-color: rgba(#000, .1);
$calendar-unselectable-bg: #faf9f9; $calendar-unselectable-bg: $gray-light;
/* /*
* Personal Access Tokens * Personal Access Tokens
......
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
} }
.blocks-container { .blocks-container {
padding: $gl-padding; padding: 0 $gl-padding;
} }
.block { .block {
...@@ -123,6 +123,13 @@ ...@@ -123,6 +123,13 @@
} }
} }
.retry-link {
color: $gl-link-color;
&:hover {
text-decoration: underline;
}
}
.stage-item { .stage-item {
cursor: pointer; cursor: pointer;
...@@ -132,7 +139,7 @@ ...@@ -132,7 +139,7 @@
} }
.build-dropdown { .build-dropdown {
padding: 0 $gl-padding; padding: $gl-padding 0;
.dropdown-menu-toggle { .dropdown-menu-toggle {
margin-top: 8px; margin-top: 8px;
...@@ -146,7 +153,6 @@ ...@@ -146,7 +153,6 @@
} }
.builds-container { .builds-container {
margin-top: $gl-padding;
background-color: $white-light; background-color: $white-light;
border-top: 1px solid $border-color; border-top: 1px solid $border-color;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
......
...@@ -113,11 +113,13 @@ ...@@ -113,11 +113,13 @@
.commit-row-description { .commit-row-description {
font-size: 14px; font-size: 14px;
border-left: 1px solid #eee; border-left: 1px solid $btn-gray-hover;
padding: 10px 15px; padding: 10px 15px;
margin: 10px 0; margin: 10px 0;
background: #f9f9f9; background: $gray-light;
display: none; display: none;
white-space: pre-line;
word-break: normal;
pre { pre {
border: none; border: none;
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
pre { pre {
border: none; border: none;
background: #f9f9f9; background: $gray-light;
border-radius: 0; border-radius: 0;
color: #777; color: #777;
margin: 0 20px; margin: 0 20px;
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
border: 1px solid #eee; border: 1px solid #eee;
padding: 5px; padding: 5px;
@include border-radius(5px); @include border-radius(5px);
background: #f9f9f9; background: $gray-light;
margin-left: 10px; margin-left: 10px;
top: -6px; top: -6px;
img { img {
......
...@@ -72,12 +72,12 @@ form.edit-issue { ...@@ -72,12 +72,12 @@ form.edit-issue {
} }
&.closed { &.closed {
background: #f9f9f9; background: $gray-light;
border-color: #e5e5e5; border-color: #e5e5e5;
} }
&.merged { &.merged {
background: #f9f9f9; background: $gray-light;
border-color: #e5e5e5; border-color: #e5e5e5;
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 10px;
margin-bottom: 10px; margin-bottom: 10px;
text-decoration: none;
} }
&.suggest-colors-dropdown { &.suggest-colors-dropdown {
......
...@@ -16,7 +16,7 @@ $colors: ( ...@@ -16,7 +16,7 @@ $colors: (
white_button_origin_chosen : #268ced, white_button_origin_chosen : #268ced,
white_header_not_chosen : #f0f0f0, white_header_not_chosen : #f0f0f0,
white_line_not_chosen : #f9f9f9, white_line_not_chosen : $gray-light,
dark_header_head_neutral : rgba(#3f3, .2), dark_header_head_neutral : rgba(#3f3, .2),
......
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
pre { pre {
border: none; border: none;
background: #f9f9f9; background: $gray-light;
border-radius: 0; border-radius: 0;
color: #777; color: #777;
margin: 0 20px; margin: 0 20px;
......
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
} }
} }
.add-to-tree {
vertical-align: top;
}
.last-commit { .last-commit {
max-width: 506px; max-width: 506px;
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
$l-cyan: #8abeb7; $l-cyan: #8abeb7;
$l-white: $ci-text-color; $l-white: $ci-text-color;
.term-bold {
font-weight: bold;
}
.term-italic { .term-italic {
font-style: italic; font-style: italic;
} }
......
...@@ -78,8 +78,8 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -78,8 +78,8 @@ class Projects::BuildsController < Projects::ApplicationController
end end
def raw def raw
if @build.has_trace? if @build.has_trace_file?
send_file @build.path_to_trace, type: 'text/plain; charset=utf-8', disposition: 'inline' send_file @build.trace_file_path, type: 'text/plain; charset=utf-8', disposition: 'inline'
else else
render_404 render_404
end end
......
...@@ -448,6 +448,6 @@ module ProjectsHelper ...@@ -448,6 +448,6 @@ module ProjectsHelper
options.delete('Everyone with access') if @project.private? && level != ProjectFeature::ENABLED options.delete('Everyone with access') if @project.private? && level != ProjectFeature::ENABLED
options = options_for_select(options, selected: @project.project_feature.public_send(field) || ProjectFeature::ENABLED) options = options_for_select(options, selected: @project.project_feature.public_send(field) || ProjectFeature::ENABLED)
content_tag(:select, options, name: "project[project_feature_attributes][#{field.to_s}]", id: "project_project_feature_attributes_#{field.to_s}", class: "pull-right form-control").html_safe content_tag(:select, options, name: "project[project_feature_attributes][#{field.to_s}]", id: "project_project_feature_attributes_#{field.to_s}", class: "pull-right form-control", data: { field: field }).html_safe
end end
end end
...@@ -208,22 +208,31 @@ module Ci ...@@ -208,22 +208,31 @@ module Ci
end end
end end
def has_trace_file?
File.exist?(path_to_trace) || has_old_trace_file?
end
def has_trace? def has_trace?
raw_trace.present? raw_trace.present?
end end
def raw_trace def raw_trace
if File.file?(path_to_trace) if File.exist?(trace_file_path)
File.read(path_to_trace) File.read(trace_file_path)
elsif project.ci_id && File.file?(old_path_to_trace)
# Temporary fix for build trace data integrity
File.read(old_path_to_trace)
else else
# backward compatibility # backward compatibility
read_attribute :trace read_attribute :trace
end end
end end
##
# Deprecated
#
# This is a hotfix for CI build data integrity, see #4246
def has_old_trace_file?
project.ci_id && File.exist?(old_path_to_trace)
end
def trace def trace
trace = raw_trace trace = raw_trace
if project && trace.present? && project.runners_token.present? if project && trace.present? && project.runners_token.present?
...@@ -262,6 +271,14 @@ module Ci ...@@ -262,6 +271,14 @@ module Ci
end end
end end
def trace_file_path
if has_old_trace_file?
old_path_to_trace
else
path_to_trace
end
end
def dir_to_trace def dir_to_trace
File.join( File.join(
Settings.gitlab_ci.builds_path, Settings.gitlab_ci.builds_path,
......
...@@ -88,7 +88,7 @@ module MergeRequests ...@@ -88,7 +88,7 @@ module MergeRequests
closes_issue = "Closes ##{iid}" closes_issue = "Closes ##{iid}"
if merge_request.description.present? if merge_request.description.present?
merge_request.description += closes_issue.prepend("\n") merge_request.description += closes_issue.prepend("\n\n")
else else
merge_request.description = closes_issue merge_request.description = closes_issue
end end
......
:plain :plain
$("##{dom_id(@group_member)}").replaceWith('#{escape_javascript(render('shared/members/member', member: @group_member))}'); $("##{dom_id(@group_member)}").replaceWith('#{escape_javascript(render('shared/members/member', member: @group_member))}');
new MemberExpirationDate(); new gl.MemberExpirationDate();
<<<<<<< HEAD
%fieldset.merge-request-feature.append-bottom-default %fieldset.merge-request-feature.append-bottom-default
%h5.prepend-top-0 %h5.prepend-top-0
Merge requests Merge requests
...@@ -89,3 +90,19 @@ ...@@ -89,3 +90,19 @@
:javascript :javascript
new UsersSelect(); new UsersSelect();
=======
.merge-requests-feature
%fieldset.builds-feature
%hr
%h5.prepend-top-0
Merge Requests
.form-group
.checkbox
= f.label :only_allow_merge_if_build_succeeds do
= f.check_box :only_allow_merge_if_build_succeeds
%strong Only allow merge requests to be merged if the build succeeds
%br
%span.descr
Builds need to be configured to enable this feature.
= link_to icon('question-circle'), help_page_path('workflow/merge_requests', anchor: 'only-allow-merge-requests-to-be-merged-if-the-build-succeeds')
>>>>>>> ce/master
- builds = @build.pipeline.builds.latest.to_a
- statuses = ["failed", "pending", "running", "canceled", "success", "skipped"]
%aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar %aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar
.block.build-sidebar-header.visible-xs-block.visible-sm-block.append-bottom-default .block.build-sidebar-header.visible-xs-block.visible-sm-block.append-bottom-default
Build Build
...@@ -11,40 +14,6 @@ ...@@ -11,40 +14,6 @@
%p.build-detail-row %p.build-detail-row
#{@build.coverage}% #{@build.coverage}%
- builds = @build.pipeline.builds.latest.to_a
- statuses = ["failed", "pending", "running", "canceled", "success", "skipped"]
- if builds.size > 1
.dropdown.build-dropdown
.build-light-text Stage
%button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'}
%span.stage-selection More
= icon('caret-down')
%ul.dropdown-menu
- builds.map(&:stage).uniq.each do |stage|
%li
%a.stage-item= stage
.builds-container
- statuses.each do |build_status|
- builds.select{|build| build.status == build_status}.each do |build|
.build-job{class: ('active' if build == @build), data: {stage: build.stage}}
= link_to namespace_project_build_path(@project.namespace, @project, build) do
= icon('check')
= ci_icon_for_status(build.status)
%span
- if build.name
= build.name
- else
= build.id
- if @build.retried?
%li.active
%a
Build ##{@build.id}
&middot;
%i.fa.fa-warning
This build was retried.
.blocks-container .blocks-container
- if can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?) - if can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?)
.block{ class: ("block-first" if !@build.coverage) } .block{ class: ("block-first" if !@build.coverage) }
...@@ -76,7 +45,7 @@ ...@@ -76,7 +45,7 @@
.title .title
Build details Build details
- if can?(current_user, :update_build, @build) && @build.retryable? - if can?(current_user, :update_build, @build) && @build.retryable?
= link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'pull-right', method: :post = link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'pull-right retry-link', method: :post
- if @build.merge_request - if @build.merge_request
%p.build-detail-row %p.build-detail-row
%span.build-light-text Merge Request: %span.build-light-text Merge Request:
...@@ -100,7 +69,7 @@ ...@@ -100,7 +69,7 @@
- elsif @build.runner - elsif @build.runner
\##{@build.runner.id} \##{@build.runner.id}
.btn-group.btn-group-justified{ role: :group } .btn-group.btn-group-justified{ role: :group }
- if @build.has_trace? - if @build.has_trace_file?
= link_to 'Raw', raw_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' = link_to 'Raw', raw_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default'
- if @build.active? - if @build.active?
= link_to "Cancel", cancel_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default', method: :post = link_to "Cancel", cancel_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default', method: :post
...@@ -141,3 +110,35 @@ ...@@ -141,3 +110,35 @@
- @build.tag_list.each do |tag| - @build.tag_list.each do |tag|
%span.label.label-primary %span.label.label-primary
= tag = tag
- if builds.size > 1
.dropdown.build-dropdown
.title Stage
%button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'}
%span.stage-selection More
= icon('caret-down')
%ul.dropdown-menu
- builds.map(&:stage).uniq.each do |stage|
%li
%a.stage-item= stage
.builds-container
- statuses.each do |build_status|
- builds.select{|build| build.status == build_status}.each do |build|
.build-job{class: ('active' if build == @build), data: {stage: build.stage}}
= link_to namespace_project_build_path(@project.namespace, @project, build) do
= icon('check')
= ci_icon_for_status(build.status)
%span
- if build.name
= build.name
- else
= build.id
- if @build.retried?
%li.active
%a
Build ##{@build.id}
&middot;
%i.fa.fa-warning
This build was retried.
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn has-tooltip' do = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn has-tooltip' do
= custom_icon('icon_fork') = custom_icon('icon_fork')
Fork %span Fork
- else - else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn has-tooltip' do = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn has-tooltip' do
= custom_icon('icon_fork') = custom_icon('icon_fork')
Fork %span Fork
%div.count-with-arrow %div.count-with-arrow
%span.arrow %span.arrow
= link_to namespace_project_forks_path(@project.namespace, @project), class: "count" do = link_to namespace_project_forks_path(@project.namespace, @project), class: "count" do
......
...@@ -32,11 +32,11 @@ ...@@ -32,11 +32,11 @@
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-new' do = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-new' do
= custom_icon('icon_fork') = custom_icon('icon_fork')
Fork %span Fork
- else - else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn btn-new' do = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn btn-new' do
= custom_icon('icon_fork') = custom_icon('icon_fork')
Fork %span Fork
= render 'projects', projects: @forks = render 'projects', projects: @forks
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
.pull-right .pull-right
#new-branch{'data-path' => can_create_branch_namespace_project_issue_path(@project.namespace, @project, @issue)} #new-branch{'data-path' => can_create_branch_namespace_project_issue_path(@project.namespace, @project, @issue)}
= link_to '#', class: 'checking btn btn-grouped', disabled: 'disabled' do
= icon('spinner spin')
Checking branches
= link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid), = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid),
method: :post, class: 'btn btn-new btn-inverted has-tooltip', title: @issue.to_branch_name, disabled: 'disabled' do method: :post, class: 'btn btn-new btn-inverted btn-grouped has-tooltip available hide', title: @issue.to_branch_name do
.checking New branch
= icon('spinner spin') = link_to '#', class: 'unavailable btn btn-grouped hide', disabled: 'disabled' do
Checking branches = icon('exclamation-triangle')
.available.hide New branch unavailable
New branch
.unavailable.hide
= icon('exclamation-triangle')
New branch unavailable
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
= render 'bitbucket_import_modal' = render 'bitbucket_import_modal'
%div %div
- if gitlab_import_enabled? - if gitlab_import_enabled?
= link_to status_import_gitlab_path, class: "btn import_gitlab #{'how_to_import_link' unless bitbucket_import_configured?}" do = link_to status_import_gitlab_path, class: "btn import_gitlab #{'how_to_import_link' unless gitlab_import_configured?}" do
= icon('gitlab', text: 'GitLab.com') = icon('gitlab', text: 'GitLab.com')
- unless gitlab_import_configured? - unless gitlab_import_configured?
= render 'gitlab_import_modal' = render 'gitlab_import_modal'
......
:plain :plain
$("##{dom_id(@project_member)}").replaceWith('#{escape_javascript(render('shared/members/member', member: @project_member))}'); $("##{dom_id(@project_member)}").replaceWith('#{escape_javascript(render('shared/members/member', member: @project_member))}');
new MemberExpirationDate(); new gl.MemberExpirationDate();
...@@ -63,24 +63,24 @@ If you have enough RAM memory and a recent CPU the speed of GitLab is mainly lim ...@@ -63,24 +63,24 @@ If you have enough RAM memory and a recent CPU the speed of GitLab is mainly lim
### Memory ### Memory
You need at least 2GB of addressable memory (RAM + swap) to install and use GitLab! You need at least 4GB of addressable memory (RAM + swap) to install and use GitLab!
The operating system and any other running applications will also be using memory The operating system and any other running applications will also be using memory
so keep in mind that you need at least 2GB available before running GitLab. With so keep in mind that you need at least 4GB available before running GitLab. With
less memory GitLab will give strange errors during the reconfigure run and 500 less memory GitLab will give strange errors during the reconfigure run and 500
errors during usage. errors during usage.
- 512MB RAM + 1.5GB of swap is the absolute minimum but we strongly **advise against** this amount of memory. See the unicorn worker section below for more advice. - 1GB RAM + 3GB of swap is the absolute minimum but we strongly **advise against** this amount of memory. See the unicorn worker section below for more advice.
- 1GB RAM + 1GB swap supports up to 100 users but it will be very slow - 2GB RAM + 2GB swap supports up to 100 users but it will be very slow
- **2GB RAM** is the **recommended** memory size for all installations and supports up to 100 users - **4GB RAM** is the **recommended** memory size for all installations and supports up to 100 users
- 4GB RAM supports up to 1,000 users - 8GB RAM supports up to 1,000 users
- 8GB RAM supports up to 2,000 users - 16GB RAM supports up to 2,000 users
- 16GB RAM supports up to 4,000 users - 32GB RAM supports up to 4,000 users
- 32GB RAM supports up to 8,000 users - 64GB RAM supports up to 8,000 users
- 64GB RAM supports up to 16,000 users - 128GB RAM supports up to 16,000 users
- 128GB RAM supports up to 32,000 users - 256GB RAM supports up to 32,000 users
- More users? Run it on [multiple application servers](https://about.gitlab.com/high-availability/) - More users? Run it on [multiple application servers](https://about.gitlab.com/high-availability/)
We recommend having at least 1GB of swap on your server, even if you currently have We recommend having at least 2GB of swap on your server, even if you currently have
enough available RAM. Having swap will help reduce the chance of errors occurring enough available RAM. Having swap will help reduce the chance of errors occurring
if your available memory changes. if your available memory changes.
...@@ -113,10 +113,8 @@ It's possible to increase the amount of unicorn workers and this will usually he ...@@ -113,10 +113,8 @@ It's possible to increase the amount of unicorn workers and this will usually he
For most instances we recommend using: CPU cores + 1 = unicorn workers. For most instances we recommend using: CPU cores + 1 = unicorn workers.
So for a machine with 2 cores, 3 unicorn workers is ideal. So for a machine with 2 cores, 3 unicorn workers is ideal.
For all machines that have 1GB and up we recommend a minimum of three unicorn workers. For all machines that have 2GB and up we recommend a minimum of three unicorn workers.
If you have a 512MB machine with a magnetic (non-SSD) swap drive we recommend to configure only one Unicorn worker to prevent excessive swapping. If you have a 1GB machine we recommend to configure only two Unicorn workers to prevent excessive swapping.
With one Unicorn worker only git over ssh access will work because the git over HTTP access requires two running workers (one worker to receive the user request and one worker for the authorization check).
If you have a 512MB machine with a SSD drive you can use two Unicorn workers, this will allow HTTP access although it will be slow due to swapping.
To change the Unicorn workers when you have the Omnibus package please see [the Unicorn settings in the Omnibus GitLab documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/unicorn.md#unicorn-settings). To change the Unicorn workers when you have the Omnibus package please see [the Unicorn settings in the Omnibus GitLab documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/unicorn.md#unicorn-settings).
......
...@@ -117,15 +117,19 @@ module API ...@@ -117,15 +117,19 @@ module API
post '/two_factor_recovery_codes' do post '/two_factor_recovery_codes' do
status 200 status 200
key = Key.find(params[:key_id]) key = Key.find_by(id: params[:key_id])
user = key.user
unless key
return { 'success' => false, 'message' => 'Could not find the given key' }
end
# Make sure this isn't a deploy key if key.is_a?(DeployKey)
unless key.type.nil?
return { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' } return { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' }
end end
unless user.present? user = key.user
unless user
return { success: false, message: 'Could not find a user for the given key' } return { success: false, message: 'Could not find a user for the given key' }
end end
......
require 'spec_helper' require 'spec_helper'
require 'tempfile'
describe "Builds" do describe "Builds" do
let(:artifacts_file) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') } let(:artifacts_file) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
...@@ -6,7 +7,7 @@ describe "Builds" do ...@@ -6,7 +7,7 @@ describe "Builds" do
before do before do
login_as(:user) login_as(:user)
@commit = FactoryGirl.create :ci_pipeline @commit = FactoryGirl.create :ci_pipeline
@build = FactoryGirl.create :ci_build, pipeline: @commit @build = FactoryGirl.create :ci_build, :trace, pipeline: @commit
@build2 = FactoryGirl.create :ci_build @build2 = FactoryGirl.create :ci_build
@project = @commit.project @project = @commit.project
@project.team << [@user, :developer] @project.team << [@user, :developer]
...@@ -156,7 +157,6 @@ describe "Builds" do ...@@ -156,7 +157,6 @@ describe "Builds" do
context 'Build raw trace' do context 'Build raw trace' do
before do before do
@build.run! @build.run!
@build.trace = 'BUILD TRACE'
visit namespace_project_build_path(@project.namespace, @project, @build) visit namespace_project_build_path(@project.namespace, @project, @build)
end end
...@@ -255,35 +255,101 @@ describe "Builds" do ...@@ -255,35 +255,101 @@ describe "Builds" do
end end
end end
describe "GET /:project/builds/:id/raw" do describe 'GET /:project/builds/:id/raw' do
context "Build from project" do context 'access source' do
before do context 'build from project' do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') before do
@build.run! Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
@build.trace = 'BUILD TRACE' @build.run!
visit namespace_project_build_path(@project.namespace, @project, @build) visit namespace_project_build_path(@project.namespace, @project, @build)
page.within('.js-build-sidebar') { click_link 'Raw' } page.within('.js-build-sidebar') { click_link 'Raw' }
end
it 'sends the right headers' do
expect(page.status_code).to eq(200)
expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8')
expect(page.response_headers['X-Sendfile']).to eq(@build.path_to_trace)
end
end end
it 'sends the right headers' do context 'build from other project' do
expect(page.status_code).to eq(200) before do
expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8') Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
expect(page.response_headers['X-Sendfile']).to eq(@build.path_to_trace) @build2.run!
visit raw_namespace_project_build_path(@project.namespace, @project, @build2)
end
it 'sends the right headers' do
expect(page.status_code).to eq(404)
end
end end
end end
context "Build from other project" do context 'storage form' do
before do let(:existing_file) { Tempfile.new('existing-trace-file').path }
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') let(:non_existing_file) do
@build2.run! file = Tempfile.new('non-existing-trace-file')
@build2.trace = 'BUILD TRACE' path = file.path
visit raw_namespace_project_build_path(@project.namespace, @project, @build2) file.unlink
puts page.status_code path
puts current_url
end end
it 'sends the right headers' do context 'when build has trace in file' do
expect(page.status_code).to eq(404) before do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
@build.run!
visit namespace_project_build_path(@project.namespace, @project, @build)
allow_any_instance_of(Project).to receive(:ci_id).and_return(nil)
allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(existing_file)
allow_any_instance_of(Ci::Build).to receive(:old_path_to_trace).and_return(non_existing_file)
page.within('.js-build-sidebar') { click_link 'Raw' }
end
it 'sends the right headers' do
expect(page.status_code).to eq(200)
expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8')
expect(page.response_headers['X-Sendfile']).to eq(existing_file)
end
end
context 'when build has trace in old file' do
before do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
@build.run!
visit namespace_project_build_path(@project.namespace, @project, @build)
allow_any_instance_of(Project).to receive(:ci_id).and_return(999)
allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(non_existing_file)
allow_any_instance_of(Ci::Build).to receive(:old_path_to_trace).and_return(existing_file)
page.within('.js-build-sidebar') { click_link 'Raw' }
end
it 'sends the right headers' do
expect(page.status_code).to eq(200)
expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8')
expect(page.response_headers['X-Sendfile']).to eq(existing_file)
end
end
context 'when build has trace in DB' do
before do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
@build.run!
visit namespace_project_build_path(@project.namespace, @project, @build)
allow_any_instance_of(Project).to receive(:ci_id).and_return(nil)
allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(non_existing_file)
allow_any_instance_of(Ci::Build).to receive(:old_path_to_trace).and_return(non_existing_file)
page.within('.js-build-sidebar') { click_link 'Raw' }
end
it 'sends the right headers' do
expect(page.status_code).to eq(404)
end
end end
end end
end end
......
require 'rails_helper'
feature 'Project edit', feature: true, js: true do
include WaitForAjax
let(:user) { create(:user) }
let(:project) { create(:project) }
before do
project.team << [user, :master]
login_as(user)
visit edit_namespace_project_path(project.namespace, project)
end
context 'feature visibility' do
context 'merge requests select' do
it 'hides merge requests section' do
select('Disabled', from: 'project_project_feature_attributes_merge_requests_access_level')
expect(page).to have_selector('.merge-requests-feature', visible: false)
end
it 'hides merge requests section after save' do
select('Disabled', from: 'project_project_feature_attributes_merge_requests_access_level')
expect(page).to have_selector('.merge-requests-feature', visible: false)
click_button 'Save changes'
wait_for_ajax
expect(page).to have_selector('.merge-requests-feature', visible: false)
end
end
context 'builds select' do
it 'hides merge requests section' do
select('Disabled', from: 'project_project_feature_attributes_builds_access_level')
expect(page).to have_selector('.builds-feature', visible: false)
end
it 'hides merge requests section after save' do
select('Disabled', from: 'project_project_feature_attributes_builds_access_level')
expect(page).to have_selector('.builds-feature', visible: false)
click_button 'Save changes'
wait_for_ajax
expect(page).to have_selector('.builds-feature', visible: false)
end
end
end
end
#= require lib/utils/datetime_utility
describe 'Date time utils', ->
describe 'get day name', ->
it 'returns Sunday', ->
day = gl.utils.getDayName(new Date('07/17/2016'))
expect(day).toBe('Sunday')
it 'returns Monday', ->
day = gl.utils.getDayName(new Date('07/18/2016'))
expect(day).toBe('Monday')
it 'returns Tuesday', ->
day = gl.utils.getDayName(new Date('07/19/2016'))
expect(day).toBe('Tuesday')
it 'returns Wednesday', ->
day = gl.utils.getDayName(new Date('07/20/2016'))
expect(day).toBe('Wednesday')
it 'returns Thursday', ->
day = gl.utils.getDayName(new Date('07/21/2016'))
expect(day).toBe('Thursday')
it 'returns Friday', ->
day = gl.utils.getDayName(new Date('07/22/2016'))
expect(day).toBe('Friday')
it 'returns Saturday', ->
day = gl.utils.getDayName(new Date('07/23/2016'))
expect(day).toBe('Saturday')
describe 'get day difference', ->
it 'should return 7', ->
firstDay = new Date('07/01/2016')
secondDay = new Date('07/08/2016')
difference = gl.utils.getDayDifference(firstDay, secondDay)
expect(difference).toBe(7)
it 'should return 31', ->
firstDay = new Date('07/01/2016')
secondDay = new Date('08/01/2016')
difference = gl.utils.getDayDifference(firstDay, secondDay)
expect(difference).toBe(31)
it 'should return 365', ->
firstDay = new Date('07/02/2015')
secondDay = new Date('07/01/2016')
difference = gl.utils.getDayDifference(firstDay, secondDay)
expect(difference).toBe(365)
\ No newline at end of file
//= require lib/utils/datetime_utility
(() => {
describe('Date time utils', () => {
describe('get day name', () => {
it('should return Sunday', () => {
const day = gl.utils.getDayName(new Date('07/17/2016'));
expect(day).toBe('Sunday');
});
it('should return Monday', () => {
const day = gl.utils.getDayName(new Date('07/18/2016'));
expect(day).toBe('Monday');
});
it('should return Tuesday', () => {
const day = gl.utils.getDayName(new Date('07/19/2016'));
expect(day).toBe('Tuesday');
});
it('should return Wednesday', () => {
const day = gl.utils.getDayName(new Date('07/20/2016'));
expect(day).toBe('Wednesday');
});
it('should return Thursday', () => {
const day = gl.utils.getDayName(new Date('07/21/2016'));
expect(day).toBe('Thursday');
});
it('should return Friday', () => {
const day = gl.utils.getDayName(new Date('07/22/2016'));
expect(day).toBe('Friday');
});
it('should return Saturday', () => {
const day = gl.utils.getDayName(new Date('07/23/2016'));
expect(day).toBe('Saturday');
});
});
describe('get day difference', () => {
it('should return 7', () => {
const firstDay = new Date('07/01/2016');
const secondDay = new Date('07/08/2016');
const difference = gl.utils.getDayDifference(firstDay, secondDay);
expect(difference).toBe(7);
});
it('should return 31', () => {
const firstDay = new Date('07/01/2016');
const secondDay = new Date('08/01/2016');
const difference = gl.utils.getDayDifference(firstDay, secondDay);
expect(difference).toBe(31);
});
it('should return 365', () => {
const firstDay = new Date('07/02/2015');
const secondDay = new Date('07/01/2016');
const difference = gl.utils.getDayDifference(firstDay, secondDay);
expect(difference).toBe(365);
});
});
});
})();
...@@ -19,4 +19,64 @@ describe Ci::Build, models: true do ...@@ -19,4 +19,64 @@ describe Ci::Build, models: true do
expect(build.trace).to eq(test_trace) expect(build.trace).to eq(test_trace)
end end
end end
describe '#has_trace_file?' do
context 'when there is no trace' do
it { expect(build.has_trace_file?).to be_falsey }
it { expect(build.trace).to be_nil }
end
context 'when there is a trace' do
context 'when trace is stored in file' do
let(:build_with_trace) { create(:ci_build, :trace) }
it { expect(build_with_trace.has_trace_file?).to be_truthy }
it { expect(build_with_trace.trace).to eq('BUILD TRACE') }
end
context 'when trace is stored in old file' do
before do
allow(build.project).to receive(:ci_id).and_return(999)
allow(File).to receive(:exist?).with(build.path_to_trace).and_return(false)
allow(File).to receive(:exist?).with(build.old_path_to_trace).and_return(true)
allow(File).to receive(:read).with(build.old_path_to_trace).and_return(test_trace)
end
it { expect(build.has_trace_file?).to be_truthy }
it { expect(build.trace).to eq(test_trace) }
end
context 'when trace is stored in DB' do
before do
allow(build.project).to receive(:ci_id).and_return(nil)
allow(build).to receive(:read_attribute).with(:trace).and_return(test_trace)
allow(File).to receive(:exist?).with(build.path_to_trace).and_return(false)
allow(File).to receive(:exist?).with(build.old_path_to_trace).and_return(false)
end
it { expect(build.has_trace_file?).to be_falsey }
it { expect(build.trace).to eq(test_trace) }
end
end
end
describe '#trace_file_path' do
context 'when trace is stored in file' do
before do
allow(build).to receive(:has_trace_file?).and_return(true)
allow(build).to receive(:has_old_trace_file?).and_return(false)
end
it { expect(build.trace_file_path).to eq(build.path_to_trace) }
end
context 'when trace is stored in old file' do
before do
allow(build).to receive(:has_trace_file?).and_return(true)
allow(build).to receive(:has_old_trace_file?).and_return(true)
end
it { expect(build.trace_file_path).to eq(build.old_path_to_trace) }
end
end
end end
...@@ -44,8 +44,8 @@ describe API::API, api: true do ...@@ -44,8 +44,8 @@ describe API::API, api: true do
secret_token: secret_token, secret_token: secret_token,
key_id: 12345 key_id: 12345
expect(response).to have_http_status(404) expect(json_response['success']).to be_falsey
expect(json_response['message']).to eq('404 Not found') expect(json_response['message']).to eq('Could not find the given key')
end end
it 'returns an error message when the key is a deploy key' do it 'returns an error message when the key is a deploy key' do
......
...@@ -99,14 +99,14 @@ describe MergeRequests::BuildService, services: true do ...@@ -99,14 +99,14 @@ describe MergeRequests::BuildService, services: true do
let(:source_branch) { "#{issue.iid}-fix-issue" } let(:source_branch) { "#{issue.iid}-fix-issue" }
it 'appends "Closes #$issue-iid" to the description' do it 'appends "Closes #$issue-iid" to the description' do
expect(merge_request.description).to eq("#{commit_1.safe_message.split(/\n+/, 2).last}\nCloses ##{issue.iid}") expect(merge_request.description).to eq("#{commit_1.safe_message.split(/\n+/, 2).last}\n\nCloses ##{issue.iid}")
end end
context 'merge request already has a description set' do context 'merge request already has a description set' do
let(:description) { 'Merge request description' } let(:description) { 'Merge request description' }
it 'appends "Closes #$issue-iid" to the description' do it 'appends "Closes #$issue-iid" to the description' do
expect(merge_request.description).to eq("#{description}\nCloses ##{issue.iid}") expect(merge_request.description).to eq("#{description}\n\nCloses ##{issue.iid}")
end end
end end
......
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