Commit 179ed967 authored by Regis's avatar Regis

Merge branch 'master' into auto-pipelines-vue

parents d8c73e3e a3cc2f1e
......@@ -2,4 +2,4 @@
/public/
/tmp/
/vendor/
/builds/
......@@ -4,7 +4,7 @@
"filenames"
],
"rules": {
"filenames/match-regex": [2, "^[a-z_]+$"]
"filenames/match-regex": [2, "^[a-z0-9_]+(.js)?$"]
},
"globals": {
"$": false,
......
Please view this file on the master branch, on stable branches it's out of date.
**Note:** This file is automatically generated. Please see the [developer
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 8.14.0 (2016-11-22)
- Show correct environment log in admin/logs (@duk3luk3 !7191)
- Fix Milestone dropdown not stay selected for `Upcoming` and `No Milestone` option !7117
- Backups do not fail anymore when using tar on annex and custom_hooks only. !5814
- Adds user project membership expired event to clarify why user was removed (Callum Dryden)
......@@ -14,6 +18,7 @@ Please view this file on the master branch, on stable branches it's out of date.
- Fix mobile layout issues in admin user overview page !7087
- Fix HipChat notifications rendering (airatshigapov, eisnerd)
- Remove 'Edit' button from wiki edit view !7143 (Hiroyuki Sato)
- Cleaned up global namespace JS !19661 (Jose Ivan Vargas)
- Refactor Jira service to use jira-ruby gem
- Improved todos empty state
- Add hover to trash icon in notes !7008 (blackst0ne)
......@@ -23,6 +28,7 @@ Please view this file on the master branch, on stable branches it's out of date.
- Fix sidekiq stats in admin area (blackst0ne)
- Added label description as tooltip to issue board list title
- Created cycle analytics bundle JavaScript file
- Hides container registry when repository is disabled
- API: Fix booleans not recognized as such when using the `to_boolean` helper
- Removed delete branch tooltip !6954
- Stop unauthorized users dragging on milestone page (blackst0ne)
......@@ -42,6 +48,8 @@ Please view this file on the master branch, on stable branches it's out of date.
- New issue board list dropdown stays open after adding a new list
- Fix: Backup restore doesn't clear cache
- Optimize Event queries by removing default order
- Add new icon for skipped builds
- Show created icon in pipeline mini-graph
- Remove duplicate links from sidebar
- API: Fix project deploy keys 400 and 500 errors when adding an existing key. !6784 (Joshua Welsh)
- Add Rake task to create/repair GitLab Shell hooks symlinks !5634
......@@ -54,16 +62,21 @@ Please view this file on the master branch, on stable branches it's out of date.
- Initialize Sidekiq with the list of queues used by GitLab
- Refactor email, use setter method instead AR callbacks for email attribute (Semyon Pupkov)
- Shortened merge request modal to let clipboard button not overlap
- Adds JavaScript validation for group path editing field
- In all filterable drop downs, put input field in focus only after load is complete (Ido @leibo)
- Improve search query parameter naming in /admin/users !7115 (YarNayar)
- Fix table pagination to be responsive
- Allow to search for user by secondary email address in the admin interface(/admin/users) !7115 (YarNayar)
- Updated commit SHA styling on the branches page.
## 8.13.3
## 8.13.3 (2016-11-02)
- Removes any symlinks before importing a project export file. CVE-2016-9086
- Fixed Import/Export foreign key issue to do with project members.
- Fix relative links in Markdown wiki when displayed in "Project" tab !7218
- Reduce the overhead to calculate number of open/closed issues and merge requests within the group or project
- Fix project features default values
- Changed build dropdown list length to be 6,5 builds long in the pipeline graph
## 8.13.2 (2016-10-31)
......@@ -253,6 +266,11 @@ Please view this file on the master branch, on stable branches it's out of date.
- Fix broken Project API docs (Takuya Noguchi)
- Migrate invalid project members (owner -> master)
## 8.12.8 (2016-11-02)
- Removes any symlinks before importing a project export file. CVE-2016-9086
- Fixed Import/Export foreign key issue to do with project members.
## 8.12.7
- Prevent running `GfmAutocomplete` setup for each diff note. !6569
......@@ -512,6 +530,10 @@ Please view this file on the master branch, on stable branches it's out of date.
- Fix non-master branch readme display in tree view
- Add UX improvements for merge request version diffs
## 8.11.10 (2016-11-02)
- Removes any symlinks before importing a project export file. CVE-2016-9086
## 8.11.9
- Don't send Private-Token (API authentication) headers to Sentry
......@@ -752,6 +774,10 @@ Please view this file on the master branch, on stable branches it's out of date.
- Update gitlab_git gem to 10.4.7
- Simplify SQL queries of marking a todo as done
## 8.10.13 (2016-11-02)
- Removes any symlinks before importing a project export file. CVE-2016-9086
## 8.10.12
- Don't send Private-Token (API authentication) headers to Sentry
......
......@@ -104,7 +104,7 @@ gem 'deckar01-task_list', '1.0.5', require: 'task_list/railtie'
gem 'gitlab-markup', '~> 1.5.0'
gem 'redcarpet', '~> 3.3.3'
gem 'RedCloth', '~> 4.3.2'
gem 'rdoc', '~>3.6'
gem 'rdoc', '~> 4.2'
gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1'
......@@ -260,9 +260,6 @@ group :development do
gem 'better_errors', '~> 1.0.1'
gem 'binding_of_caller', '~> 0.7.2'
# Docs generator
gem 'sdoc', '~> 0.3.20'
# thin instead webrick
gem 'thin', '~> 1.7.0'
end
......
......@@ -567,7 +567,7 @@ GEM
ffi (>= 0.5.0)
rblineprof (0.3.6)
debugger-ruby_core_source (~> 1.3)
rdoc (3.12.2)
rdoc (4.2.2)
json (~> 1.4)
recaptcha (3.0.0)
json
......@@ -663,9 +663,6 @@ GEM
scss_lint (0.47.1)
rake (>= 0.9, < 11)
sass (~> 3.4.15)
sdoc (0.3.20)
json (>= 1.1.3)
rdoc (~> 3.10)
seed-fu (2.3.6)
activerecord (>= 3.1)
activesupport (>= 3.1)
......@@ -936,7 +933,7 @@ DEPENDENCIES
rails-deprecated_sanitizer (~> 1.0.3)
rainbow (~> 2.1.0)
rblineprof (~> 0.3.6)
rdoc (~> 3.6)
rdoc (~> 4.2)
recaptcha (~> 3.0)
redcarpet (~> 3.3.3)
redis (~> 3.2)
......@@ -956,7 +953,6 @@ DEPENDENCIES
sanitize (~> 2.0)
sass-rails (~> 5.0.6)
scss_lint (~> 0.47.0)
sdoc (~> 0.3.20)
seed-fu (~> 2.3.5)
select2-rails (~> 3.5.9)
sentry-raven (~> 2.0.0)
......
......@@ -80,7 +80,7 @@ GitLab is a Ruby on Rails application that runs on the following software:
- Redis 2.8+
- MySQL or PostgreSQL
For more information please see the [architecture documentation](http://doc.gitlab.com/ce/development/architecture.html).
For more information please see the [architecture documentation](https://docs.gitlab.com/ce/development/architecture.html).
## Third-party applications
......@@ -96,7 +96,7 @@ For upgrading information please see our [update page](https://about.gitlab.com/
## Documentation
All documentation can be found on [doc.gitlab.com/ce/](http://doc.gitlab.com/ce/).
All documentation can be found on [docs.gitlab.com/ce/](https://docs.gitlab.com/ce/).
## Getting help
......
......@@ -22,16 +22,14 @@
});
},
// Return groups list. Filtered by query
// Only active groups retrieved
groups: function(query, skip_ldap, skip_groups, callback) {
groups: function(query, options, callback) {
var url = Api.buildUrl(Api.groupsPath);
return $.ajax({
url: url,
data: {
search: query,
skip_groups: skip_groups,
per_page: 20
},
data: $.extend({
search: query,
per_page: 20
}, options),
dataType: "json"
}).done(function(groups) {
return callback(groups);
......
This diff is collapsed.
/* eslint-disable */
(function() {
this.AwardsHandler = (function() {
const FROM_SENTENCE_REGEX = /(?:, and | and |, )/; //For separating lists produced by ruby's Array#toSentence
var FROM_SENTENCE_REGEX = /(?:, and | and |, )/; //For separating lists produced by ruby's Array#toSentence
function AwardsHandler() {
this.aliases = gl.emojiAliases();
$(document).off('click', '.js-add-award').on('click', '.js-add-award', (function(_this) {
......
......@@ -12,7 +12,7 @@
submit.disable();
$('.js-confirm-danger-input').off('input');
$('.js-confirm-danger-input').on('input', function() {
if (rstrip($(this).val()) === project_path) {
if (gl.utils.rstrip($(this).val()) === project_path) {
return submit.enable();
} else {
return submit.disable();
......
......@@ -299,7 +299,7 @@
};
Dispatcher.prototype.initFieldErrors = function() {
$('.show-gl-field-errors').each((i, form) => {
$('.gl-show-field-errors').each((i, form) => {
new gl.GlFieldErrors(form);
});
};
......
......@@ -126,8 +126,8 @@
}
return {
username: m.username,
title: sanitize(title),
search: sanitize(m.username + " " + m.name)
title: gl.utils.sanitize(title),
search: gl.utils.sanitize(m.username + " " + m.name)
};
});
}
......@@ -159,7 +159,7 @@
}
return {
id: i.iid,
title: sanitize(i.title),
title: gl.utils.sanitize(i.title),
search: i.iid + " " + i.title
};
});
......@@ -189,7 +189,7 @@
}
return {
id: m.iid,
title: sanitize(m.title),
title: gl.utils.sanitize(m.title),
search: "" + m.title
};
});
......@@ -222,7 +222,7 @@
}
return {
id: m.iid,
title: sanitize(m.title),
title: gl.utils.sanitize(m.title),
search: m.iid + " " + m.title
};
});
......@@ -240,9 +240,9 @@
var sanitizeLabelTitle;
sanitizeLabelTitle = function(title) {
if (/[\w\?&]+\s+[\w\?&]+/g.test(title)) {
return "\"" + (sanitize(title)) + "\"";
return "\"" + (gl.utils.sanitize(title)) + "\"";
} else {
return sanitize(title);
return gl.utils.sanitize(title);
}
};
return $.map(merges, function(m) {
......
/* eslint-disable no-param-reassign */
((global) => {
/*
* This class overrides the browser's validation error bubbles, displaying custom
* error messages for invalid fields instead. To begin validating any form, add the
* class `gl-show-field-errors` to the form element, and ensure error messages are
* declared in each inputs' `title` attribute. If no title is declared for an invalid
* field the user attempts to submit, "This field is required." will be shown by default.
*
* Opt not to validate certain fields by adding the class `gl-field-error-ignore` to the input.
*
* Set a custom error anchor for error message to be injected after with the
* class `gl-field-error-anchor`
*
* Examples:
*
* Basic:
*
* <form class='gl-show-field-errors'>
* <input type='text' name='username' title='Username is required.'/>
* </form>
*
* Ignore specific inputs (e.g. UsernameValidator):
*
* <form class='gl-show-field-errors'>
* <div class="form-group>
* <input type='text' class='gl-field-errors-ignore' pattern='[a-zA-Z0-9-_]+'/>
* </div>
* <div class="form-group">
* <input type='text' name='username' title='Username is required.'/>
* </div>
* </form>
*
* Custom Error Anchor (allows error message to be injected after specified element):
*
* <form class='gl-show-field-errors'>
* <div class="form-group gl-field-error-anchor">
* <input type='text' name='username' title='Username is required.'/>
* // Error message typically injected here
* </div>
* // Error message now injected here
* </form>
*
* */
/*
* Regex Patterns in use:
*
* Only alphanumeric: : "[a-zA-Z0-9]+"
* No special characters : "[a-zA-Z0-9-_]+",
*
* */
const errorMessageClass = 'gl-field-error';
const inputErrorClass = 'gl-field-error-outline';
const errorAnchorSelector = '.gl-field-error-anchor';
const ignoreInputSelector = '.gl-field-error-ignore';
class GlFieldError {
constructor({ input, formErrors }) {
this.inputElement = $(input);
this.inputDomElement = this.inputElement.get(0);
this.form = formErrors;
this.errorMessage = this.inputElement.attr('title') || 'This field is required.';
this.fieldErrorElement = $(`<p class='${errorMessageClass} hide'>${this.errorMessage}</p>`);
this.state = {
valid: false,
empty: true,
};
this.initFieldValidation();
}
initFieldValidation() {
const customErrorAnchor = this.inputElement.parents(errorAnchorSelector);
const errorAnchor = customErrorAnchor.length ? customErrorAnchor : this.inputElement;
// hidden when injected into DOM
errorAnchor.after(this.fieldErrorElement);
this.inputElement.off('invalid').on('invalid', this.handleInvalidSubmit.bind(this));
this.scopedSiblings = this.safelySelectSiblings();
}
safelySelectSiblings() {
// Apply `ignoreSelector` in markup to siblings whose visibility should not be toggled
const unignoredSiblings = this.inputElement.siblings(`p:not(${ignoreInputSelector})`);
const parentContainer = this.inputElement.parent('.form-group');
// Only select siblings when they're scoped within a form-group with one input
const safelyScoped = parentContainer.length && parentContainer.find('input').length === 1;
return safelyScoped ? unignoredSiblings : this.fieldErrorElement;
}
renderValidity() {
this.renderClear();
if (this.state.valid) {
this.renderValid();
} else if (this.state.empty) {
this.renderEmpty();
} else if (!this.state.valid) {
this.renderInvalid();
}
}
handleInvalidSubmit(event) {
event.preventDefault();
const currentValue = this.accessCurrentValue();
this.state.valid = false;
this.state.empty = currentValue === '';
this.renderValidity();
this.form.focusOnFirstInvalid.apply(this.form);
// For UX, wait til after first invalid submission to check each keyup
this.inputElement.off('keyup.fieldValidator')
.on('keyup.fieldValidator', this.updateValidity.bind(this));
}
/* Get or set current input value */
accessCurrentValue(newVal) {
return newVal ? this.inputElement.val(newVal) : this.inputElement.val();
}
getInputValidity() {
return this.inputDomElement.validity.valid;
}
updateValidity() {
const inputVal = this.accessCurrentValue();
this.state.empty = !inputVal.length;
this.state.valid = this.getInputValidity();
this.renderValidity();
}
renderValid() {
return this.renderClear();
}
renderEmpty() {
return this.renderInvalid();
}
renderInvalid() {
this.inputElement.addClass(inputErrorClass);
this.scopedSiblings.hide();
return this.fieldErrorElement.show();
}
renderClear() {
const inputVal = this.accessCurrentValue();
if (!inputVal.split(' ').length) {
const trimmedInput = inputVal.trim();
this.accessCurrentValue(trimmedInput);
}
this.inputElement.removeClass(inputErrorClass);
this.scopedSiblings.hide();
this.fieldErrorElement.hide();
}
}
global.GlFieldError = GlFieldError;
})(window.gl || (window.gl = {}));
/* eslint-disable */
((global) => {
/*
* This class overrides the browser's validation error bubbles, displaying custom
* error messages for invalid fields instead. To begin validating any form, add the
* class `show-gl-field-errors` to the form element, and ensure error messages are
* declared in each inputs' title attribute.
*
* Example:
*
* <form class='show-gl-field-errors'>
* <input type='text' name='username' title='Username is required.'/>
*</form>
*
* */
const errorMessageClass = 'gl-field-error';
const inputErrorClass = 'gl-field-error-outline';
class GlFieldError {
constructor({ input, formErrors }) {
this.inputElement = $(input);
this.inputDomElement = this.inputElement.get(0);
this.form = formErrors;
this.errorMessage = this.inputElement.attr('title') || 'This field is required.';
this.fieldErrorElement = $(`<p class='${errorMessageClass} hide'>${ this.errorMessage }</p>`);
this.state = {
valid: false,
empty: true
};
this.initFieldValidation();
}
initFieldValidation() {
// hidden when injected into DOM
this.inputElement.after(this.fieldErrorElement);
this.inputElement.off('invalid').on('invalid', this.handleInvalidSubmit.bind(this));
this.scopedSiblings = this.safelySelectSiblings();
}
safelySelectSiblings() {
// Apply `ignoreSelector` in markup to siblings whose visibility should not be toggled with input validity
const ignoreSelector = '.validation-ignore';
const unignoredSiblings = this.inputElement.siblings(`p:not(${ignoreSelector})`);
const parentContainer = this.inputElement.parent('.form-group');
// Only select siblings when they're scoped within a form-group with one input
const safelyScoped = parentContainer.length && parentContainer.find('input').length === 1;
return safelyScoped ? unignoredSiblings : this.fieldErrorElement;
}
renderValidity() {
this.renderClear();
if (this.state.valid) {
return this.renderValid();
}
if (this.state.empty) {
return this.renderEmpty();
}
if (!this.state.valid) {
return this.renderInvalid();
}
}
//= require gl_field_error
handleInvalidSubmit(event) {
event.preventDefault();
const currentValue = this.accessCurrentValue();
this.state.valid = false;
this.state.empty = currentValue === '';
this.renderValidity();
this.form.focusOnFirstInvalid.apply(this.form);
// For UX, wait til after first invalid submission to check each keyup
this.inputElement.off('keyup.field_validator')
.on('keyup.field_validator', this.updateValidity.bind(this));
}
/* Get or set current input value */
accessCurrentValue(newVal) {
return newVal ? this.inputElement.val(newVal) : this.inputElement.val();
}
getInputValidity() {
return this.inputDomElement.validity.valid;
}
updateValidity() {
const inputVal = this.accessCurrentValue();
this.state.empty = !inputVal.length;
this.state.valid = this.getInputValidity();
this.renderValidity();
}
renderValid() {
return this.renderClear();
}
renderEmpty() {
return this.renderInvalid();
}
renderInvalid() {
this.inputElement.addClass(inputErrorClass);
this.scopedSiblings.hide();
return this.fieldErrorElement.show();
}
renderClear() {
const inputVal = this.accessCurrentValue();
if (!inputVal.split(' ').length) {
const trimmedInput = inputVal.trim();
this.accessCurrentValue(trimmedInput);
}
this.inputElement.removeClass(inputErrorClass);
this.scopedSiblings.hide();
this.fieldErrorElement.hide();
}
}
const customValidationFlag = 'no-gl-field-errors';
((global) => {
const customValidationFlag = 'gl-field-error-ignore';
class GlFieldErrors {
constructor(form) {
......@@ -144,7 +22,7 @@
this.state.inputs = this.form.find(validateSelectors).toArray()
.filter((input) => !input.classList.contains(customValidationFlag))
.map((input) => new GlFieldError({ input, formErrors: this }));
.map((input) => new global.GlFieldError({ input, formErrors: this }));
this.form.on('submit', this.catchInvalidFormSubmit);
}
......
......@@ -24,8 +24,8 @@
if (isNewForm) {
this.form.find('.div-dropzone').remove();
this.form.addClass('gfm-form');
disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
// remove notify commit author checkbox for non-commit notes
gl.utils.disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
GitLab.GfmAutoComplete.setup(this.form.find('.js-gfm-input'));
new DropzoneInput(this.form);
autosize(this.textarea);
......
......@@ -6,15 +6,16 @@
function GroupsSelect() {
$('.ajax-groups-select').each((function(_this) {
return function(i, select) {
var skip_ldap, skip_groups;
skip_ldap = $(select).hasClass('skip_ldap');
var all_available, skip_groups;
all_available = $(select).data('all-available');
skip_groups = $(select).data('skip-groups') || [];
return $(select).select2({
placeholder: "Search for a group",
multiple: $(select).hasClass('multiselect'),
minimumInputLength: 0,
query: function(query) {
return Api.groups(query.term, skip_ldap, skip_groups, function(groups) {
options = { all_available: all_available, skip_groups: skip_groups };
return Api.groups(query.term, options, function(groups) {
var data;
data = {
results: groups
......
......@@ -24,6 +24,81 @@
return null;
}
};
w.gl.utils.ajaxGet = function(url) {
return $.ajax({
type: "GET",
url: url,
dataType: "script"
});
};
w.gl.utils.split = function(val) {
return val.split(/,\s*/);
};
w.gl.utils.extractLast = function(term) {
return this.split(term).pop();
};
w.gl.utils.rstrip = function rstrip(val) {
if (val) {
return val.replace(/\s+$/, '');
} else {
return val;
}
};
w.gl.utils.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
event_name = event_name || 'input';
var closest_submit, field, that;
that = this;
field = $(field_selector);
closest_submit = field.closest('form').find(button_selector);
if (this.rstrip(field.val()) === "") {
closest_submit.disable();
}
return field.on(event_name, function() {
if (that.rstrip($(this).val()) === "") {
return closest_submit.disable();
} else {
return closest_submit.enable();
}
});
};
w.gl.utils.disableButtonIfAnyEmptyField = function(form, form_selector, button_selector) {
var closest_submit, updateButtons;
closest_submit = form.find(button_selector);
updateButtons = function() {
var filled;
filled = true;
form.find('input').filter(form_selector).each(function() {
return filled = this.rstrip($(this).val()) !== "" || !$(this).attr('required');
});
if (filled) {
return closest_submit.enable();
} else {
return closest_submit.disable();
}
};
updateButtons();
return form.keyup(updateButtons);
};
w.gl.utils.sanitize = function(str) {
return str.replace(/<(?:.|\n)*?>/gm, '');
};
w.gl.utils.unbindEvents = function() {
return $(document).off('scroll');
};
w.gl.utils.shiftWindow = function() {
return w.scrollBy(0, -100);
};
gl.utils.updateTooltipTitle = function($tooltipEl, newTitle) {
return $tooltipEl.tooltip('destroy').attr('title', newTitle).tooltip('fixTitle');
};
......
......@@ -11,7 +11,7 @@
$('.project_member, .group_member').off('ajax:success').on('ajax:success', this.removeRow);
$('.js-member-update-control').off('change').on('change', this.formSubmit);
$('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess);
disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
gl.utils.disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
}
removeRow(e) {
......
......@@ -45,7 +45,9 @@
};
ProjectNew.prototype.toggleRepoVisibility = function () {
var $repoAccessLevel = $('.js-repo-access-level select');
var $repoAccessLevel = $('.js-repo-access-level select'),
containerRegistry = document.querySelectorAll('.js-container-registry')[0],
containerRegistryCheckbox = document.getElementById('project_container_registry_enabled');
this.$repoSelects.find("option[value='" + $repoAccessLevel.val() + "']")
.nextAll()
......@@ -70,8 +72,17 @@
if (selectedVal) {
this.$repoSelects.removeClass('disabled');
if (containerRegistry) {
containerRegistry.style.display = '';
}
} else {
this.$repoSelects.addClass('disabled');
if (containerRegistry) {
containerRegistry.style.display = 'none';
containerRegistryCheckbox.checked = false;
}
}
}.bind(this));
};
......
......@@ -24,7 +24,7 @@
data = groups.concat(projects);
return finalCallback(data);
};
return Api.groups(term, false, false, groupsCallback);
return Api.groups(term, {}, groupsCallback);
};
} else {
projectsCallback = finalCallback;
......@@ -73,7 +73,7 @@
data = groups.concat(projects);
return finalCallback(data);
};
return Api.groups(query.term, false, false, groupsCallback);
return Api.groups(query.term, {}, groupsCallback);
};
} else {
projectsCallback = finalCallback;
......
......@@ -11,7 +11,7 @@
filterable: true,
fieldName: 'group_id',
data: function(term, callback) {
return Api.groups(term, false, false, function(data) {
return Api.groups(term, {}, function(data) {
data.unshift({
name: 'Any'
});
......
......@@ -36,7 +36,7 @@
color: $dropdown-toggle-color;
font-size: 15px;
text-align: left;
border: 1px solid $dropdown-toggle-border-color;
border: 1px solid $border-color;
border-radius: $border-radius-base;
outline: 0;
text-overflow: ellipsis;
......@@ -45,11 +45,9 @@
.fa {
position: absolute;
top: 50%;
right: 6px;
margin-top: -6px;
top: 10px;
right: 8px;
color: $dropdown-toggle-icon-color;
font-size: 10px;
&.fa-spinner {
font-size: 16px;
......
......@@ -136,3 +136,35 @@ label {
color: $red-normal;
}
.gl-show-field-errors {
.gl-field-success-outline {
border: 1px solid $green-normal;
&:focus {
box-shadow: 0 0 0 1px $green-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 $green-normal;
border: 0 none;
}
}
.gl-field-error-outline {
border: 1px solid $red-normal;
&:focus {
box-shadow: 0 0 0 1px $red-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 rgba(210, 40, 82, 0.6);
border: 0 none;
}
}
.gl-field-success-message {
color: $green-normal;
}
.gl-field-error-message {
color: $red-normal;
}
.gl-field-hint {
color: $gl-text-color;
}
}
......@@ -27,9 +27,9 @@
height: 0;
margin-left: 2px;
vertical-align: middle;
border-top: $caret-width-base dashed;
border-right: $caret-width-base solid transparent;
border-left: $caret-width-base solid transparent;
border-top: 5px dashed;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
color: $gray-darkest;
}
}
......
......@@ -164,7 +164,22 @@
.branch-commit {
color: $gl-gray;
.commit-id,
.commit-icon {
text-align: center;
display: inline-block;
svg {
height: 14px;
width: 14px;
vertical-align: middle;
fill: $table-text-gray;
}
}
.commit-id {
color: $gl-link-color;
}
.commit-row-message {
color: $gl-gray;
}
......
......@@ -55,6 +55,10 @@
float: left;
}
.file-buttons {
font-size: 0;
}
.select2 {
float: right;
}
......
// CI icon colors
.ci-status-icon {
&-created {
fill: $gray-darkest;
}
&-skipped,
&-canceled {
fill: $gl-text-color;
}
}
......@@ -75,43 +75,17 @@
.login-body {
font-size: 13px;
input + p {
margin-top: 5px;
}
.gl-field-success-outline {
border: 1px solid $green-normal;
&:focus {
box-shadow: 0 0 0 1px $green-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 $green-normal;
border: 0 none;
}
}
.gl-field-error-outline {
border: 1px solid $red-normal;
&:focus {
box-shadow: 0 0 0 1px $red-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 rgba(210, 40, 82, 0.6);
border: 0 none;
}
}
.username .validation-success,
.gl-field-success-message {
.username .validation-success {
color: $green-normal;
}
.username .validation-error,
.gl-field-error-message {
.username .validation-error {
color: $red-normal;
}
.gl-field-hint {
color: $gl-text-color;
}
}
}
......
......@@ -85,6 +85,11 @@
}
.commit-link {
a {
&:focus {
text-decoration: none;
}
}
.ci-status {
......@@ -439,7 +444,7 @@
}
.grouped-pipeline-dropdown {
padding: 8px 0;
padding: 0;
width: 186px;
left: auto;
right: -197px;
......@@ -448,6 +453,14 @@
ul {
max-height: 245px;
overflow: auto;
li:first-child {
padding-top: 8px;
}
li:last-child {
padding-bottom: 8px;
}
}
a {
......
......@@ -6,7 +6,8 @@
white-space: nowrap;
border-radius: 4px;
&:hover {
&:hover,
&:focus {
text-decoration: none;
}
......
......@@ -116,8 +116,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_packet_size,
:send_user_confirmation_email,
:container_registry_token_expire_delay,
:repository_storage,
:enabled_git_access_protocol,
repository_storages: [],
restricted_visibility_levels: [],
import_sources: [],
disabled_oauth_sign_in_sources: []
......
......@@ -7,7 +7,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
@group_links = project.project_group_links.all
@skip_groups = @group_links.pluck(:group_id)
@skip_groups << project.group.try(:id)
@skip_groups << project.namespace_id unless project.personal?
end
def create
......
......@@ -93,11 +93,11 @@ module ApplicationSettingsHelper
end
end
def repository_storage_options_for_select
def repository_storages_options_for_select
options = Gitlab.config.repositories.storages.map do |name, path|
["#{name} - #{path}", name]
end
options_for_select(options, @application_setting.repository_storage)
options_for_select(options, @application_setting.repository_storages)
end
end
......@@ -47,8 +47,10 @@ module CiStatusHelper
'icon_play'
when 'created'
'icon_status_created'
when 'skipped'
'icon_status_skipped'
else
'icon_status_cancel'
'icon_status_canceled'
end
custom_icon(icon_name)
......
......@@ -43,7 +43,7 @@ module DropdownsHelper
default_label = data_attr[:default_label]
content_tag(:button, class: "dropdown-menu-toggle #{options[:toggle_class] if options.has_key?(:toggle_class)}", id: (options[:id] if options.has_key?(:id)), type: "button", data: data_attr) do
output = content_tag(:span, toggle_text, class: "dropdown-toggle-text #{'is-default' if toggle_text == default_label}")
output << icon('chevron-down')
output << icon('caret-down')
output.html_safe
end
end
......
......@@ -18,6 +18,7 @@ class ApplicationSetting < ActiveRecord::Base
serialize :disabled_oauth_sign_in_sources, Array
serialize :domain_whitelist, Array
serialize :domain_blacklist, Array
serialize :repository_storages
cache_markdown_field :sign_in_text
cache_markdown_field :help_page_text
......@@ -74,9 +75,8 @@ class ApplicationSetting < ActiveRecord::Base
presence: true,
numericality: { only_integer: true, greater_than: 0 }
validates :repository_storage,
presence: true,
inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } }
validates :repository_storages, presence: true
validate :check_repository_storages
validates :enabled_git_access_protocol,
inclusion: { in: %w(ssh http), allow_blank: true, allow_nil: true }
......@@ -166,7 +166,7 @@ class ApplicationSetting < ActiveRecord::Base
disabled_oauth_sign_in_sources: [],
send_user_confirmation_email: false,
container_registry_token_expire_delay: 5,
repository_storage: 'default',
repository_storages: ['default'],
user_default_external: false,
)
end
......@@ -201,6 +201,29 @@ class ApplicationSetting < ActiveRecord::Base
self.domain_blacklist_raw = file.read
end
def repository_storages
value = read_attribute(:repository_storages)
value = [value] if value.is_a?(String)
value = [] if value.nil?
value
end
# repository_storage is still required in the API. Remove in 9.0
def repository_storage
repository_storages.first
end
def repository_storage=(value)
self.repository_storages = [value]
end
# Choose one of the available repository storage options. Currently all have
# equal weighting.
def pick_repository_storage
repository_storages.sample
end
def runners_registration_token
ensure_runners_registration_token!
end
......@@ -208,4 +231,12 @@ class ApplicationSetting < ActiveRecord::Base
def health_check_access_token
ensure_health_check_access_token!
end
private
def check_repository_storages
invalid = repository_storages - Gitlab.config.repositories.storages.keys
errors.add(:repository_storages, "can't include: #{invalid.join(", ")}") unless
invalid.empty?
end
end
......@@ -441,11 +441,11 @@ class MergeRequest < ActiveRecord::Base
end
def should_remove_source_branch?
merge_params['should_remove_source_branch'].present?
Gitlab::Utils.to_boolean(merge_params['should_remove_source_branch'])
end
def force_remove_source_branch?
merge_params['force_remove_source_branch'].present?
Gitlab::Utils.to_boolean(merge_params['force_remove_source_branch'])
end
def remove_source_branch?
......
......@@ -28,7 +28,7 @@ class Project < ActiveRecord::Base
default_value_for :archived, false
default_value_for :visibility_level, gitlab_config_features.visibility_level
default_value_for :container_registry_enabled, gitlab_config_features.container_registry
default_value_for(:repository_storage) { current_application_settings.repository_storage }
default_value_for(:repository_storage) { current_application_settings.pick_repository_storage }
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
default_value_for :issues_enabled, gitlab_config_features.issues
default_value_for :merge_requests_enabled, gitlab_config_features.merge_requests
......
= render 'devise/shared/tab_single', tab_title: 'Sign in preview'
.login-box
%form.show-gl-field-errors
%form.gl-show-field-errors
.form-group
= label_tag :login
= text_field_tag :login, nil, class: "form-control top", title: 'Please provide your username or email address.'
......
......@@ -353,9 +353,9 @@
%fieldset
%legend Repository Storage
.form-group
= f.label :repository_storage, 'Storage path for new projects', class: 'control-label col-sm-2'
= f.label :repository_storages, 'Storage paths for new projects', class: 'control-label col-sm-2'
.col-sm-10
= f.select :repository_storage, repository_storage_options_for_select, {}, class: 'form-control'
= f.select :repository_storages, repository_storages_options_for_select, {include_hidden: false}, multiple: true, class: 'form-control'
.help-block
Manage repository storage paths. Learn more in the
= succeed "." do
......
- @no_container = true
- page_title "Logs"
- loggers = [Gitlab::GitLogger, Gitlab::AppLogger,
Gitlab::ProductionLogger, Gitlab::SidekiqLogger,
Gitlab::EnvironmentLogger, Gitlab::SidekiqLogger,
Gitlab::RepositoryCheckLogger]
= render 'admin/background_jobs/head'
......
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{current_user.name} issues"
xml.link href: issues_dashboard_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html"
xml.id issues_dashboard_url
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
......
......@@ -2,13 +2,13 @@
- header_title "Issues", issues_dashboard_path(assignee_id: current_user.id)
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, issues_dashboard_url(format: :atom, private_token: current_user.private_token), title: "#{current_user.name} issues")
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{current_user.name} issues")
.top-area
= render 'shared/issuable/nav', type: :issues
.nav-controls
- if current_user
= link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do
= link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do
= icon('rss')
%span.icon-label
Subscribe
......
= render 'devise/shared/tab_single', tab_title: 'Resend confirmation instructions'
.login-box
.login-body
= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post, class: 'show-gl-field-errors' }) do |f|
= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post, class: 'gl-show-field-errors' }) do |f|
.devise-errors
= devise_error_messages!
.form-group
......
= render 'devise/shared/tab_single', tab_title:'Change your password'
.login-box
.login-body
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put, class: 'show-gl-field-errors' }) do |f|
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put, class: 'gl-show-field-errors' }) do |f|
.devise-errors
= devise_error_messages!
= f.hidden_field :reset_password_token
......
= render 'devise/shared/tab_single', tab_title: 'Reset Password'
.login-box
.login-body
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post, class: 'show-gl-field-errors' }) do |f|
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post, class: 'gl-show-field-errors' }) do |f|
.devise-errors
= devise_error_messages!
.form-group
......
= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'new_user show-gl-field-errors', 'aria-live' => 'assertive'}) do |f|
= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'new_user gl-show-field-errors', 'aria-live' => 'assertive'}) do |f|
%div.form-group
= f.label "Username or email", for: :login
= f.text_field :login, class: "form-control top", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off", required: true, title: "This field is required."
......
= form_tag(omniauth_authorize_path(:user, :crowd), id: 'new_crowd_user', class: 'show-gl-field-errors') do
= form_tag(omniauth_authorize_path(:user, :crowd), id: 'new_crowd_user', class: 'gl-show-field-errors') do
.form-group
= label_tag :username, 'Username or email'
= text_field_tag :username, nil, {class: "form-control top", title: "This field is required", autofocus: "autofocus", required: true }
......
= form_tag(omniauth_callback_path(:user, server['provider_name']), id: 'new_ldap_user', class: "show-gl-field-errors") do
= form_tag(omniauth_callback_path(:user, server['provider_name']), id: 'new_ldap_user', class: "gl-show-field-errors") do
.form-group
= label_tag :username, "#{server['label']} Username"
= text_field_tag :username, nil, {class: "form-control top", title: "This field is required.", autofocus: "autofocus", required: true }
......
......@@ -7,7 +7,7 @@
.login-box
.login-body
- if @user.two_factor_otp_enabled?
= form_for(resource, as: resource_name, url: session_path(resource_name), method: :post, html: { class: 'edit_user show-gl-field-errors' }) do |f|
= form_for(resource, as: resource_name, url: session_path(resource_name), method: :post, html: { class: 'edit_user gl-show-field-errors' }) do |f|
- resource_params = params[resource_name].presence || params
= f.hidden_field :remember_me, value: resource_params.fetch(:remember_me, 0)
%div
......
#register-pane.login-box{ role: 'tabpanel', class: 'tab-pane' }
.login-body
= form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user show-gl-field-errors", "aria-live" => "assertive" }) do |f|
= form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
.devise-errors
= devise_error_messages!
%div.form-group
......@@ -8,7 +8,7 @@
= f.text_field :name, class: "form-control top", required: true, title: "This field is required."
%div.username.form-group
= f.label :username
= f.text_field :username, class: "form-control middle no-gl-field-error", pattern: "[a-zA-Z0-9]+", required: true, title: 'Please create a username with only alphanumeric characters.'
= f.text_field :username, class: "form-control middle", pattern: "[a-zA-Z0-9]+", required: true, title: 'Please create a username with only alphanumeric characters.'
%p.validation-error.hide Username is already taken.
%p.validation-success.hide Username is available.
%p.validation-pending.hide Checking username availability...
......
= render 'devise/shared/tab_single', tab_title: 'Resend unlock instructions'
.login-box
.login-body
= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post, class: 'show-gl-field-errors' }) do |f|
= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post, class: 'gl-show-field-errors' }) do |f|
.devise-errors
= devise_error_messages!
.form-group.append-bottom-20
......
......@@ -2,7 +2,7 @@
.panel-heading
Group settings
.panel-body
= form_for @group, html: { multipart: true, class: "form-horizontal" }, authenticity_token: true do |f|
= form_for @group, html: { multipart: true, class: "form-horizontal gl-show-field-errors" }, authenticity_token: true do |f|
= form_errors(@group)
= render 'shared/group_form', f: f
......
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@group.name} issues"
xml.link href: issues_group_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
xml.link href: issues_group_url, rel: "alternate", type: "text/html"
xml.id issues_group_url
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
......
- page_title "Issues"
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, issues_group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} issues")
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues")
.top-area
= render 'shared/issuable/nav', type: :issues
.nav-controls
- if current_user
= link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do
= link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do
= icon('rss')
%span.icon-label
Subscribe
......
......@@ -5,7 +5,7 @@
New Group
%hr
= form_for @group, html: { class: 'group-form form-horizontal' } do |f|
= form_for @group, html: { class: 'group-form form-horizontal gl-show-field-errors' } do |f|
= form_errors(@group)
= render 'shared/group_form', f: f, autofocus: true
......
......@@ -26,8 +26,8 @@
Perform code reviews and enhance collaboration with merge requests.
Each project can also have an issue tracker and a wiki.
- if current_application_settings.sign_in_text.present?
= markdown_field(current_application_settings, :sign_in_text)
- if current_application_settings.sign_in_text.present?
= markdown_field(current_application_settings, :sign_in_text)
%hr.footer-fixed
.container.footer-container
......
......@@ -14,13 +14,13 @@
= text_field_tag 'file_name', params[:file_name], placeholder: "File name",
required: true, class: 'form-control new-file-name'
.pull-right
.pull-right.file-buttons
.license-selector.js-license-selector-wrap.hidden
= dropdown_tag("Choose a License template", options: { toggle_class: 'js-license-selector', title: "Choose a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } )
= dropdown_tag("Choose a License template", options: { toggle_class: 'btn js-license-selector', title: "Choose a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } )
.gitignore-selector.js-gitignore-selector-wrap.hidden
= dropdown_tag("Choose a .gitignore template", options: { toggle_class: 'js-gitignore-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitignore_names } } )
= dropdown_tag("Choose a .gitignore template", options: { toggle_class: 'btn js-gitignore-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitignore_names } } )
.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.hidden
= dropdown_tag("Choose a GitLab CI Yaml template", options: { toggle_class: 'js-gitlab-ci-yml-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls } } )
= dropdown_tag("Choose a GitLab CI Yaml template", options: { toggle_class: 'btn js-gitlab-ci-yml-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls } } )
= button_tag class: 'soft-wrap-toggle btn', type: 'button' do
%span.no-wrap
= custom_icon('icon_no_wrap')
......
......@@ -26,6 +26,6 @@
:javascript
disableButtonIfEmptyField($('.js-upload-blob-form').find('.js-commit-message'), '.btn-upload-file');
gl.utils.disableButtonIfEmptyField($('.js-upload-blob-form').find('.js-commit-message'), '.btn-upload-file');
new BlobFileDropzone($('.js-upload-blob-form'), '#{method}');
new NewCommitForm($('.js-upload-blob-form'))
.branch-commit
.icon-container.commit-icon
= custom_icon("icon_commit")
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-id monospace"
&middot;
%span.str-truncated
......
......@@ -41,7 +41,7 @@
- else
Cant find HEAD commit for this branch
- stages_status = pipeline.statuses.relevant.latest.stages_status
- stages_status = pipeline.statuses.latest.stages_status
%td.stage-cell
- stages.each do |stage|
- status = stages_status[stage]
......
......@@ -102,7 +102,7 @@
= link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
- if Gitlab.config.registry.enabled
.form-group
.form-group.js-container-registry{ style: ("display: none;" if @project.project_feature.send(:repository_access_level) == 0) }
.checkbox
= f.label :container_registry_enabled do
= f.check_box :container_registry_enabled
......@@ -290,4 +290,4 @@
Saving project.
%p Please wait a moment, this page will automatically refresh when ready.
= render 'shared/confirm_modal', phrase: @project.path
\ No newline at end of file
= render 'shared/confirm_modal', phrase: @project.path
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@project.name} issues"
xml.link href: namespace_project_issues_url(@project.namespace, @project, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
xml.link href: namespace_project_issues_url(@project.namespace, @project), rel: "alternate", type: "text/html"
xml.id namespace_project_issues_url(@project.namespace, @project)
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
......
......@@ -8,7 +8,7 @@
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@project.name} issues")
%div{ class: (container_class) }
- if @project.issues.any?
......@@ -16,7 +16,7 @@
= render 'shared/issuable/nav', type: :issues
.nav-controls
- if current_user
= link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do
= link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn append-right-10' do
= icon('rss')
%span.icon-label
Subscribe
......
......@@ -12,7 +12,7 @@
= render 'projects/last_push'
= render "home_panel"
- if @project.feature_available?(:repository, current_user)
- if current_user && can?(current_user, :download_code, @project)
%nav.project-stats{ class: container_class }
%ul.nav
%li
......
......@@ -37,5 +37,5 @@
:javascript
// Load last commit log for each file in tree
$('#tree-slider').waitForImages(function() {
ajaxGet("#{escape_javascript(@logs_path)}");
gl.utils.ajaxGet("#{escape_javascript(@logs_path)}");
});
......@@ -9,11 +9,13 @@
= f.label :path, class: 'control-label' do
Group path
.col-sm-10
.input-group
.input-group.gl-field-error-anchor
.input-group-addon
= root_url
= f.text_field :path, placeholder: 'open-source', class: 'form-control',
autofocus: local_assigns[:autofocus] || false
autofocus: local_assigns[:autofocus] || false, pattern: "[a-zA-Z0-9-_]+",
required: true, title: 'Please choose a group name with no special characters.'
- if @group.persisted?
.alert.alert-warning.prepend-top-10
%ul
......
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" class="ci-status-icon-canceled" viewBox="0 0 14 14">
<g fill="#5C5C5C" fill-rule="evenodd">
<path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/>
<rect width="8" height="2" x="3" y="6" transform="rotate(45 7 7)" rx=".5"/>
......
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" enable-background="new 0 0 14 14"><path d="M12.5,7 C12.5,4 10,1.5 7,1.5 C4,1.5 1.5,4 1.5,7 C1.5,10 4,12.5 7,12.5 C10,12.5 12.5,10 12.5,7 L12.5,7 Z M0,7 C0,3.1 3.1,0 7,0 C10.9,0 14,3.1 14,7 C14,10.9 10.9,14 7,14 C3.1,14 0,10.9 0,7 L0,7 Z" /><circle cx="7" cy="7" r="3.25"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" class="ci-status-icon-created" viewBox="0 0 14 14" enable-background="new 0 0 14 14"><path d="M12.5,7 C12.5,4 10,1.5 7,1.5 C4,1.5 1.5,4 1.5,7 C1.5,10 4,12.5 7,12.5 C10,12.5 12.5,10 12.5,7 L12.5,7 Z M0,7 C0,3.1 3.1,0 7,0 C10.9,0 14,3.1 14,7 C14,10.9 10.9,14 7,14 C3.1,14 0,10.9 0,7 L0,7 Z" /><circle cx="7" cy="7" r="3.25"/></svg>
<svg width="20" height="20" class="ci-status-icon-skipped" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Group Copy 31</title><g fill="#5C5C5C" fill-rule="evenodd"><path d="M10 17.857c4.286 0 7.857-3.571 7.857-7.857S14.286 2.143 10 2.143 2.143 5.714 2.143 10 5.714 17.857 10 17.857M10 0c5.571 0 10 4.429 10 10s-4.429 10-10 10S0 15.571 0 10 4.429 0 10 0"/><path d="M10.986 11l-1.293 1.293a1 1 0 0 0 1.414 1.414l2.644-2.644a1.505 1.505 0 0 0 0-2.126l-2.644-2.644a1 1 0 0 0-1.414 1.414L10.986 9H6.4a1 1 0 0 0 0 2h4.586z"/></g></svg>
......@@ -142,6 +142,7 @@
.col-sm-10.col-sm-offset-2
.checkbox
= label_tag 'merge_request[force_remove_source_branch]' do
= hidden_field_tag 'merge_request[force_remove_source_branch]', '0'
= check_box_tag 'merge_request[force_remove_source_branch]', '1', @merge_request.force_remove_source_branch?
Remove source branch when merge request is accepted.
......
......@@ -22,7 +22,7 @@
%button.dropdown-menu-toggle.js-label-select.js-multiselect{class: classes.join(' '), type: "button", data: dropdown_data}
%span.dropdown-toggle-text{ class: ("is-default" if selected.nil? || selected.empty?) }
= multi_label_name(selected, "Labels")
= icon('chevron-down')
= icon('caret-down')
.dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable
= render partial: "shared/issuable/label_page_default", locals: { title: dropdown_title, show_footer: show_footer, show_create: show_create }
- if show_create && project && can?(current_user, :admin_label, project)
......
......@@ -12,6 +12,7 @@ Options = Struct.new(
:amend,
:author,
:dry_run,
:force,
:merge_request,
:title
)
......@@ -21,7 +22,7 @@ class ChangelogOptionParser
options = Options.new
parser = OptionParser.new do |opts|
opts.banner = "Usage: #{__FILE__} [options]"
opts.banner = "Usage: #{__FILE__} [options] [title]\n\n"
# Note: We do not provide a shorthand for this in order to match the `git
# commit` interface
......@@ -29,6 +30,10 @@ class ChangelogOptionParser
options.amend = value
end
opts.on('-f', '--force', 'Overwrite an existing entry') do |value|
options.force = value
end
opts.on('-m', '--merge-request [integer]', Integer, 'Merge Request ID') do |value|
options.merge_request = value
end
......@@ -111,8 +116,9 @@ class ChangelogEntry
def assert_new_file!
return unless File.exist?(file_path)
return if options.force
fail_with "#{file_path} already exists!"
fail_with "#{file_path} already exists! Use `--force` to overwrite."
end
def assert_title!
......
---
title: Issues atom feed url reflect filters on dashboard
merge_request: 7114
author: Lucas Deschamps
---
title: Only skip group when it's actually a group in the "Share with group" select
merge_request: 7262
author:
---
title: 'Fix: Guest sees some repository details and gets 404'
merge_request:
author:
---
title: Introduce round-robin project creation to spread load over multiple shards
merge_request: 7266
author:
---
title: Ensure merge request's "remove branch" accessors return booleans
merge_request: 7267
author:
---
title: Fix invalid filename validation on eslint
merge_request: 7281
author:
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class RenameRepositoryStorageColumn < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
# When a migration requires downtime you **must** uncomment the following
# constant and define a short and easy to understand explanation as to why the
# migration requires downtime.
# DOWNTIME_REASON = ''
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
# To disable transactions uncomment the following line and remove these
# comments:
# disable_ddl_transaction!
def change
rename_column :application_settings, :repository_storage, :repository_storages
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161025231710) do
ActiveRecord::Schema.define(version: 20161103171205) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -88,7 +88,7 @@ ActiveRecord::Schema.define(version: 20161025231710) do
t.integer "container_registry_token_expire_delay", default: 5
t.text "after_sign_up_text"
t.boolean "user_default_external", default: false, null: false
t.string "repository_storage", default: "default"
t.string "repository_storages", default: "default"
t.string "enabled_git_access_protocol"
t.boolean "domain_blacklist_enabled", default: false
t.text "domain_blacklist"
......
......@@ -13,7 +13,8 @@ This guide talks about how to read and use these system log files.
This file lives in `/var/log/gitlab/gitlab-rails/production.log` for
omnibus package or in `/home/git/gitlab/log/production.log` for
installations from source.
installations from source. (When Gitlab is running in an environment
other than production, the corresponding logfile is shown here.)
It contains information about all performed requests. You can see the
URL and type of request, IP address and what exactly parts of code were
......
......@@ -91,6 +91,9 @@ be stored via the **Application Settings** in the Admin area.
![Choose repository storage path in Admin area](img/repository_storages_admin_ui.png)
Beginning with GitLab 8.13.4, multiple paths can be chosen. New projects will be
randomly placed on one of the selected paths.
[ce-4578]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4578
[restart gitlab]: restart_gitlab.md#installations-from-source
[reconfigure gitlab]: restart_gitlab.md#omnibus-gitlab-reconfigure
......
......@@ -2,7 +2,12 @@
## List groups
Get a list of groups. (As user: my groups, as admin: all groups)
Get a list of groups. (As user: my groups or all available, as admin: all groups).
Parameters:
- `all_available` (optional) - if passed, show all groups you have access to
- `skip_groups` (optional)(array of group IDs) - if passed, skip groups
```
GET /groups
......@@ -21,7 +26,6 @@ GET /groups
You can search for groups by name or path, see below.
## List a group's projects
Get a list of projects in this group.
......
......@@ -42,6 +42,7 @@ Example response:
"sign_in_text" : null,
"container_registry_token_expire_delay": 5,
"repository_storage": "default",
"repository_storages": ["default"],
"koding_enabled": false,
"koding_url": null
}
......@@ -73,7 +74,8 @@ PUT /application/settings
| `user_oauth_applications` | boolean | no | Allow users to register any application to use GitLab as an OAuth provider |
| `after_sign_out_path` | string | no | Where to redirect users after logout |
| `container_registry_token_expire_delay` | integer | no | Container Registry token duration in minutes |
| `repository_storage` | string | no | Storage path for new projects. The value should be the name of one of the repository storage paths defined in your gitlab.yml |
| `repository_storages` | array of strings | no | A list of names of enabled storage paths, taken from `gitlab.yml`. New projects will be created in one of these stores, chosen at random. |
| `repository_storage` | string | no | The first entry in `repository_storages`. Deprecated, but retained for compatibility reasons |
| `enabled_git_access_protocol` | string | no | Enabled protocols for Git access. Allowed values are: `ssh`, `http`, and `nil` to allow both protocols. |
| `koding_enabled` | boolean | no | Enable Koding integration. Default is `false`. |
| `koding_url` | string | yes (if `koding_enabled` is `true`) | The Koding instance URL for integration. |
......
......@@ -27,11 +27,14 @@ Example response:
```json
[
{
"id" : 1,
"url" : "https://gitlab.example.com/hook",
"created_at" : "2015-11-04T20:07:35.874Z"
}
{
"id":1,
"url":"https://gitlab.example.com/hook",
"created_at":"2016-10-31T12:32:15.192Z",
"push_events":true,
"tag_push_events":false,
"enable_ssl_verification":true
}
]
```
......@@ -48,6 +51,10 @@ POST /hooks
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `url` | string | yes | The hook URL |
| `token` | string | no | Secret token to validate received payloads; this will not be returned in the response |
| `push_events` | boolean | no | When true, the hook will fire on push events |
| `tag_push_events` | boolean | no | When true, the hook will fire on new tags being pushed |
| `enable_ssl_verification` | boolean | no | Do SSL verification when triggering the hook |
Example request:
......@@ -59,11 +66,14 @@ Example response:
```json
[
{
"id" : 2,
"url" : "https://gitlab.example.com/hook",
"created_at" : "2015-11-04T20:07:35.874Z"
}
{
"id":1,
"url":"https://gitlab.example.com/hook",
"created_at":"2016-10-31T12:32:15.192Z",
"push_events":true,
"tag_push_events":false,
"enable_ssl_verification":true
}
]
```
......
......@@ -226,7 +226,7 @@ e.g. `docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_ap
> **Note:**
This feature requires GitLab 8.8 and GitLab Runner 1.2.
Once you've built a Docker image, you can push it up to the built-in [GitLab Container Registry](../../container_registry/README.md). For example, if you're using
Once you've built a Docker image, you can push it up to the built-in [GitLab Container Registry](../../user/project/container_registry.md). For example, if you're using
docker-in-docker on your runners, this is how your `.gitlab-ci.yml` could look:
......
......@@ -21,6 +21,9 @@ The `merge_request` value is a reference to a merge request that adds this
entry, and the `author` key is used to give attribution to community
contributors. Both are optional.
Community contributors and core team members are encouraged to add their name to
the `author` field. GitLab team members should not.
If you're working on the GitLab EE repository, the entry will be added to
`changelogs/unreleased-ee/` instead.
......@@ -46,13 +49,14 @@ author:
The entry filename is based on the name of the current Git branch. If you run
the command above on a branch called `feature/hey-dz`, it will generate a
`changelogs/unreleased/feature-hey-dz` file.
`changelogs/unreleased/feature-hey-dz.yml` file.
### Arguments
| Argument | Shorthand | Purpose |
| ----------------- | --------- | --------------------------------------------- |
| `--amend` | | Amend the previous commit |
| `--force` | `-f` | Overwrite an existing entry |
| `--merge-request` | `-m` | Merge Request ID |
| `--dry-run` | `-n` | Don't actually write anything, just print |
| `--git-username` | `-u` | Use Git user.name configuration as the author |
......@@ -79,6 +83,23 @@ merge_request:
author:
```
#### `--force` or `-f`
Use **`--force`** or **`-f`** to overwrite an existing changelog entry if it
already exists.
```text
$ bin/changelog 'Hey DZ, I added a feature to GitLab!'
error changelogs/unreleased/feature-hey-dz.yml already exists! Use `--force` to overwrite.
$ bin/changelog 'Hey DZ, I added a feature to GitLab!' --force
create changelogs/unreleased/feature-hey-dz.yml
---
title: Hey DZ, I added a feature to GitLab!
merge_request: 1983
author:
```
#### `--merge-request` or `-m`
Use the **`--merge-request`** or **`-m`** argument to provide the
......
......@@ -465,6 +465,7 @@ curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --data "domain
[cURL]: http://curl.haxx.se/ "cURL website"
[single spaces]: http://www.slate.com/articles/technology/technology/2011/01/space_invaders.html
[gfm]: http://docs.gitlab.com/ce/user/markdown.html#newlines "GitLab flavored markdown documentation"
[ce-1242]: https://gitlab.com/gitlab-org/gitlab-ce/issues/1242
[doc-restart]: ../administration/restart_gitlab.md "GitLab restart documentation"
[ce-3349]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3349 "Documentation restructure"
[graffle]: https://gitlab.com/gitlab-org/gitlab-design/blob/d8d39f4a87b90fb9ae89ca12dc565347b4900d5e/production/resources/gitlab-map.graffle
......
......@@ -196,6 +196,12 @@ It consists of two subtasks:
As long as the fixtures don't change, `rake teaspoon:tests` is sufficient
(and saves you some time).
If you need to debug your tests and/or application code while they're
running, navigate to [localhost:3000/teaspoon](http://localhost:3000/teaspoon)
in your browser, open DevTools, and run tests for individual files by clicking
on them. This is also much faster than setting up and running tests from the
command line.
Please note: Not all of the frontend fixtures are generated. Some are still static
files. These will not be touched by `rake teaspoon:fixtures`.
......
......@@ -42,14 +42,6 @@ To run several tests inside one directory:
If you want to use [Spring](https://github.com/rails/spring) set
`ENABLE_SPRING=1` in your environment.
## Generate searchable docs for source code
You can find results under the `doc/code` directory.
```
bundle exec rake gitlab:generate_docs
```
## Generate API documentation for project services (e.g. Slack)
```
......
......@@ -271,9 +271,9 @@ sudo usermod -aG redis git
### Clone the Source
# Clone GitLab repository
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 8-13-stable gitlab
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 8-14-stable gitlab
**Note:** You can change `8-13-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
**Note:** You can change `8-14-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It
......@@ -479,10 +479,14 @@ Copy the example site config:
sudo cp lib/support/nginx/gitlab /etc/nginx/sites-available/gitlab
sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab
Make sure to edit the config file to match your setup:
Make sure to edit the config file to match your setup. Also, ensure that you match your paths to GitLab, especially if installing for a user other than the 'git' user:
# Change YOUR_SERVER_FQDN to the fully-qualified
# domain name of your host serving GitLab.
#
# Remember to match your paths to GitLab, especially
# if installing for a user other than 'git'.
#
# If using Ubuntu default nginx install:
# either remove the default_server from the listen line
# or else sudo rm -f /etc/nginx/sites-enabled/default
......
......@@ -2,7 +2,7 @@
GitLab University is the best place to learn about **Version Control with Git and GitLab**.
It doesn't replace, but accompanies our great [Documentation](http://docs.gitlab.com)
It doesn't replace, but accompanies our great [Documentation](https://docs.gitlab.com)
and [Blog Articles](https://about.gitlab.com/blog/).
Would you like to contribute to GitLab University? Then please take a look at our contribution [process](/process) for more information.
......@@ -31,7 +31,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [An Overview of GitLab.com - Video](https://www.youtube.com/watch?v=WaiL5DGEMR4)
1. [Why Use Git and GitLab - Slides](https://docs.google.com/a/gitlab.com/presentation/d/1RcZhFmn5VPvoFu6UMxhMOy7lAsToeBZRjLRn0LIdaNc/edit?usp=drive_web)
1. [GitLab Basics - Article](http://doc.gitlab.com/ce/gitlab-basics/README.html)
1. [GitLab Basics - Article](../gitlab-basics/README.md)
1. [Git and GitLab Basics - Video](https://www.youtube.com/watch?v=03wb9FvO4Ak&index=5&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e)
1. [Git and GitLab Basics - Online Course](https://courses.platzi.com/classes/git-gitlab/concepto/part-1/part-23370/material/)
1. [Comparison of GitLab Versions](https://about.gitlab.com/features/#compare)
......@@ -51,10 +51,10 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
#### 1.5. Migrating from other Source Control
1. [Migrating from BitBucket/Stash](http://doc.gitlab.com/ee/workflow/importing/import_projects_from_bitbucket.html)
1. [Migrating from GitHub](http://doc.gitlab.com/ee/workflow/importing/import_projects_from_github.html)
1. [Migrating from SVN](http://doc.gitlab.com/ee/workflow/importing/migrating_from_svn.html)
1. [Migrating from Fogbugz](http://doc.gitlab.com/ee/workflow/importing/import_projects_from_fogbugz.html)
1. [Migrating from BitBucket/Stash](https://docs.gitlab.com/ee/workflow/importing/import_projects_from_bitbucket.html)
1. [Migrating from GitHub](https://docs.gitlab.com/ee/workflow/importing/import_projects_from_github.html)
1. [Migrating from SVN](https://docs.gitlab.com/ee/workflow/importing/migrating_from_svn.html)
1. [Migrating from Fogbugz](https://docs.gitlab.com/ee/workflow/importing/import_projects_from_fogbugz.html)
#### 1.6. GitLab Inc.
......@@ -91,11 +91,11 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [Using any Static Site Generator with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
1. [Securing GitLab Pages with SSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/)
1. [GitLab Pages Documentation](http://doc.gitlab.com/ee/pages/README.html)
1. [GitLab Pages Documentation](https://docs.gitlab.com/ee/pages/README.html)
#### 2.2. GitLab Issues
1. [Markdown in GitLab](http://doc.gitlab.com/ce/markdown/markdown.html)
1. [Markdown in GitLab](../user/markdown.md)
1. [Issues and Merge Requests - Video](https://www.youtube.com/watch?v=raXvuwet78M)
1. [Due Dates and Milestones fro GitLab Issues](https://about.gitlab.com/2016/08/05/feature-highlight-set-dates-for-issues/)
1. [How to Use GitLab Labels](https://about.gitlab.com/2016/08/17/using-gitlab-labels/)
......@@ -129,7 +129,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [GitLab Flow vs Forking in GitLab - Video](https://www.youtube.com/watch?v=UGotqAUACZA)
1. [GitLab Flow Overview](https://about.gitlab.com/2014/09/29/gitlab-flow/)
1. [Always Start with an Issue](https://about.gitlab.com/2016/03/03/start-with-an-issue/)
1. [GitLab Flow Documentation](http://doc.gitlab.com/ee/workflow/gitlab_flow.html)
1. [GitLab Flow Documentation](https://docs.gitlab.com/ee/workflow/gitlab_flow.html)
#### 2.5. GitLab Comparisons
......@@ -189,8 +189,8 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
#### 3.9. <a name="integrations"></a> Integrations
1. [How to Integrate JIRA and Jenkins with GitLab - Video](https://gitlabmeetings.webex.com/gitlabmeetings/ldr.php?RCID=44b548147a67ab4d8a62274047146415)
1. [How to Integrate Jira with GitLab](http://doc.gitlab.com/ee/integration/jira.html)
1. [How to Integrate Jenkins with GitLab](http://doc.gitlab.com/ee/integration/jenkins.html)
1. [How to Integrate Jira with GitLab](https://docs.gitlab.com/ee/integration/jira.html)
1. [How to Integrate Jenkins with GitLab](https://docs.gitlab.com/ee/integration/jenkins.html)
1. [How to Integrate Bamboo with GitLab](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/project_services/bamboo.md)
1. [How to Integrate Slack with GitLab](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/slack.md)
1. [How to Integrate Convox with GitLab](https://about.gitlab.com/2016/06/09/continuous-delivery-with-gitlab-and-convox/)
......
......@@ -10,7 +10,7 @@ User authentication by combination of 2 different steps during login. This allow
### Access Levels
Process of selective restriction to create, view, modify or delete a resource based on a set of assigned permissions. See [GitLab's Permission Guidelines](http://doc.gitlab.com/ce/permissions/permissions.html)
Process of selective restriction to create, view, modify or delete a resource based on a set of assigned permissions. See [GitLab's Permission Guidelines](../../permissions/permissions.md
### Active Directory (AD)
......
......@@ -58,28 +58,28 @@ Sometimes we need to upgrade customers from old versions of GitLab to latest, so
- Users
- Groups
- Projects
- [Backup using our Backup rake task](http://docs.gitlab.com/ce/raketasks/backup_restore.html#create-a-backup-of-the-gitlab-system)
- [Backup using our Backup rake task](https://docs.gitlab.com/ce/raketasks/backup_restore.html#create-a-backup-of-the-gitlab-system)
- [Upgrade to 5.0 source using our Upgrade documentation](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/doc/update/4.2-to-5.0.md)
- [Upgrade to 5.1 source](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/doc/update/5.0-to-5.1.md)
- [Upgrade to 6.0 source](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/doc/update/5.1-to-6.0.md)
- [Upgrade to 7.14 source](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/doc/update/6.x-or-7.x-to-7.14.md)
- [Backup using our Backup rake task](http://docs.gitlab.com/ce/raketasks/backup_restore.html#create-a-backup-of-the-gitlab-system)
- [Perform the MySQL to PostgreSQL migration to convert your backup](http://docs.gitlab.com/ce/update/mysql_to_postgresql.html#converting-a-gitlab-backup-file-from-mysql-to-postgres)
- [Upgrade to Omnibus 7.14](http://doc.gitlab.com/omnibus/update/README.html#upgrading-from-a-non-omnibus-installation-to-an-omnibus-installation)
- [Restore backup using our Restore rake task](http://docs.gitlab.com/ce/raketasks/backup_restore.html#restore-a-previously-created-backup)
- [Backup using our Backup rake task](https://docs.gitlab.com/ce/raketasks/backup_restore.html#create-a-backup-of-the-gitlab-system)
- [Perform the MySQL to PostgreSQL migration to convert your backup](https://docs.gitlab.com/ce/update/mysql_to_postgresql.html#converting-a-gitlab-backup-file-from-mysql-to-postgres)
- [Upgrade to Omnibus 7.14](https://docs.gitlab.com/omnibus/update/README.html#upgrading-from-a-non-omnibus-installation-to-an-omnibus-installation)
- [Restore backup using our Restore rake task](https://docs.gitlab.com/ce/raketasks/backup_restore.html#restore-a-previously-created-backup)
- [Upgrade to latest EE](https://about.gitlab.com/downloads-ee)
- (GitLab inc. only) Acquire and apply a license for the Enterprise Edition product, ask in #support
- Perform a downgrade from [EE to CE](http://doc.gitlab.com/ee/downgrade_ee_to_ce/README.html)
- Perform a downgrade from [EE to CE](https://docs.gitlab.com/ee/downgrade_ee_to_ce/README.html)
#### Start to learn about some of the integrations that we support
Our integrations add great value to GitLab. User questions often relate to integrating GitLab with existing external services and the configuration involved
- Learn about our Integrations (specially, not only):
- [LDAP](http://doc.gitlab.com/ee/integration/ldap.html)
- [JIRA](http://doc.gitlab.com/ee/project_services/jira.html)
- [Jenkins](http://doc.gitlab.com/ee/integration/jenkins.html)
- [SAML](http://doc.gitlab.com/ce/integration/saml.html)
- [LDAP](https://docs.gitlab.com/ee/integration/ldap.html)
- [JIRA](https://docs.gitlab.com/ee/project_services/jira.html)
- [Jenkins](https://docs.gitlab.com/ee/integration/jenkins.html)
- [SAML](https://docs.gitlab.com/ce/integration/saml.html)
#### Goals
......@@ -91,8 +91,8 @@ Our integrations add great value to GitLab. User questions often relate to integ
#### Understand the gathering of diagnostics for GitLab instances
- Learn about the GitLab checks that are available
- [Environment Information and maintenance checks](http://docs.gitlab.com/ce/raketasks/maintenance.html)
- [GitLab check](http://docs.gitlab.com/ce/raketasks/check.html)
- [Environment Information and maintenance checks](https://docs.gitlab.com/ce/raketasks/maintenance.html)
- [GitLab check](https://docs.gitlab.com/ce/raketasks/check.html)
- Omnibus commands
- [Status](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#get-service-status)
- [Starting and stopping services](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#starting-and-stopping)
......@@ -167,12 +167,12 @@ Some tickets need specific knowledge or a deep understanding of a particular com
Move on to understanding some of GitLab's more advanced features. You can make use of GitLab.com to understand the features from an end-user perspective and then use your own instance to understand setup and configuration of the feature from an Administrative perspective
- Set up and try [Git Annex](http://doc.gitlab.com/ee/workflow/git_annex.html)
- Set up and try [Git LFS](http://doc.gitlab.com/ee/workflow/lfs/manage_large_binaries_with_git_lfs.html)
- Get to know the [GitLab API](http://doc.gitlab.com/ee/api/README.html), its capabilities and shortcomings
- Learn how to [migrate from SVN to Git](http://doc.gitlab.com/ee/workflow/importing/migrating_from_svn.html)
- Set up [GitLab CI](http://doc.gitlab.com/ee/ci/quick_start/README.html)
- Create your first [GitLab Page](http://doc.gitlab.com/ee/pages/administration.html)
- Set up and try [Git Annex](https://docs.gitlab.com/ee/workflow/git_annex.html)
- Set up and try [Git LFS](https://docs.gitlab.com/ee/workflow/lfs/manage_large_binaries_with_git_lfs.html)
- Get to know the [GitLab API](https://docs.gitlab.com/ee/api/README.html), its capabilities and shortcomings
- Learn how to [migrate from SVN to Git](https://docs.gitlab.com/ee/workflow/importing/migrating_from_svn.html)
- Set up [GitLab CI](https://docs.gitlab.com/ee/ci/quick_start/README.html)
- Create your first [GitLab Page](https://docs.gitlab.com/ee/pages/administration.html)
- Get to know the GitLab Codebase by reading through the source code:
- Find the differences between the [EE codebase](https://gitlab.com/gitlab-org/gitlab-ce)
and the [CE codebase](https://gitlab.com/gitlab-org/gitlab-ce)
......
# From 8.13 to 8.14
Make sure you view this update guide from the tag (version) of GitLab you would
like to install. In most cases this should be the highest numbered production
tag (without rc in it). You can select the tag in the version dropdown at the
top left corner of GitLab (below the menu bar).
If the highest number stable branch is unclear please check the
[GitLab Blog](https://about.gitlab.com/blog/archives.html) for installation
guide links by version.
### 1. Stop server
sudo service gitlab stop
### 2. Backup
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```
### 3. Update Ruby
We will continue supporting Ruby < 2.3 for the time being but we recommend you
upgrade to Ruby 2.3 if you're running a source installation, as this is the same
version that ships with our Omnibus package.
You can check which version you are running with `ruby -v`.
Download and compile Ruby:
```bash
mkdir /tmp/ruby && cd /tmp/ruby
curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz
echo 'c39b4001f7acb4e334cb60a0f4df72d434bef711 ruby-2.3.1.tar.gz' | shasum --check - && tar xzf ruby-2.3.1.tar.gz
cd ruby-2.3.1
./configure --disable-install-rdoc
make
sudo make install
```
Install Bundler:
```bash
sudo gem install bundler --no-ri --no-rdoc
```
### 4. Get latest code
```bash
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
```
For GitLab Community Edition:
```bash
sudo -u git -H git checkout 8-14-stable
```
OR
For GitLab Enterprise Edition:
```bash
sudo -u git -H git checkout 8-14-stable-ee
```
### 5. Update gitlab-shell
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch --all --tags
sudo -u git -H git checkout v4.0.0
```
### 6. Update gitlab-workhorse
Install and compile gitlab-workhorse. This requires
[Go 1.5](https://golang.org/dl) which should already be on your system from
GitLab 8.1.
```bash
cd /home/git/gitlab-workhorse
sudo -u git -H git fetch --all
sudo -u git -H git checkout v0.8.5
sudo -u git -H make
```
### 7. Install libs, migrations, etc.
```bash
cd /home/git/gitlab
# MySQL installations (note: the line below states '--without postgres')
sudo -u git -H bundle install --without postgres development test --deployment
# PostgreSQL installations (note: the line below states '--without mysql')
sudo -u git -H bundle install --without mysql development test --deployment
# Optional: clean up old gems
sudo -u git -H bundle clean
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Clean up assets and cache
sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
```
### 8. Update configuration files
#### New configuration options for `gitlab.yml`
There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them manually to your current `gitlab.yml`:
```sh
git diff origin/8-13-stable:config/gitlab.yml.example origin/8-14-stable:config/gitlab.yml.example
```
#### Git configuration
Configure Git to generate packfile bitmaps (introduced in Git 2.0) on
the GitLab server during `git gc`.
```sh
sudo -u git -H git config --global repack.writeBitmaps true
```
#### Nginx configuration
Ensure you're still up-to-date with the latest NGINX configuration changes:
```sh
# For HTTPS configurations
git diff origin/8-13-stable:lib/support/nginx/gitlab-ssl origin/8-14-stable:lib/support/nginx/gitlab-ssl
# For HTTP configurations
git diff origin/8-13-stable:lib/support/nginx/gitlab origin/8-14-stable:lib/support/nginx/gitlab
```
If you are using Apache instead of NGINX please see the updated [Apache templates].
Also note that because Apache does not support upstreams behind Unix sockets you
will need to let gitlab-workhorse listen on a TCP port. You can do this
via [/etc/default/gitlab].
[Apache templates]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache
[/etc/default/gitlab]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-14-stable/lib/support/init.d/gitlab.default.example#L38
#### SMTP configuration
If you're installing from source and use SMTP to deliver mail, you will need to add the following line
to config/initializers/smtp_settings.rb:
```ruby
ActionMailer::Base.delivery_method = :smtp
```
See [smtp_settings.rb.sample] as an example.
[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-14-stable/config/initializers/smtp_settings.rb.sample#L13
#### Init script
Ensure you're still up-to-date with the latest init script changes:
sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
For Ubuntu 16.04.1 LTS:
sudo systemctl daemon-reload
### 9. Start application
sudo service gitlab start
sudo service nginx restart
### 10. Check application status
Check if GitLab and its environment are configured correctly:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
To make sure you didn't miss anything run a more thorough check:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
If all items are green, then congratulations, the upgrade is complete!
## Things went south? Revert to previous version (8.13)
### 1. Revert the code to the previous version
Follow the [upgrade guide from 8.12 to 8.13](8.12-to-8.13.md), except for the
database migration (the backup is already migrated to the previous version).
### 2. Restore from the backup
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
```
If you have more than one backup `*.tar` file(s) please add `BACKUP=timestamp_of_backup` to the command above.
......@@ -4,7 +4,7 @@ class Spinach::Features::AdminLogs < Spinach::FeatureSteps
include SharedAdmin
step 'I should see tabs with available logs' do
expect(page).to have_content 'production.log'
expect(page).to have_content 'test.log'
expect(page).to have_content 'githost.log'
expect(page).to have_content 'application.log'
end
......
......@@ -43,14 +43,13 @@ module API
end
class Hook < Grape::Entity
expose :id, :url, :created_at
expose :id, :url, :created_at, :push_events, :tag_push_events
expose :enable_ssl_verification
end
class ProjectHook < Hook
expose :project_id, :push_events
expose :issues_events, :merge_requests_events, :tag_push_events
expose :project_id, :issues_events, :merge_requests_events
expose :note_events, :build_events, :pipeline_events, :wiki_page_events
expose :enable_ssl_verification
end
class BasicProjectDetails < Grape::Entity
......@@ -510,6 +509,7 @@ module API
expose :after_sign_out_path
expose :container_registry_token_expire_delay
expose :repository_storage
expose :repository_storages
expose :koding_enabled
expose :koding_url
end
......
......@@ -8,11 +8,14 @@ module API
#
# Parameters:
# skip_groups (optional) - Array of group ids to exclude from list
# all_available (optional, boolean) - Show all group that you have access to
# Example Request:
# GET /groups
get do
@groups = if current_user.admin
Group.all
elsif params[:all_available]
GroupsFinder.new.execute(current_user)
else
current_user.groups
end
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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