Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into 22191-delete-dynamic-envs-mr
This commit is contained in:
commit
bb7ff8eb17
38 changed files with 461 additions and 265 deletions
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -19,8 +19,8 @@ Please view this file on the master branch, on stable branches it's out of date.
|
|||
- Clarify documentation for Runners API (Gennady Trafimenkov)
|
||||
- The instrumentation for Banzai::Renderer has been restored
|
||||
- Change user & group landing page routing from /u/:username to /:username
|
||||
- Prevent running GfmAutocomplete setup for each diff note !6569
|
||||
- Added documentation for .gitattributes files
|
||||
- Move Pipeline Metrics to separate worker
|
||||
- AbstractReferenceFilter caches project_refs on RequestStore when active
|
||||
- Replaced the check sign to arrow in the show build view. !6501
|
||||
- Add a /wip slash command to toggle the Work In Progress status of a merge request. !6259 (tbalthazar)
|
||||
|
@ -39,7 +39,6 @@ Please view this file on the master branch, on stable branches it's out of date.
|
|||
- Update Gitlab Shell to fix some problems with moving projects between storages
|
||||
- Cache rendered markdown in the database, rather than Redis
|
||||
- Avoid database queries on Banzai::ReferenceParser::BaseParser for nodes without references
|
||||
- Do not alter 'force_remove_source_branch' options on MergeRequest unless specified
|
||||
- Simplify Mentionable concern instance methods
|
||||
- API: Ability to retrieve version information (Robert Schilling)
|
||||
- Fix permission for setting an issue's due date
|
||||
|
@ -76,14 +75,12 @@ Please view this file on the master branch, on stable branches it's out of date.
|
|||
- Only update issuable labels if they have been changed
|
||||
- Take filters in account in issuable counters. !6496
|
||||
- Use custom Ruby images to test builds (registry.dev.gitlab.org/gitlab/gitlab-build-images:*)
|
||||
- Prevent flash alert text from being obscured when container is fluid
|
||||
- Append issue template to existing description !6149 (Joseph Frazier)
|
||||
- Trending projects now only show public projects and the list of projects is cached for a day
|
||||
- Memoize Gitlab Shell's secret token (!6599, Justin DiPierro)
|
||||
- Revoke button in Applications Settings underlines on hover.
|
||||
- Use higher size on Gitlab::Redis connection pool on Sidekiq servers
|
||||
- Add missing values to linter !6276 (Katarzyna Kobierska Ula Budziszewska)
|
||||
- Fix Long commit messages overflow viewport in file tree
|
||||
- Revert avoid touching file system on Build#artifacts?
|
||||
- Stop using a Redis lease when updating the project activity timestamp whenever a new event is created
|
||||
- Add disabled delete button to protected branches (ClemMakesApps)
|
||||
|
@ -94,7 +91,7 @@ Please view this file on the master branch, on stable branches it's out of date.
|
|||
- Replace bootstrap caret with fontawesome caret (ClemMakesApps)
|
||||
- Fix unnecessary escaping of reserved HTML characters in milestone title. !6533
|
||||
- Add organization field to user profile
|
||||
- Ignore deployment for statistics in Cycle Analytics, except in staging and production stages
|
||||
- Change user pages routing from /u/:username/PATH to /users/:username/PATH. Old routes will redirect to the new ones for the time being.
|
||||
- Fix enter key when navigating search site search dropdown. !6643 (Brennan Roberts)
|
||||
- Fix deploy status responsiveness error !6633
|
||||
- Make searching for commits case insensitive
|
||||
|
@ -125,8 +122,15 @@ Please view this file on the master branch, on stable branches it's out of date.
|
|||
|
||||
## 8.12.7
|
||||
|
||||
- Use gitlab-markup gem instead of github-markup to fix `.rst` file rendering. !6659
|
||||
- Fix GFM autocomplete setup being called several times
|
||||
- Prevent running `GfmAutocomplete` setup for each diff note. !6569
|
||||
- Fix long commit messages overflow viewport in file tree. !6573
|
||||
- Use `gitlab-markup` gem instead of `github-markup` to fix `.rst` file rendering. !6659
|
||||
- Prevent flash alert text from being obscured when container is fluid. !6694
|
||||
- Fix due date being displayed as `NaN` in Safari. !6797
|
||||
- Fix JS bug with select2 because of missing `data-field` attribute in select box. !6812
|
||||
- Do not alter `force_remove_source_branch` options on MergeRequest unless specified. !6817
|
||||
- Fix GFM autocomplete setup being called several times. !6840
|
||||
- Handle case where deployment ref no longer exists. !6855
|
||||
|
||||
## 8.12.6
|
||||
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -262,8 +262,6 @@ group :development do
|
|||
|
||||
# thin instead webrick
|
||||
gem 'thin', '~> 1.7.0'
|
||||
|
||||
gem 'activerecord_sane_schema_dumper', '0.2'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
|
@ -310,6 +308,8 @@ group :development, :test do
|
|||
|
||||
gem 'license_finder', '~> 2.1.0', require: false
|
||||
gem 'knapsack', '~> 1.11.0'
|
||||
|
||||
gem 'activerecord_sane_schema_dumper', '0.2'
|
||||
end
|
||||
|
||||
group :test do
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
case 'projects:milestones:new':
|
||||
case 'projects:milestones:edit':
|
||||
new ZenMode();
|
||||
new DueDateSelect();
|
||||
new gl.DueDateSelectors();
|
||||
new GLForm($('.milestone-form'));
|
||||
break;
|
||||
case 'groups:milestones:new':
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
(function() {
|
||||
this.DueDateSelect = (function() {
|
||||
function DueDateSelect() {
|
||||
var $datePicker, $dueDate, $loading;
|
||||
// Milestone edit/new form
|
||||
$datePicker = $('.datepicker');
|
||||
if ($datePicker.length) {
|
||||
$dueDate = $('#milestone_due_date');
|
||||
$datePicker.datepicker({
|
||||
dateFormat: 'yy-mm-dd',
|
||||
onSelect: function(dateText, inst) {
|
||||
return $dueDate.val(dateText);
|
||||
}
|
||||
}).datepicker('setDate', $.datepicker.parseDate('yy-mm-dd', $dueDate.val()));
|
||||
}
|
||||
$('.js-clear-due-date').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
return $.datepicker._clearDate($datePicker);
|
||||
});
|
||||
// Issuable sidebar
|
||||
$loading = $('.js-issuable-update .due_date').find('.block-loading').hide();
|
||||
$('.js-due-date-select').each(function(i, dropdown) {
|
||||
var $block, $dropdown, $dropdownParent, $selectbox, $sidebarValue, $value, $valueContent, abilityName, addDueDate, fieldName, issueUpdateURL;
|
||||
$dropdown = $(dropdown);
|
||||
$dropdownParent = $dropdown.closest('.dropdown');
|
||||
$datePicker = $dropdownParent.find('.js-due-date-calendar');
|
||||
$block = $dropdown.closest('.block');
|
||||
$selectbox = $dropdown.closest('.selectbox');
|
||||
$value = $block.find('.value');
|
||||
$valueContent = $block.find('.value-content');
|
||||
$sidebarValue = $('.js-due-date-sidebar-value', $block);
|
||||
fieldName = $dropdown.data('field-name');
|
||||
abilityName = $dropdown.data('ability-name');
|
||||
issueUpdateURL = $dropdown.data('issue-update');
|
||||
$dropdown.glDropdown({
|
||||
hidden: function() {
|
||||
$selectbox.hide();
|
||||
return $value.css('display', '');
|
||||
}
|
||||
});
|
||||
addDueDate = function(isDropdown) {
|
||||
var data, date, mediumDate, value;
|
||||
// Create the post date
|
||||
value = $("input[name='" + fieldName + "']").val();
|
||||
if (value !== '') {
|
||||
date = new Date(value.replace(new RegExp('-', 'g'), ','));
|
||||
mediumDate = $.datepicker.formatDate('M d, yy', date);
|
||||
} else {
|
||||
mediumDate = 'No due date';
|
||||
}
|
||||
data = {};
|
||||
data[abilityName] = {};
|
||||
data[abilityName].due_date = value;
|
||||
return $.ajax({
|
||||
type: 'PUT',
|
||||
url: issueUpdateURL,
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
beforeSend: function() {
|
||||
var cssClass;
|
||||
$loading.fadeIn();
|
||||
if (isDropdown) {
|
||||
$dropdown.trigger('loading.gl.dropdown');
|
||||
$selectbox.hide();
|
||||
}
|
||||
$value.css('display', '');
|
||||
cssClass = Date.parse(mediumDate) ? 'bold' : 'no-value';
|
||||
$valueContent.html("<span class='" + cssClass + "'>" + mediumDate + "</span>");
|
||||
$sidebarValue.html(mediumDate);
|
||||
if (value !== '') {
|
||||
return $('.js-remove-due-date-holder').removeClass('hidden');
|
||||
} else {
|
||||
return $('.js-remove-due-date-holder').addClass('hidden');
|
||||
}
|
||||
}
|
||||
}).done(function(data) {
|
||||
if (isDropdown) {
|
||||
$dropdown.trigger('loaded.gl.dropdown');
|
||||
$dropdown.dropdown('toggle');
|
||||
}
|
||||
return $loading.fadeOut();
|
||||
});
|
||||
};
|
||||
$block.on('click', '.js-remove-due-date', function(e) {
|
||||
e.preventDefault();
|
||||
$("input[name='" + fieldName + "']").val('');
|
||||
return addDueDate(false);
|
||||
});
|
||||
return $datePicker.datepicker({
|
||||
dateFormat: 'yy-mm-dd',
|
||||
defaultDate: $("input[name='" + fieldName + "']").val(),
|
||||
altField: "input[name='" + fieldName + "']",
|
||||
onSelect: function() {
|
||||
return addDueDate(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
$(document).off('click', '.ui-datepicker-header a').on('click', '.ui-datepicker-header a', function(e) {
|
||||
return e.stopImmediatePropagation();
|
||||
});
|
||||
}
|
||||
|
||||
return DueDateSelect;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
161
app/assets/javascripts/due_date_select.js.es6
Normal file
161
app/assets/javascripts/due_date_select.js.es6
Normal file
|
@ -0,0 +1,161 @@
|
|||
(function(global) {
|
||||
class DueDateSelect {
|
||||
constructor({ $dropdown, $loading } = {}) {
|
||||
const $dropdownParent = $dropdown.closest('.dropdown');
|
||||
const $block = $dropdown.closest('.block');
|
||||
this.$loading = $loading;
|
||||
this.$dropdown = $dropdown;
|
||||
this.$dropdownParent = $dropdownParent;
|
||||
this.$datePicker = $dropdownParent.find('.js-due-date-calendar');
|
||||
this.$block = $block;
|
||||
this.$selectbox = $dropdown.closest('.selectbox');
|
||||
this.$value = $block.find('.value');
|
||||
this.$valueContent = $block.find('.value-content');
|
||||
this.$sidebarValue = $('.js-due-date-sidebar-value', $block);
|
||||
this.fieldName = $dropdown.data('field-name'),
|
||||
this.abilityName = $dropdown.data('ability-name'),
|
||||
this.issueUpdateURL = $dropdown.data('issue-update')
|
||||
|
||||
this.rawSelectedDate = null;
|
||||
this.displayedDate = null;
|
||||
this.datePayload = null;
|
||||
|
||||
this.initGlDropdown();
|
||||
this.initRemoveDueDate();
|
||||
this.initDatePicker();
|
||||
this.initStopPropagation();
|
||||
}
|
||||
|
||||
initGlDropdown() {
|
||||
this.$dropdown.glDropdown({
|
||||
hidden: () => {
|
||||
this.$selectbox.hide();
|
||||
this.$value.css('display', '');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initDatePicker() {
|
||||
this.$datePicker.datepicker({
|
||||
dateFormat: 'yy-mm-dd',
|
||||
defaultDate: $("input[name='" + this.fieldName + "']").val(),
|
||||
altField: "input[name='" + this.fieldName + "']",
|
||||
onSelect: () => {
|
||||
return this.saveDueDate(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initRemoveDueDate() {
|
||||
this.$block.on('click', '.js-remove-due-date', (e) => {
|
||||
e.preventDefault();
|
||||
$("input[name='" + this.fieldName + "']").val('');
|
||||
return this.saveDueDate(false);
|
||||
});
|
||||
}
|
||||
|
||||
initStopPropagation() {
|
||||
$(document).off('click', '.ui-datepicker-header a').on('click', '.ui-datepicker-header a', (e) => {
|
||||
return e.stopImmediatePropagation();
|
||||
});
|
||||
}
|
||||
|
||||
saveDueDate(isDropdown) {
|
||||
this.parseSelectedDate();
|
||||
this.prepSelectedDate();
|
||||
this.submitSelectedDate(isDropdown);
|
||||
}
|
||||
|
||||
parseSelectedDate() {
|
||||
this.rawSelectedDate = $("input[name='" + this.fieldName + "']").val();
|
||||
if (this.rawSelectedDate.length) {
|
||||
let dateObj = new Date(this.rawSelectedDate);
|
||||
this.displayedDate = $.datepicker.formatDate('M d, yy', dateObj);
|
||||
} else {
|
||||
this.displayedDate = 'No due date';
|
||||
}
|
||||
}
|
||||
|
||||
prepSelectedDate() {
|
||||
const datePayload = {};
|
||||
datePayload[this.abilityName] = {};
|
||||
datePayload[this.abilityName].due_date = this.rawSelectedDate;
|
||||
this.datePayload = datePayload;
|
||||
}
|
||||
|
||||
submitSelectedDate(isDropdown) {
|
||||
return $.ajax({
|
||||
type: 'PUT',
|
||||
url: this.issueUpdateURL,
|
||||
data: this.datePayload,
|
||||
dataType: 'json',
|
||||
beforeSend: () => {
|
||||
const selectedDateValue = this.datePayload[this.abilityName].due_date;
|
||||
const displayedDateStyle = this.displayedDate !== 'No due date' ? 'bold' : 'no-value';
|
||||
|
||||
this.$loading.fadeIn();
|
||||
|
||||
if (isDropdown) {
|
||||
this.$dropdown.trigger('loading.gl.dropdown');
|
||||
this.$selectbox.hide();
|
||||
}
|
||||
|
||||
this.$value.css('display', '');
|
||||
this.$valueContent.html(`<span class='${displayedDateStyle}'>${this.displayedDate}</span>`);
|
||||
this.$sidebarValue.html(this.displayedDate);
|
||||
|
||||
return selectedDateValue.length ?
|
||||
$('.js-remove-due-date-holder').removeClass('hidden') :
|
||||
$('.js-remove-due-date-holder').addClass('hidden');
|
||||
|
||||
}
|
||||
}).done((data) => {
|
||||
if (isDropdown) {
|
||||
this.$dropdown.trigger('loaded.gl.dropdown');
|
||||
this.$dropdown.dropdown('toggle');
|
||||
}
|
||||
return this.$loading.fadeOut();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class DueDateSelectors {
|
||||
constructor() {
|
||||
this.initMilestoneDueDate();
|
||||
this.initIssuableSelect();
|
||||
}
|
||||
|
||||
initMilestoneDueDate() {
|
||||
const $datePicker = $('.datepicker');
|
||||
|
||||
if ($datePicker.length) {
|
||||
const $dueDate = $('#milestone_due_date');
|
||||
$datePicker.datepicker({
|
||||
dateFormat: 'yy-mm-dd',
|
||||
onSelect: (dateText, inst) => {
|
||||
$dueDate.val(dateText);
|
||||
}
|
||||
}).datepicker('setDate', $.datepicker.parseDate('yy-mm-dd', $dueDate.val()));
|
||||
}
|
||||
$('.js-clear-due-date').on('click', (e) => {
|
||||
e.preventDefault();
|
||||
$.datepicker._clearDate($datePicker);
|
||||
});
|
||||
}
|
||||
|
||||
initIssuableSelect() {
|
||||
const $loading = $('.js-issuable-update .due_date').find('.block-loading').hide();
|
||||
|
||||
$('.js-due-date-select').each((i, dropdown) => {
|
||||
const $dropdown = $(dropdown);
|
||||
new DueDateSelect({
|
||||
$dropdown,
|
||||
$loading
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
global.DueDateSelectors = DueDateSelectors;
|
||||
|
||||
})(window.gl || (window.gl = {}));
|
|
@ -15,7 +15,7 @@
|
|||
$($pipelineBtn).add($pipelineGraph).toggleClass('graph-collapsed');
|
||||
|
||||
|
||||
graphCollapsed ? $btnText.text('Expand') : $btnText.text('Hide')
|
||||
graphCollapsed ? $btnText.text('Hide') : $btnText.text('Expand')
|
||||
}
|
||||
|
||||
addMarginToBuildColumns() {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
function ProjectFindFile(element1, options) {
|
||||
this.element = element1;
|
||||
this.options = options;
|
||||
this.goToBlob = bind(this.goToBlob, this);
|
||||
this.goToTree = bind(this.goToTree, this);
|
||||
this.selectRowDown = bind(this.selectRowDown, this);
|
||||
this.selectRowUp = bind(this.selectRowUp, this);
|
||||
|
@ -154,6 +155,14 @@
|
|||
return location.href = this.options.treeUrl;
|
||||
};
|
||||
|
||||
ProjectFindFile.prototype.goToBlob = function() {
|
||||
var $link = this.element.find(".tree-item.selected .tree-item-file-name a");
|
||||
|
||||
if ($link.length) {
|
||||
$link.get(0).click();
|
||||
}
|
||||
};
|
||||
|
||||
return ProjectFindFile;
|
||||
|
||||
})();
|
||||
|
|
|
@ -45,40 +45,38 @@
|
|||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-size: 1.75em;
|
||||
font-weight: 600;
|
||||
margin: 1em 0 10px;
|
||||
margin: 16px 0 10px;
|
||||
padding: 0 0 0.3em;
|
||||
border-bottom: 1px solid $btn-default-border;
|
||||
border-bottom: 1px solid $white-dark;
|
||||
color: $gl-gray-dark;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.6em;
|
||||
font-size: 1.5em;
|
||||
font-weight: 600;
|
||||
margin: 1em 0 10px;
|
||||
padding-bottom: 0.3em;
|
||||
border-bottom: 1px solid $btn-default-border;
|
||||
margin: 16px 0 10px;
|
||||
color: $gl-gray-dark;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1em 0 10px;
|
||||
font-size: 1.4em;
|
||||
margin: 16px 0 10px;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 1em 0 10px;
|
||||
font-size: 1.25em;
|
||||
margin: 16px 0 10px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 1em 0 10px;
|
||||
margin: 16px 0 10px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin: 1em 0 10px;
|
||||
margin: 16px 0 10px;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
|
@ -87,12 +85,12 @@
|
|||
font-size: inherit;
|
||||
padding: 8px 21px;
|
||||
margin: 12px 0;
|
||||
border-left: 3px solid #e7e9ed;
|
||||
border-left: 3px solid $white-dark;
|
||||
}
|
||||
|
||||
blockquote:dir(rtl) {
|
||||
border-left: 0;
|
||||
border-right: 3px solid #e7e9ed;
|
||||
border-right: 3px solid $white-dark;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
|
||||
.detail-page-description {
|
||||
.title {
|
||||
margin: 0;
|
||||
font-size: 23px;
|
||||
margin: 0 0 16px;
|
||||
font-size: 2em;
|
||||
color: $gl-gray-dark;
|
||||
padding: 0 0 0.3em;
|
||||
border-bottom: 1px solid $white-dark;
|
||||
}
|
||||
|
||||
.description {
|
||||
|
|
|
@ -438,13 +438,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.merge-request-details {
|
||||
|
||||
.title {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.merge-request-tabs {
|
||||
background-color: #fff;
|
||||
|
||||
|
|
|
@ -169,4 +169,8 @@
|
|||
margin-top: 11px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.download-button {
|
||||
margin-left: $btn-side-margin;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,10 @@ module Ci
|
|||
transition any => :canceled
|
||||
end
|
||||
|
||||
# IMPORTANT
|
||||
# Do not add any operations to this state_machine
|
||||
# Create a separate worker for each new operation
|
||||
|
||||
before_transition [:created, :pending] => :running do |pipeline|
|
||||
pipeline.started_at = Time.now
|
||||
end
|
||||
|
@ -62,13 +66,11 @@ module Ci
|
|||
end
|
||||
|
||||
after_transition [:created, :pending] => :running do |pipeline|
|
||||
MergeRequest::Metrics.where(merge_request_id: pipeline.merge_requests.map(&:id)).
|
||||
update_all(latest_build_started_at: pipeline.started_at, latest_build_finished_at: nil)
|
||||
pipeline.run_after_commit { PipelineMetricsWorker.perform_async(id) }
|
||||
end
|
||||
|
||||
after_transition any => [:success] do |pipeline|
|
||||
MergeRequest::Metrics.where(merge_request_id: pipeline.merge_requests.map(&:id)).
|
||||
update_all(latest_build_finished_at: pipeline.finished_at)
|
||||
pipeline.run_after_commit { PipelineMetricsWorker.perform_async(id) }
|
||||
end
|
||||
|
||||
after_transition [:created, :pending, :running] => :success do |pipeline|
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- if !project.empty_repo? && can?(current_user, :download_code, project)
|
||||
%span{class: 'hidden-xs hidden-sm'}
|
||||
%span{class: 'hidden-xs hidden-sm download-button'}
|
||||
.dropdown.inline
|
||||
%button.btn{ 'data-toggle' => 'dropdown' }
|
||||
= icon('download')
|
||||
|
|
|
@ -171,5 +171,5 @@
|
|||
new LabelsSelect();
|
||||
new IssuableContext('#{escape_javascript(current_user.to_json(only: [:username, :id, :name]))}');
|
||||
new Subscription('.subscription')
|
||||
new DueDateSelect();
|
||||
new gl.DueDateSelectors();
|
||||
sidebar = new Sidebar();
|
||||
|
|
30
app/workers/pipeline_metrics_worker.rb
Normal file
30
app/workers/pipeline_metrics_worker.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
class PipelineMetricsWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
sidekiq_options queue: :default
|
||||
|
||||
def perform(pipeline_id)
|
||||
Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline|
|
||||
update_metrics_for_active_pipeline(pipeline) if pipeline.active?
|
||||
update_metrics_for_succeeded_pipeline(pipeline) if pipeline.success?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_metrics_for_active_pipeline(pipeline)
|
||||
metrics(pipeline).update_all(latest_build_started_at: pipeline.started_at, latest_build_finished_at: nil)
|
||||
end
|
||||
|
||||
def update_metrics_for_succeeded_pipeline(pipeline)
|
||||
metrics(pipeline).update_all(latest_build_started_at: pipeline.started_at, latest_build_finished_at: pipeline.finished_at)
|
||||
end
|
||||
|
||||
def metrics(pipeline)
|
||||
MergeRequest::Metrics.where(merge_request_id: merge_requests(pipeline))
|
||||
end
|
||||
|
||||
def merge_requests(pipeline)
|
||||
pipeline.merge_requests.map(&:id)
|
||||
end
|
||||
end
|
|
@ -1,8 +1,5 @@
|
|||
require 'constraints/user_url_constrainer'
|
||||
|
||||
get '/u/:username', to: redirect('/%{username}'),
|
||||
constraints: { username: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }
|
||||
|
||||
devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks,
|
||||
registrations: :registrations,
|
||||
passwords: :passwords,
|
||||
|
@ -23,7 +20,7 @@ constraints(UserUrlConstrainer.new) do
|
|||
end
|
||||
end
|
||||
|
||||
scope(path: 'u/:username',
|
||||
scope(path: 'users/:username',
|
||||
as: :user,
|
||||
constraints: { username: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ },
|
||||
controller: :users) do
|
||||
|
@ -36,3 +33,12 @@ scope(path: 'u/:username',
|
|||
get :exists
|
||||
get '/', to: redirect('/%{username}')
|
||||
end
|
||||
|
||||
# Compatibility with old routing
|
||||
# TODO (dzaporozhets): remove in 10.0
|
||||
get '/u/:username', to: redirect('/%{username}'), constraints: { username: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }
|
||||
# TODO (dzaporozhets): remove in 9.0
|
||||
get '/u/:username/groups', to: redirect('/users/%{username}/groups'), constraints: { username: /[a-zA-Z.0-9_\-]+/ }
|
||||
get '/u/:username/projects', to: redirect('/users/%{username}/projects'), constraints: { username: /[a-zA-Z.0-9_\-]+/ }
|
||||
get '/u/:username/snippets', to: redirect('/users/%{username}/snippets'), constraints: { username: /[a-zA-Z.0-9_\-]+/ }
|
||||
get '/u/:username/contributed', to: redirect('/users/%{username}/contributed'), constraints: { username: /[a-zA-Z.0-9_\-]+/ }
|
||||
|
|
|
@ -43,7 +43,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/root"
|
||||
"web_url": "http://gitlab.example.com/root"
|
||||
},
|
||||
"created_at": "2016-06-15T10:09:34.206Z",
|
||||
"updated_at": "2016-06-15T10:09:34.206Z",
|
||||
|
@ -59,7 +59,7 @@ Example Response:
|
|||
"id": 26,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/user4"
|
||||
"web_url": "http://gitlab.example.com/user4"
|
||||
},
|
||||
"created_at": "2016-06-15T10:09:34.177Z",
|
||||
"updated_at": "2016-06-15T10:09:34.177Z",
|
||||
|
@ -103,7 +103,7 @@ Example Response:
|
|||
"id": 26,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/user4"
|
||||
"web_url": "http://gitlab.example.com/user4"
|
||||
},
|
||||
"created_at": "2016-06-15T10:09:34.177Z",
|
||||
"updated_at": "2016-06-15T10:09:34.177Z",
|
||||
|
@ -146,7 +146,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/root"
|
||||
"web_url": "http://gitlab.example.com/root"
|
||||
},
|
||||
"created_at": "2016-06-17T17:47:29.266Z",
|
||||
"updated_at": "2016-06-17T17:47:29.266Z",
|
||||
|
@ -190,7 +190,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/root"
|
||||
"web_url": "http://gitlab.example.com/root"
|
||||
},
|
||||
"created_at": "2016-06-17T17:47:29.266Z",
|
||||
"updated_at": "2016-06-17T17:47:29.266Z",
|
||||
|
@ -238,7 +238,7 @@ Example Response:
|
|||
"id": 26,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/user4"
|
||||
"web_url": "http://gitlab.example.com/user4"
|
||||
},
|
||||
"created_at": "2016-06-15T10:09:34.197Z",
|
||||
"updated_at": "2016-06-15T10:09:34.197Z",
|
||||
|
@ -279,7 +279,7 @@ Example Response:
|
|||
"id": 26,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/user4"
|
||||
"web_url": "http://gitlab.example.com/user4"
|
||||
},
|
||||
"created_at": "2016-06-15T10:09:34.197Z",
|
||||
"updated_at": "2016-06-15T10:09:34.197Z",
|
||||
|
@ -319,7 +319,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/root"
|
||||
"web_url": "http://gitlab.example.com/root"
|
||||
},
|
||||
"created_at": "2016-06-17T19:59:55.888Z",
|
||||
"updated_at": "2016-06-17T19:59:55.888Z",
|
||||
|
@ -362,7 +362,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://gitlab.example.com/u/root"
|
||||
"web_url": "http://gitlab.example.com/root"
|
||||
},
|
||||
"created_at": "2016-06-17T19:59:55.888Z",
|
||||
"updated_at": "2016-06-17T19:59:55.888Z",
|
||||
|
|
|
@ -64,7 +64,7 @@ Example of response
|
|||
"state": "active",
|
||||
"twitter": "",
|
||||
"username": "root",
|
||||
"web_url": "http://gitlab.dev/u/root",
|
||||
"web_url": "http://gitlab.dev/root",
|
||||
"website_url": ""
|
||||
}
|
||||
},
|
||||
|
@ -108,7 +108,7 @@ Example of response
|
|||
"state": "active",
|
||||
"twitter": "",
|
||||
"username": "root",
|
||||
"web_url": "http://gitlab.dev/u/root",
|
||||
"web_url": "http://gitlab.dev/root",
|
||||
"website_url": ""
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ Example of response
|
|||
"state": "active",
|
||||
"twitter": "",
|
||||
"username": "root",
|
||||
"web_url": "http://gitlab.dev/u/root",
|
||||
"web_url": "http://gitlab.dev/root",
|
||||
"website_url": ""
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ Example of response
|
|||
"state": "active",
|
||||
"twitter": "",
|
||||
"username": "root",
|
||||
"web_url": "http://gitlab.dev/u/root",
|
||||
"web_url": "http://gitlab.dev/root",
|
||||
"website_url": ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -288,7 +288,7 @@ Example response:
|
|||
```json
|
||||
{
|
||||
"author" : {
|
||||
"web_url" : "https://gitlab.example.com/u/thedude",
|
||||
"web_url" : "https://gitlab.example.com/thedude",
|
||||
"avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png",
|
||||
"username" : "thedude",
|
||||
"state" : "active",
|
||||
|
@ -343,7 +343,7 @@ Example response:
|
|||
"author" : {
|
||||
"username" : "thedude",
|
||||
"state" : "active",
|
||||
"web_url" : "https://gitlab.example.com/u/thedude",
|
||||
"web_url" : "https://gitlab.example.com/thedude",
|
||||
"avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png",
|
||||
"id" : 28,
|
||||
"name" : "Jeff Lebowski"
|
||||
|
@ -370,7 +370,7 @@ Example response:
|
|||
"id" : 28,
|
||||
"name" : "Jeff Lebowski",
|
||||
"username" : "thedude",
|
||||
"web_url" : "https://gitlab.example.com/u/thedude",
|
||||
"web_url" : "https://gitlab.example.com/thedude",
|
||||
"state" : "active",
|
||||
"avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png"
|
||||
},
|
||||
|
@ -408,7 +408,7 @@ Example response:
|
|||
```json
|
||||
{
|
||||
"author" : {
|
||||
"web_url" : "https://gitlab.example.com/u/thedude",
|
||||
"web_url" : "https://gitlab.example.com/thedude",
|
||||
"name" : "Jeff Lebowski",
|
||||
"avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png",
|
||||
"username" : "thedude",
|
||||
|
|
|
@ -56,7 +56,7 @@ Example of response
|
|||
"state": "active",
|
||||
"twitter": "",
|
||||
"username": "root",
|
||||
"web_url": "http://localhost:3000/u/root",
|
||||
"web_url": "http://localhost:3000/root",
|
||||
"website_url": ""
|
||||
}
|
||||
},
|
||||
|
@ -75,7 +75,7 @@ Example of response
|
|||
"name": "Administrator",
|
||||
"state": "active",
|
||||
"username": "root",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ Example of response
|
|||
"state": "active",
|
||||
"twitter": "",
|
||||
"username": "root",
|
||||
"web_url": "http://localhost:3000/u/root",
|
||||
"web_url": "http://localhost:3000/root",
|
||||
"website_url": ""
|
||||
}
|
||||
},
|
||||
|
@ -133,7 +133,7 @@ Example of response
|
|||
"name": "Administrator",
|
||||
"state": "active",
|
||||
"username": "root",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -169,7 +169,7 @@ Example of response
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"environment": {
|
||||
"id": 9,
|
||||
|
@ -193,7 +193,7 @@ Example of response
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://localhost:3000/u/root",
|
||||
"web_url": "http://localhost:3000/root",
|
||||
"created_at": "2016-08-11T07:09:20.351Z",
|
||||
"is_admin": true,
|
||||
"bio": null,
|
||||
|
|
|
@ -46,7 +46,7 @@ Example response:
|
|||
"author" : {
|
||||
"state" : "active",
|
||||
"id" : 18,
|
||||
"web_url" : "https://gitlab.example.com/u/eileen.lowe",
|
||||
"web_url" : "https://gitlab.example.com/eileen.lowe",
|
||||
"name" : "Alexandra Bashirian",
|
||||
"avatar_url" : null,
|
||||
"username" : "eileen.lowe"
|
||||
|
@ -67,7 +67,7 @@ Example response:
|
|||
"state" : "active",
|
||||
"id" : 1,
|
||||
"name" : "Administrator",
|
||||
"web_url" : "https://gitlab.example.com/u/root",
|
||||
"web_url" : "https://gitlab.example.com/root",
|
||||
"avatar_url" : null,
|
||||
"username" : "root"
|
||||
},
|
||||
|
@ -134,7 +134,7 @@ Example response:
|
|||
},
|
||||
"author" : {
|
||||
"state" : "active",
|
||||
"web_url" : "https://gitlab.example.com/u/root",
|
||||
"web_url" : "https://gitlab.example.com/root",
|
||||
"avatar_url" : null,
|
||||
"username" : "root",
|
||||
"id" : 1,
|
||||
|
@ -145,7 +145,7 @@ Example response:
|
|||
"iid" : 1,
|
||||
"assignee" : {
|
||||
"avatar_url" : null,
|
||||
"web_url" : "https://gitlab.example.com/u/lennie",
|
||||
"web_url" : "https://gitlab.example.com/lennie",
|
||||
"state" : "active",
|
||||
"username" : "lennie",
|
||||
"id" : 9,
|
||||
|
@ -215,7 +215,7 @@ Example response:
|
|||
},
|
||||
"author" : {
|
||||
"state" : "active",
|
||||
"web_url" : "https://gitlab.example.com/u/root",
|
||||
"web_url" : "https://gitlab.example.com/root",
|
||||
"avatar_url" : null,
|
||||
"username" : "root",
|
||||
"id" : 1,
|
||||
|
@ -226,7 +226,7 @@ Example response:
|
|||
"iid" : 1,
|
||||
"assignee" : {
|
||||
"avatar_url" : null,
|
||||
"web_url" : "https://gitlab.example.com/u/lennie",
|
||||
"web_url" : "https://gitlab.example.com/lennie",
|
||||
"state" : "active",
|
||||
"username" : "lennie",
|
||||
"id" : 9,
|
||||
|
@ -281,7 +281,7 @@ Example response:
|
|||
},
|
||||
"author" : {
|
||||
"state" : "active",
|
||||
"web_url" : "https://gitlab.example.com/u/root",
|
||||
"web_url" : "https://gitlab.example.com/root",
|
||||
"avatar_url" : null,
|
||||
"username" : "root",
|
||||
"id" : 1,
|
||||
|
@ -292,7 +292,7 @@ Example response:
|
|||
"iid" : 1,
|
||||
"assignee" : {
|
||||
"avatar_url" : null,
|
||||
"web_url" : "https://gitlab.example.com/u/lennie",
|
||||
"web_url" : "https://gitlab.example.com/lennie",
|
||||
"state" : "active",
|
||||
"username" : "lennie",
|
||||
"id" : 9,
|
||||
|
@ -357,7 +357,7 @@ Example response:
|
|||
"name" : "Alexandra Bashirian",
|
||||
"avatar_url" : null,
|
||||
"state" : "active",
|
||||
"web_url" : "https://gitlab.example.com/u/eileen.lowe",
|
||||
"web_url" : "https://gitlab.example.com/eileen.lowe",
|
||||
"id" : 18,
|
||||
"username" : "eileen.lowe"
|
||||
},
|
||||
|
@ -414,7 +414,7 @@ Example response:
|
|||
"username" : "eileen.lowe",
|
||||
"id" : 18,
|
||||
"state" : "active",
|
||||
"web_url" : "https://gitlab.example.com/u/eileen.lowe"
|
||||
"web_url" : "https://gitlab.example.com/eileen.lowe"
|
||||
},
|
||||
"state" : "closed",
|
||||
"title" : "Issues with auth",
|
||||
|
@ -500,7 +500,7 @@ Example response:
|
|||
"id": 12,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/axel.block"
|
||||
"web_url": "https://gitlab.example.com/axel.block"
|
||||
},
|
||||
"author": {
|
||||
"name": "Kris Steuber",
|
||||
|
@ -508,7 +508,7 @@ Example response:
|
|||
"id": 10,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/7a190fecbaa68212a4b68aeb6e3acd10?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/solon.cremin"
|
||||
"web_url": "https://gitlab.example.com/solon.cremin"
|
||||
},
|
||||
"due_date": null,
|
||||
"web_url": "http://example.com/example/example/issues/11",
|
||||
|
@ -557,7 +557,7 @@ Example response:
|
|||
"id": 12,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/axel.block"
|
||||
"web_url": "https://gitlab.example.com/axel.block"
|
||||
},
|
||||
"author": {
|
||||
"name": "Kris Steuber",
|
||||
|
@ -565,7 +565,7 @@ Example response:
|
|||
"id": 10,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/7a190fecbaa68212a4b68aeb6e3acd10?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/solon.cremin"
|
||||
"web_url": "https://gitlab.example.com/solon.cremin"
|
||||
},
|
||||
"due_date": null,
|
||||
"web_url": "http://example.com/example/example/issues/11",
|
||||
|
@ -614,7 +614,7 @@ Example response:
|
|||
"id": 21,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/3e6f06a86cf27fa8b56f3f74f7615987?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/keyon"
|
||||
"web_url": "https://gitlab.example.com/keyon"
|
||||
},
|
||||
"author": {
|
||||
"name": "Vivian Hermann",
|
||||
|
@ -622,7 +622,7 @@ Example response:
|
|||
"id": 11,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/5224fd70153710e92fb8bcf79ac29d67?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/orville"
|
||||
"web_url": "https://gitlab.example.com/orville"
|
||||
},
|
||||
"subscribed": false,
|
||||
"due_date": null,
|
||||
|
@ -669,7 +669,7 @@ Example response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/root"
|
||||
"web_url": "https://gitlab.example.com/root"
|
||||
},
|
||||
"action_name": "marked",
|
||||
"target_type": "Issue",
|
||||
|
@ -700,7 +700,7 @@ Example response:
|
|||
"id": 14,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/a7fa515d53450023c83d62986d0658a8?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/francisca"
|
||||
"web_url": "https://gitlab.example.com/francisca"
|
||||
},
|
||||
"author": {
|
||||
"name": "Maxie Medhurst",
|
||||
|
@ -708,7 +708,7 @@ Example response:
|
|||
"id": 12,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/craig_rutherford"
|
||||
"web_url": "https://gitlab.example.com/craig_rutherford"
|
||||
},
|
||||
"subscribed": true,
|
||||
"user_notes_count": 7,
|
||||
|
|
|
@ -24,7 +24,7 @@ Parameters:
|
|||
"id": 25,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/cfa35b8cd2ec278026357769582fa563?s=40\u0026d=identicon",
|
||||
"web_url": "http://localhost:3000/u/john_smith",
|
||||
"web_url": "http://localhost:3000/john_smith",
|
||||
"created_at": "2015-09-03T07:24:01.670Z",
|
||||
"is_admin": false,
|
||||
"bio": null,
|
||||
|
|
|
@ -621,7 +621,7 @@ Example response when the GitLab issue tracker is used:
|
|||
"author" : {
|
||||
"state" : "active",
|
||||
"id" : 18,
|
||||
"web_url" : "https://gitlab.example.com/u/eileen.lowe",
|
||||
"web_url" : "https://gitlab.example.com/eileen.lowe",
|
||||
"name" : "Alexandra Bashirian",
|
||||
"avatar_url" : null,
|
||||
"username" : "eileen.lowe"
|
||||
|
@ -642,7 +642,7 @@ Example response when the GitLab issue tracker is used:
|
|||
"state" : "active",
|
||||
"id" : 1,
|
||||
"name" : "Administrator",
|
||||
"web_url" : "https://gitlab.example.com/u/root",
|
||||
"web_url" : "https://gitlab.example.com/root",
|
||||
"avatar_url" : null,
|
||||
"username" : "root"
|
||||
},
|
||||
|
@ -711,7 +711,7 @@ Example response:
|
|||
"id": 19,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/39ce4a2822cc896933ffbd68c1470e55?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/leila"
|
||||
"web_url": "https://gitlab.example.com/leila"
|
||||
},
|
||||
"assignee": {
|
||||
"name": "Celine Wehner",
|
||||
|
@ -719,7 +719,7 @@ Example response:
|
|||
"id": 16,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/f4cd5605b769dd2ce405a27c6e6f2684?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/carli"
|
||||
"web_url": "https://gitlab.example.com/carli"
|
||||
},
|
||||
"source_project_id": 5,
|
||||
"target_project_id": 5,
|
||||
|
@ -787,7 +787,7 @@ Example response:
|
|||
"id": 19,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/39ce4a2822cc896933ffbd68c1470e55?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/leila"
|
||||
"web_url": "https://gitlab.example.com/leila"
|
||||
},
|
||||
"assignee": {
|
||||
"name": "Celine Wehner",
|
||||
|
@ -795,7 +795,7 @@ Example response:
|
|||
"id": 16,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/f4cd5605b769dd2ce405a27c6e6f2684?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/carli"
|
||||
"web_url": "https://gitlab.example.com/carli"
|
||||
},
|
||||
"source_project_id": 5,
|
||||
"target_project_id": 5,
|
||||
|
@ -858,7 +858,7 @@ Example response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/root"
|
||||
"web_url": "https://gitlab.example.com/root"
|
||||
},
|
||||
"action_name": "marked",
|
||||
"target_type": "MergeRequest",
|
||||
|
@ -881,7 +881,7 @@ Example response:
|
|||
"id": 14,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/a7fa515d53450023c83d62986d0658a8?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/francisca"
|
||||
"web_url": "https://gitlab.example.com/francisca"
|
||||
},
|
||||
"assignee": {
|
||||
"name": "Dr. Gabrielle Strosin",
|
||||
|
@ -889,7 +889,7 @@ Example response:
|
|||
"id": 4,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/733005fcd7e6df12d2d8580171ccb966?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/barrett.krajcik"
|
||||
"web_url": "https://gitlab.example.com/barrett.krajcik"
|
||||
},
|
||||
"source_project_id": 3,
|
||||
"target_project_id": 3,
|
||||
|
|
|
@ -143,7 +143,7 @@ Example Response:
|
|||
"state": "active",
|
||||
"created_at": "2013-09-30T13:46:01Z",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/5224fd70153710e92fb8bcf79ac29d67?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/pipin"
|
||||
"web_url": "https://gitlab.example.com/pipin"
|
||||
},
|
||||
"created_at": "2016-04-05T22:10:44.164Z",
|
||||
"system": false,
|
||||
|
@ -268,7 +268,7 @@ Example Response:
|
|||
"state": "active",
|
||||
"created_at": "2013-09-30T13:46:01Z",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/5224fd70153710e92fb8bcf79ac29d67?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/pipin"
|
||||
"web_url": "https://gitlab.example.com/pipin"
|
||||
},
|
||||
"created_at": "2016-04-06T16:51:53.239Z",
|
||||
"system": false,
|
||||
|
@ -398,7 +398,7 @@ Example Response:
|
|||
"state": "active",
|
||||
"created_at": "2013-09-30T13:46:01Z",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/5224fd70153710e92fb8bcf79ac29d67?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/pipin"
|
||||
"web_url": "https://gitlab.example.com/pipin"
|
||||
},
|
||||
"created_at": "2016-04-05T22:11:59.923Z",
|
||||
"system": false,
|
||||
|
|
|
@ -34,7 +34,7 @@ Example of response
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"created_at": "2016-08-16T10:23:19.007Z",
|
||||
"updated_at": "2016-08-16T10:23:19.216Z",
|
||||
|
@ -57,7 +57,7 @@ Example of response
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"created_at": "2016-08-16T10:23:21.184Z",
|
||||
"updated_at": "2016-08-16T10:23:21.314Z",
|
||||
|
@ -103,7 +103,7 @@ Example of response
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"created_at": "2016-08-11T11:28:34.085Z",
|
||||
"updated_at": "2016-08-11T11:32:35.169Z",
|
||||
|
@ -148,7 +148,7 @@ Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"created_at": "2016-08-11T11:28:34.085Z",
|
||||
"updated_at": "2016-08-11T11:32:35.169Z",
|
||||
|
@ -193,7 +193,7 @@ Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"created_at": "2016-08-11T11:28:34.085Z",
|
||||
"updated_at": "2016-08-11T11:32:35.169Z",
|
||||
|
|
|
@ -465,7 +465,7 @@ Parameters:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
},
|
||||
|
@ -482,7 +482,7 @@ Parameters:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"author_username": "john",
|
||||
"data": {
|
||||
|
@ -528,7 +528,7 @@ Parameters:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
},
|
||||
|
@ -552,7 +552,7 @@ Parameters:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"created_at": "2015-12-04T10:33:56.698Z",
|
||||
"system": false,
|
||||
|
@ -567,7 +567,7 @@ Parameters:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/root"
|
||||
"web_url": "https://gitlab.example.com/root"
|
||||
},
|
||||
"action_name": "marked",
|
||||
"target_type": "MergeRequest",
|
||||
|
@ -67,7 +67,7 @@ Example Response:
|
|||
"id": 12,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/craig_rutherford"
|
||||
"web_url": "https://gitlab.example.com/craig_rutherford"
|
||||
},
|
||||
"assignee": {
|
||||
"name": "Administrator",
|
||||
|
@ -75,7 +75,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/root"
|
||||
"web_url": "https://gitlab.example.com/root"
|
||||
},
|
||||
"source_project_id": 2,
|
||||
"target_project_id": 2,
|
||||
|
@ -117,7 +117,7 @@ Example Response:
|
|||
"id": 12,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/craig_rutherford"
|
||||
"web_url": "https://gitlab.example.com/craig_rutherford"
|
||||
},
|
||||
"action_name": "assigned",
|
||||
"target_type": "MergeRequest",
|
||||
|
@ -140,7 +140,7 @@ Example Response:
|
|||
"id": 12,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/craig_rutherford"
|
||||
"web_url": "https://gitlab.example.com/craig_rutherford"
|
||||
},
|
||||
"assignee": {
|
||||
"name": "Administrator",
|
||||
|
@ -148,7 +148,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/root"
|
||||
"web_url": "https://gitlab.example.com/root"
|
||||
},
|
||||
"source_project_id": 2,
|
||||
"target_project_id": 2,
|
||||
|
@ -215,7 +215,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/root"
|
||||
"web_url": "https://gitlab.example.com/root"
|
||||
},
|
||||
"action_name": "marked",
|
||||
"target_type": "MergeRequest",
|
||||
|
@ -238,7 +238,7 @@ Example Response:
|
|||
"id": 12,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/craig_rutherford"
|
||||
"web_url": "https://gitlab.example.com/craig_rutherford"
|
||||
},
|
||||
"assignee": {
|
||||
"name": "Administrator",
|
||||
|
@ -246,7 +246,7 @@ Example Response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "https://gitlab.example.com/u/root"
|
||||
"web_url": "https://gitlab.example.com/root"
|
||||
},
|
||||
"source_project_id": 2,
|
||||
"target_project_id": 2,
|
||||
|
|
|
@ -20,7 +20,7 @@ GET /users
|
|||
"name": "John Smith",
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg",
|
||||
"web_url": "http://localhost:3000/u/john_smith"
|
||||
"web_url": "http://localhost:3000/john_smith"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
|
@ -28,7 +28,7 @@ GET /users
|
|||
"name": "Jack Smith",
|
||||
"state": "blocked",
|
||||
"avatar_url": "http://gravatar.com/../e32131cd8.jpeg",
|
||||
"web_url": "http://localhost:3000/u/jack_smith"
|
||||
"web_url": "http://localhost:3000/jack_smith"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -48,7 +48,7 @@ GET /users
|
|||
"name": "John Smith",
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
|
||||
"web_url": "http://localhost:3000/u/john_smith",
|
||||
"web_url": "http://localhost:3000/john_smith",
|
||||
"created_at": "2012-05-23T08:00:58Z",
|
||||
"is_admin": false,
|
||||
"bio": null,
|
||||
|
@ -81,7 +81,7 @@ GET /users
|
|||
"name": "Jack Smith",
|
||||
"state": "blocked",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/2/index.jpg",
|
||||
"web_url": "http://localhost:3000/u/jack_smith",
|
||||
"web_url": "http://localhost:3000/jack_smith",
|
||||
"created_at": "2012-05-23T08:01:01Z",
|
||||
"is_admin": false,
|
||||
"bio": null,
|
||||
|
@ -141,7 +141,7 @@ Parameters:
|
|||
"name": "John Smith",
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg",
|
||||
"web_url": "http://localhost:3000/u/john_smith",
|
||||
"web_url": "http://localhost:3000/john_smith",
|
||||
"created_at": "2012-05-23T08:00:58Z",
|
||||
"is_admin": false,
|
||||
"bio": null,
|
||||
|
@ -172,7 +172,7 @@ Parameters:
|
|||
"name": "John Smith",
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
|
||||
"web_url": "http://localhost:3000/u/john_smith",
|
||||
"web_url": "http://localhost:3000/john_smith",
|
||||
"created_at": "2012-05-23T08:00:58Z",
|
||||
"is_admin": false,
|
||||
"bio": null,
|
||||
|
@ -293,7 +293,7 @@ GET /user
|
|||
"name": "John Smith",
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
|
||||
"web_url": "http://localhost:3000/u/john_smith",
|
||||
"web_url": "http://localhost:3000/john_smith",
|
||||
"created_at": "2012-05-23T08:00:58Z",
|
||||
"is_admin": false,
|
||||
"bio": null,
|
||||
|
@ -665,7 +665,7 @@ Example response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
},
|
||||
|
@ -682,7 +682,7 @@ Example response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"author_username": "john",
|
||||
"data": {
|
||||
|
@ -728,7 +728,7 @@ Example response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
},
|
||||
|
@ -752,7 +752,7 @@ Example response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"created_at": "2015-12-04T10:33:56.698Z",
|
||||
"system": false,
|
||||
|
@ -767,7 +767,7 @@ Example response:
|
|||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
"web_url": "http://localhost:3000/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
}
|
||||
|
|
|
@ -254,5 +254,5 @@ impact on runtime performance, and as such, using a constant instead of
|
|||
referencing an object directly may even slow code down.
|
||||
|
||||
[#15607]: https://gitlab.com/gitlab-org/gitlab-ce/issues/15607
|
||||
[yorickpeterse]: https://gitlab.com/u/yorickpeterse
|
||||
[yorickpeterse]: https://gitlab.com/yorickpeterse
|
||||
[anti-pattern]: https://en.wikipedia.org/wiki/Anti-pattern
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 31 KiB |
|
@ -21,7 +21,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps
|
|||
expect(response_headers['Content-Type']).to have_content("application/atom+xml")
|
||||
expect(body).to have_selector("title", text: "#{@project.name}:master commits")
|
||||
expect(body).to have_selector("author email", text: commit.author_email)
|
||||
expect(body).to have_selector("entry summary", text: commit.description[0..10])
|
||||
expect(body).to have_selector("entry summary", text: commit.description[0..10].delete("\r"))
|
||||
end
|
||||
|
||||
step 'I click on tag link' do
|
||||
|
|
|
@ -512,6 +512,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
|
|||
step 'I should see new target branch changes' do
|
||||
expect(page).to have_content 'Request to merge fix into feature'
|
||||
expect(page).to have_content 'Target branch changed from merge-test to feature'
|
||||
wait_for_ajax
|
||||
end
|
||||
|
||||
step 'I click on "Email Patches"' do
|
||||
|
|
42
spec/features/projects/files/find_file_keyboard_spec.rb
Normal file
42
spec/features/projects/files/find_file_keyboard_spec.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
require 'spec_helper'
|
||||
|
||||
feature 'Find file keyboard shortcuts', 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 namespace_project_find_file_path(project.namespace, project, project.repository.root_ref)
|
||||
|
||||
wait_for_ajax
|
||||
end
|
||||
|
||||
it 'opens file when pressing enter key' do
|
||||
fill_in 'file_find', with: 'CHANGELOG'
|
||||
|
||||
find('#file_find').native.send_keys(:enter)
|
||||
|
||||
expect(page).to have_selector('.blob-content-holder')
|
||||
|
||||
page.within('.file-title') do
|
||||
expect(page).to have_content('CHANGELOG')
|
||||
end
|
||||
end
|
||||
|
||||
it 'navigates files with arrow keys' do
|
||||
fill_in 'file_find', with: 'application.'
|
||||
|
||||
find('#file_find').native.send_keys(:down)
|
||||
find('#file_find').native.send_keys(:enter)
|
||||
|
||||
expect(page).to have_selector('.blob-content-holder')
|
||||
|
||||
page.within('.file-title') do
|
||||
expect(page).to have_content('application.js')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -51,6 +51,18 @@ feature 'Users', feature: true, js: true do
|
|||
expect(current_path).to eq user_path(user)
|
||||
expect(page).to have_text(user.name)
|
||||
end
|
||||
|
||||
scenario '/u/user1/groups redirects to user groups page' do
|
||||
visit '/u/user1/groups'
|
||||
|
||||
expect(current_path).to eq user_groups_path(user)
|
||||
end
|
||||
|
||||
scenario '/u/user1/projects redirects to user projects page' do
|
||||
visit '/u/user1/projects'
|
||||
|
||||
expect(current_path).to eq user_projects_path(user)
|
||||
end
|
||||
end
|
||||
|
||||
feature 'username validation' do
|
||||
|
|
|
@ -187,33 +187,24 @@ describe Ci::Pipeline, models: true do
|
|||
end
|
||||
end
|
||||
|
||||
describe "merge request metrics" do
|
||||
describe 'merge request metrics' do
|
||||
let(:project) { FactoryGirl.create :project }
|
||||
let(:pipeline) { FactoryGirl.create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master', sha: project.repository.commit('master').id) }
|
||||
let!(:merge_request) { create(:merge_request, source_project: project, source_branch: pipeline.ref) }
|
||||
|
||||
before do
|
||||
expect(PipelineMetricsWorker).to receive(:perform_async).with(pipeline.id)
|
||||
end
|
||||
|
||||
context 'when transitioning to running' do
|
||||
it 'records the build start time' do
|
||||
time = Time.now
|
||||
Timecop.freeze(time) { build.run }
|
||||
|
||||
expect(merge_request.reload.metrics.latest_build_started_at).to be_within(1.second).of(time)
|
||||
end
|
||||
|
||||
it 'clears the build end time' do
|
||||
build.run
|
||||
|
||||
expect(merge_request.reload.metrics.latest_build_finished_at).to be_nil
|
||||
it 'schedules metrics workers' do
|
||||
pipeline.run
|
||||
end
|
||||
end
|
||||
|
||||
context 'when transitioning to success' do
|
||||
it 'records the build end time' do
|
||||
build.run
|
||||
time = Time.now
|
||||
Timecop.freeze(time) { build.success }
|
||||
|
||||
expect(merge_request.reload.metrics.latest_build_finished_at).to be_within(1.second).of(time)
|
||||
it 'schedules metrics workers' do
|
||||
pipeline.succeed
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,27 +15,27 @@ describe UsersController, "routing" do
|
|||
end
|
||||
|
||||
it "to #groups" do
|
||||
expect(get("/u/User/groups")).to route_to('users#groups', username: 'User')
|
||||
expect(get("/users/User/groups")).to route_to('users#groups', username: 'User')
|
||||
end
|
||||
|
||||
it "to #projects" do
|
||||
expect(get("/u/User/projects")).to route_to('users#projects', username: 'User')
|
||||
expect(get("/users/User/projects")).to route_to('users#projects', username: 'User')
|
||||
end
|
||||
|
||||
it "to #contributed" do
|
||||
expect(get("/u/User/contributed")).to route_to('users#contributed', username: 'User')
|
||||
expect(get("/users/User/contributed")).to route_to('users#contributed', username: 'User')
|
||||
end
|
||||
|
||||
it "to #snippets" do
|
||||
expect(get("/u/User/snippets")).to route_to('users#snippets', username: 'User')
|
||||
expect(get("/users/User/snippets")).to route_to('users#snippets', username: 'User')
|
||||
end
|
||||
|
||||
it "to #calendar" do
|
||||
expect(get("/u/User/calendar")).to route_to('users#calendar', username: 'User')
|
||||
expect(get("/users/User/calendar")).to route_to('users#calendar', username: 'User')
|
||||
end
|
||||
|
||||
it "to #calendar_activities" do
|
||||
expect(get("/u/User/calendar_activities")).to route_to('users#calendar_activities', username: 'User')
|
||||
expect(get("/users/User/calendar_activities")).to route_to('users#calendar_activities', username: 'User')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -98,7 +98,9 @@ module TestEnv
|
|||
|
||||
def setup_gitlab_shell
|
||||
unless File.directory?(Gitlab.config.gitlab_shell.path)
|
||||
`rake gitlab:shell:install`
|
||||
unless system('rake', 'gitlab:shell:install')
|
||||
raise 'Can`t clone gitlab-shell'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
46
spec/workers/pipeline_metrics_worker_spec.rb
Normal file
46
spec/workers/pipeline_metrics_worker_spec.rb
Normal file
|
@ -0,0 +1,46 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe PipelineMetricsWorker do
|
||||
let(:project) { create(:project) }
|
||||
let!(:merge_request) { create(:merge_request, source_project: project, source_branch: pipeline.ref) }
|
||||
|
||||
let(:pipeline) do
|
||||
create(:ci_empty_pipeline,
|
||||
status: status,
|
||||
project: project,
|
||||
ref: 'master',
|
||||
sha: project.repository.commit('master').id,
|
||||
started_at: 1.hour.ago,
|
||||
finished_at: Time.now)
|
||||
end
|
||||
|
||||
describe '#perform' do
|
||||
subject { described_class.new.perform(pipeline.id) }
|
||||
|
||||
context 'when pipeline is running' do
|
||||
let(:status) { 'running' }
|
||||
|
||||
it 'records the build start time' do
|
||||
subject
|
||||
|
||||
expect(merge_request.reload.metrics.latest_build_started_at).to be_within(1.second).of(pipeline.started_at)
|
||||
end
|
||||
|
||||
it 'clears the build end time' do
|
||||
subject
|
||||
|
||||
expect(merge_request.reload.metrics.latest_build_finished_at).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when pipeline succeeded' do
|
||||
let(:status) { 'success' }
|
||||
|
||||
it 'records the build end time' do
|
||||
subject
|
||||
|
||||
expect(merge_request.reload.metrics.latest_build_finished_at).to be_within(1.second).of(pipeline.finished_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue