Commit 8ae9b485 authored by Valery Sizov's avatar Valery Sizov

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ee into ce-to-ee-tue

parents 8ab045ad dc4945f2
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
## 9.0.5 (2017-04-10)
- Return 404 instead of a 500 error on API status endpoint if Geo tracking DB is not enabled.
## 9.0.4 (2017-04-05) ## 9.0.4 (2017-04-05)
- No changes. - No changes.
......
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
## 9.0.5 (2017-04-10)
- Add shortcuts and counters to MRs and issues in navbar.
- Disable invalid service templates.
- Handle SSH keys that have multiple spaces between each marker.
## 9.0.4 (2017-04-05) ## 9.0.4 (2017-04-05)
- Don’t show source project name when user does not have access. - Don’t show source project name when user does not have access.
......
/* eslint-disable func-names, space-before-function-paren, quotes, object-shorthand, camelcase, no-var, comma-dangle, prefer-arrow-callback, quote-props, no-param-reassign, max-len */ /* eslint-disable func-names, space-before-function-paren, quotes, object-shorthand, camelcase, no-var, comma-dangle, prefer-arrow-callback, quote-props, no-param-reassign, max-len */
var Api = { var Api = {
groupsPath: "/api/:version/groups.json", groupsPath: '/api/:version/groups.json',
groupPath: "/api/:version/groups/:id.json", groupPath: '/api/:version/groups/:id.json',
namespacesPath: "/api/:version/namespaces.json", namespacesPath: '/api/:version/namespaces.json',
groupProjectsPath: "/api/:version/groups/:id/projects.json", groupProjectsPath: '/api/:version/groups/:id/projects.json',
projectsPath: "/api/:version/projects.json?simple=true", projectsPath: '/api/:version/projects.json?simple=true',
labelsPath: "/:namespace_path/:project_path/labels", labelsPath: '/:namespace_path/:project_path/labels',
licensePath: "/api/:version/templates/licenses/:key", licensePath: '/api/:version/templates/licenses/:key',
gitignorePath: "/api/:version/templates/gitignores/:key", gitignorePath: '/api/:version/templates/gitignores/:key',
gitlabCiYmlPath: "/api/:version/templates/gitlab_ci_ymls/:key", gitlabCiYmlPath: '/api/:version/templates/gitlab_ci_ymls/:key',
ldapGroupsPath: "/api/:version/ldap/:provider/groups.json", ldapGroupsPath: '/api/:version/ldap/:provider/groups.json',
dockerfilePath: "/api/:version/templates/dockerfiles/:key", dockerfilePath: '/api/:version/templates/dockerfiles/:key',
issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key", issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
group: function(group_id, callback) { group: function(group_id, callback) {
var url = Api.buildUrl(Api.groupPath) var url = Api.buildUrl(Api.groupPath)
.replace(':id', group_id); .replace(':id', group_id);
return $.ajax({ return $.ajax({
url: url, url: url,
dataType: "json" dataType: 'json'
}).done(function(group) { }).done(function(group) {
return callback(group); return callback(group);
}); });
}, },
users: function(search, options, callback = $.noop) {
var url = Api.buildUrl('/autocomplete/users.json');
return $.ajax({
url,
data: $.extend({
search,
per_page: 20
}, options),
dataType: 'json'
}).done(callback);
},
// Return groups list. Filtered by query // Return groups list. Filtered by query
groups: function(query, options, callback) { groups: function(query, options, callback = $.noop) {
var url = Api.buildUrl(Api.groupsPath); var url = Api.buildUrl(Api.groupsPath);
return $.ajax({ return $.ajax({
url: url, url: url,
...@@ -32,7 +43,7 @@ var Api = { ...@@ -32,7 +43,7 @@ var Api = {
search: query, search: query,
per_page: 20 per_page: 20
}, options), }, options),
dataType: "json" dataType: 'json'
}).done(function(groups) { }).done(function(groups) {
return callback(groups); return callback(groups);
}); });
...@@ -46,7 +57,7 @@ var Api = { ...@@ -46,7 +57,7 @@ var Api = {
search: query, search: query,
per_page: 20 per_page: 20
}, },
dataType: "json" dataType: 'json'
}).done(function(namespaces) { }).done(function(namespaces) {
return callback(namespaces); return callback(namespaces);
}); });
...@@ -61,7 +72,7 @@ var Api = { ...@@ -61,7 +72,7 @@ var Api = {
per_page: 20, per_page: 20,
membership: true membership: true
}, options), }, options),
dataType: "json" dataType: 'json'
}).done(function(projects) { }).done(function(projects) {
return callback(projects); return callback(projects);
}); });
...@@ -72,9 +83,9 @@ var Api = { ...@@ -72,9 +83,9 @@ var Api = {
.replace(':project_path', project_path); .replace(':project_path', project_path);
return $.ajax({ return $.ajax({
url: url, url: url,
type: "POST", type: 'POST',
data: { 'label': data }, data: { 'label': data },
dataType: "json" dataType: 'json'
}).done(function(label) { }).done(function(label) {
return callback(label); return callback(label);
}).error(function(message) { }).error(function(message) {
...@@ -91,7 +102,7 @@ var Api = { ...@@ -91,7 +102,7 @@ var Api = {
search: query, search: query,
per_page: 20 per_page: 20
}, },
dataType: "json" dataType: 'json'
}).done(function(projects) { }).done(function(projects) {
return callback(projects); return callback(projects);
}); });
...@@ -156,7 +167,7 @@ var Api = { ...@@ -156,7 +167,7 @@ var Api = {
per_page: 20, per_page: 20,
active: true active: true
}, },
dataType: "json" dataType: 'json'
}).done(function(groups) { }).done(function(groups) {
return callback(groups); return callback(groups);
}); });
......
/* global Api */
export default class ApproversSelect {
constructor() {
this.$approverSelect = $('.js-select-user-and-group');
const name = this.$approverSelect.data('name');
this.fieldNames = [`${name}[approver_ids]`, `${name}[approver_group_ids]`];
this.$loadWrapper = $('.load-wrapper');
this.bindEvents();
this.addEvents();
this.initSelect2();
}
bindEvents() {
this.handleSelectChange = this.handleSelectChange.bind(this);
this.fetchGroups = this.fetchGroups.bind(this);
this.fetchUsers = this.fetchUsers.bind(this);
}
addEvents() {
$(document).on('click', '.js-add-approvers', () => this.addApprover());
$(document).on('click', '.js-approver-remove', e => ApproversSelect.removeApprover(e));
}
static getApprovers(fieldName, selector, key) {
const input = $(`[name="${fieldName}"]`);
const existingApprovers = $(selector).map((i, el) =>
parseInt($(el).data('id'), 10),
);
const selectedApprovers = input.val()
.split(',')
.filter(val => val !== '');
const approvers = {
[key]: [...existingApprovers, ...selectedApprovers],
};
return approvers;
}
fetchGroups(term) {
const options = ApproversSelect.getApprovers(this.fieldNames[1], '.js-approver-group', 'skip_groups');
return Api.groups(term, options);
}
fetchUsers(term) {
const options = ApproversSelect.getApprovers(this.fieldNames[0], '.js-approver', 'skip_users');
return Api.users(term, options);
}
handleSelectChange(e) {
const { added, removed } = e;
const userInput = $(`[name="${this.fieldNames[0]}"]`);
const groupInput = $(`[name="${this.fieldNames[1]}"]`);
if (added) {
if (added.full_name) {
groupInput.val(`${groupInput.val()},${added.id}`.replace(/^,/, ''));
} else {
userInput.val(`${userInput.val()},${added.id}`.replace(/^,/, ''));
}
}
if (removed) {
if (removed.full_name) {
groupInput.val(groupInput.val().replace(new RegExp(`,?${removed.id}`), ''));
} else {
userInput.val(userInput.val().replace(new RegExp(`,?${removed.id}`), ''));
}
}
}
initSelect2() {
this.$approverSelect.select2({
placeholder: 'Search for users or groups',
multiple: true,
minimumInputLength: 0,
query: (query) => {
const fetchGroups = this.fetchGroups(query.term);
const fetchUsers = this.fetchUsers(query.term);
return $.when(fetchGroups, fetchUsers).then((groups, users) => {
const data = {
results: groups[0].concat(users[0]),
};
return query.callback(data);
});
},
formatResult: ApproversSelect.formatResult,
formatSelection: ApproversSelect.formatSelection,
dropdownCss() {
const $input = $('.js-select-user-and-group .select2-input');
const offset = $input.offset();
const inputRightPosition = offset.left + $input.outerWidth();
const $dropdown = $('.select2-drop-active');
let left = offset.left;
if ($dropdown.outerWidth() > $input.outerWidth()) {
left = `${inputRightPosition - $dropdown.width()}px`;
}
return {
left,
right: 'auto',
width: 'auto',
};
},
})
.on('change', this.handleSelectChange);
}
static formatSelection(group) {
return group.full_name || group.name;
}
static formatResult({
name,
username,
avatar_url: avatarUrl,
full_name: fullName,
full_path: fullPath,
}) {
if (username) {
const avatar = avatarUrl || gon.default_avatar_url;
return `
<div class="user-result">
<div class="user-image">
<img class="avatar s40" src="${avatar}">
</div>
<div class="user-info">
<div class="user-name">${name}</div>
<div class="user-username">@${username}</div>
</div>
</div>
`;
}
return `
<div class="group-result">
<div class="group-name">${fullName}</div>
<div class="group-path">${fullPath}</div>
</div>
`;
}
addApprover() {
this.fieldNames.forEach(ApproversSelect.saveApprovers);
}
static saveApprovers(fieldName) {
const $input = $(`[name="${fieldName}"]`);
const newValue = $input.val();
const $loadWrapper = $('.load-wrapper');
const $approverSelect = $('.js-select-user-and-group');
if (!newValue) {
return;
}
const $form = $('.js-add-approvers').closest('form');
$loadWrapper.removeClass('hidden');
$.ajax({
url: $form.attr('action'),
type: 'POST',
data: {
_method: 'PATCH',
[fieldName]: newValue,
},
success: ApproversSelect.updateApproverList,
complete() {
$input.val('val', '');
$approverSelect.select2('val', '');
$loadWrapper.addClass('hidden');
},
error() {
window.Flash('Failed to add Approver', 'alert');
},
});
}
static removeApprover(e) {
e.preventDefault();
const target = e.currentTarget;
const $loadWrapper = $('.load-wrapper');
$loadWrapper.removeClass('hidden');
$.ajax({
url: target.getAttribute('href'),
type: 'POST',
data: {
_method: 'DELETE',
},
success: ApproversSelect.updateApproverList,
complete: () => $loadWrapper.addClass('hidden'),
error() {
window.Flash('Failed to remove Approver', 'alert');
},
});
}
static updateApproverList(html) {
$('.js-current-approvers').html($(html).find('.js-current-approvers').html());
}
}
...@@ -43,6 +43,7 @@ import Group from './group'; ...@@ -43,6 +43,7 @@ import Group from './group';
import GroupName from './group_name'; import GroupName from './group_name';
import GroupsList from './groups_list'; import GroupsList from './groups_list';
import ProjectsList from './projects_list'; import ProjectsList from './projects_list';
import ApproversSelect from './approvers_select';
import MiniPipelineGraph from './mini_pipeline_graph_dropdown'; import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
import BlobLinePermalinkUpdater from './blob/blob_line_permalink_updater'; import BlobLinePermalinkUpdater from './blob/blob_line_permalink_updater';
import BlobForkSuggestion from './blob/blob_fork_suggestion'; import BlobForkSuggestion from './blob/blob_fork_suggestion';
...@@ -432,6 +433,7 @@ const ShortcutsBlob = require('./shortcuts_blob'); ...@@ -432,6 +433,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'edit': case 'edit':
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
new ProjectNew(); new ProjectNew();
new ApproversSelect();
break; break;
case 'new': case 'new':
new ProjectNew(); new ProjectNew();
......
...@@ -67,7 +67,7 @@ export default { ...@@ -67,7 +67,7 @@ export default {
}, },
created() { created() {
this.getDeployBoard(); this.getDeployBoard(true);
}, },
updated() { updated() {
...@@ -80,14 +80,14 @@ export default { ...@@ -80,14 +80,14 @@ export default {
this.deployBoardData.completion < 100) { this.deployBoardData.completion < 100) {
// let's wait 1s and make the request again // let's wait 1s and make the request again
setTimeout(() => { setTimeout(() => {
this.getDeployBoard(); this.getDeployBoard(false);
}, 3000); }, 3000);
} }
}, },
methods: { methods: {
getDeployBoard() { getDeployBoard(showLoading) {
this.isLoading = true; this.isLoading = showLoading;
const maxNumberOfRequests = 3; const maxNumberOfRequests = 3;
......
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-unused-vars, one-var, no-underscore-dangle, prefer-template, no-else-return, prefer-arrow-callback, max-len */ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-unused-vars, one-var, no-underscore-dangle, prefer-template, no-else-return, prefer-arrow-callback, max-len */
(function() { (function() {
var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; };
this.ProjectNew = (function() { this.ProjectNew = (function() {
function ProjectNew() { function ProjectNew() {
this.toggleSettings = bind(this.toggleSettings, this);
this.$selects = $('.features select'); this.$selects = $('.features select');
this.$repoSelects = this.$selects.filter('.js-repo-select'); this.$repoSelects = this.$selects.filter('.js-repo-select');
this.$enableApprovers = $('.js-require-approvals-toggle');
$('.project-edit-container').on('ajax:before', (function(_this) { $('.project-edit-container').on('ajax:before', (function(_this) {
return function() { return function() {
...@@ -19,10 +17,15 @@ ...@@ -19,10 +17,15 @@
this.initVisibilitySelect(); this.initVisibilitySelect();
this.toggleSettings(); this.toggleSettings();
this.toggleSettingsOnclick(); this.bindEvents();
this.toggleRepoVisibility(); this.toggleRepoVisibility();
} }
ProjectNew.prototype.bindEvents = function() {
this.$selects.on('change', () => this.toggleSettings());
$('#require_approvals').on('change', e => this.toggleApproverSettingsVisibility(e));
};
ProjectNew.prototype.initVisibilitySelect = function() { ProjectNew.prototype.initVisibilitySelect = function() {
const visibilityContainer = document.querySelector('.js-visibility-select'); const visibilityContainer = document.querySelector('.js-visibility-select');
if (!visibilityContainer) return; if (!visibilityContainer) return;
...@@ -30,6 +33,15 @@ ...@@ -30,6 +33,15 @@
visibilitySelect.init(); visibilitySelect.init();
}; };
ProjectNew.prototype.toggleApproverSettingsVisibility = function(e) {
this.$requiredApprovals = $('#project_approvals_before_merge');
const enabled = $(e.target).prop('checked');
const val = enabled ? 1 : 0;
this.$requiredApprovals.val(val);
this.$requiredApprovals.prop('min', val);
$('.nested-settings').toggleClass('hidden', !enabled);
};
ProjectNew.prototype.toggleSettings = function() { ProjectNew.prototype.toggleSettings = function() {
var self = this; var self = this;
...@@ -42,10 +54,6 @@ ...@@ -42,10 +54,6 @@
}); });
}; };
ProjectNew.prototype.toggleSettingsOnclick = function() {
this.$selects.on('change', this.toggleSettings);
};
ProjectNew.prototype._showOrHide = function(checkElement, container) { ProjectNew.prototype._showOrHide = function(checkElement, container) {
var $container = $(container); var $container = $(container);
......
...@@ -386,7 +386,7 @@ ...@@ -386,7 +386,7 @@
} else { } else {
avatar = gon.default_avatar_url; avatar = gon.default_avatar_url;
} }
return "<div class='user-result " + (!user.username ? 'no-username' : void 0) + "'> <div class='user-image'><img class='avatar s24' src='" + avatar + "'></div> <div class='user-name'>" + user.name + "</div> <div class='user-username'>" + (user.username || "") + "</div> </div>"; return "<div class='user-result " + (!user.username ? 'no-username' : void 0) + "'> <div class='user-image'><img class='avatar s40' src='" + avatar + "'></div> <div><div class='user-name'>" + user.name + "</div> <div class='user-username'>" + (user.username || "") + "</div> </div> </div>";
}; };
UsersSelect.prototype.formatSelection = function(user) { UsersSelect.prototype.formatSelection = function(user) {
......
...@@ -47,9 +47,10 @@ ...@@ -47,9 +47,10 @@
} }
.select2-drop { .select2-drop {
box-shadow: $select2-drop-shadow1 0 0 1px 0, $select2-drop-shadow2 0 2px 18px 0; background-color: $white-light;
border-radius: $border-radius-default; border: 1px solid $dropdown-border-color;
border: none; border-radius: $border-radius-base;
box-shadow: 0 2px 4px $dropdown-shadow-color;
min-width: 175px; min-width: 175px;
} }
...@@ -63,7 +64,7 @@ ...@@ -63,7 +64,7 @@
} }
.select2-highlighted { .select2-highlighted {
background: $gl-link-color !important; background: $dropdown-hover-color !important;
} }
.select2-results li.select2-result-with-children > .select2-result-label { .select2-results li.select2-result-with-children > .select2-result-label {
...@@ -124,8 +125,8 @@ ...@@ -124,8 +125,8 @@
&.select2-container-active .select2-choices, &.select2-container-active .select2-choices,
&.select2-dropdown-open .select2-choices { &.select2-dropdown-open .select2-choices {
border-color: $border-white-normal; border-color: $dropdown-input-focus-border;
box-shadow: $gl-btn-active-gradient; box-shadow: 0 0 4px $search-input-focus-shadow-color;
} }
} }
...@@ -237,6 +238,7 @@ ...@@ -237,6 +238,7 @@
.user-result { .user-result {
min-height: 24px; min-height: 24px;
display: flex;
.user-image { .user-image {
float: left; float: left;
......
...@@ -46,11 +46,19 @@ ...@@ -46,11 +46,19 @@
} }
} }
.load-wrapper {
position: absolute;
background: $black-transparent;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
.input-group > div { .input-group > div {
margin-bottom: 14px;
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
......
...@@ -35,3 +35,28 @@ ...@@ -35,3 +35,28 @@
margin-left: 5px; margin-left: 5px;
} }
} }
.nested-settings {
padding-left: 20px;
}
.input-btn-group {
display: flex;
.input-large {
flex: 1;
}
.btn {
margin-left: 10px;
}
}
.settings-flex-row {
display: flex;
align-items: center;
.pull-right {
margin-left: auto;
}
}
...@@ -3,7 +3,7 @@ class Admin::GeoNodesController < Admin::ApplicationController ...@@ -3,7 +3,7 @@ class Admin::GeoNodesController < Admin::ApplicationController
before_action :load_node, only: [:destroy, :repair, :toggle, :status] before_action :load_node, only: [:destroy, :repair, :toggle, :status]
def index def index
@nodes = GeoNode.all @nodes = GeoNode.all.order(:id)
@node = GeoNode.new @node = GeoNode.new
unless Gitlab::Geo.license_allows? unless Gitlab::Geo.license_allows?
......
...@@ -12,5 +12,14 @@ module EE ...@@ -12,5 +12,14 @@ module EE
expire_branch_cache expire_branch_cache
expire_content_cache expire_content_cache
end end
# Returns a list of commits that are not present in any reference
def new_commits(newrev)
refs = ::Gitlab::Git::RevList.new(
path_to_repo: path_to_repo,
newrev: newrev).new_refs
refs.map { |sha| commit(sha.strip) }
end
end end
end end
...@@ -636,15 +636,6 @@ class Repository ...@@ -636,15 +636,6 @@ class Repository
commit(sha) commit(sha)
end end
# Returns a list of commits that are not present in any reference
def new_commits(newrev)
args = %W(#{Gitlab.config.git.bin_path} rev-list #{newrev} --not --all)
Gitlab::Popen.popen(args, path_to_repo).first.split("\n").map do |sha|
commit(sha.strip)
end
end
def last_commit_id_for_path(sha, path) def last_commit_id_for_path(sha, path)
key = path.blank? ? "last_commit_id_for_path:#{sha}" : "last_commit_id_for_path:#{sha}:#{Digest::SHA1.hexdigest(path)}" key = path.blank? ? "last_commit_id_for_path:#{sha}" : "last_commit_id_for_path:#{sha}:#{Digest::SHA1.hexdigest(path)}"
......
...@@ -43,55 +43,75 @@ ...@@ -43,55 +43,75 @@
.hint .hint
Description parsed with #{link_to "GitLab Flavored Markdown", help_page_path('user/markdown'), target: '_blank'}. Description parsed with #{link_to "GitLab Flavored Markdown", help_page_path('user/markdown'), target: '_blank'}.
.form-group
= form.label :approvals_before_merge, class: 'label-light' do
Approvals required
= form.number_field :approvals_before_merge, class: "form-control", min: 0
.help-block
Number of users to approve a merge request before it can be accepted. 0 - approving is disabled
.form-group.reset-approvals-on-push .form-group.reset-approvals-on-push
.checkbox .checkbox
= form.label :reset_approvals_on_push do = label_tag :require_approvals do
= form.check_box :reset_approvals_on_push = check_box_tag :require_approvals, nil, project.approvals_before_merge.nonzero?, class: 'js-require-approvals-toggle'
%span.descr Reset approvals on push %strong Activate merge request approvals
.help-block Approvals are reset when new data is pushed to the merge request = link_to icon('question-circle'), help_page_path("user/project/merge_requests/merge_request_approvals"), target: '_blank'
.descr Merge request approvals allow you to set the number of necessary approvals and predefine a list of approvers that you will need to approve every merge request in a project.
.form-group .nested-settings{ class: project.approvals_before_merge.nonzero? ? '' : 'hidden' }
.form-group
= form.label :approver_ids, class: 'label-light' do = form.label :approver_ids, class: 'label-light' do
Approvers Approvers
= users_select_tag("project[approver_ids]", multiple: true, class: 'input-large', scope: :all, email_user: true) = hidden_field_tag "project[approver_ids]"
.help-block = hidden_field_tag "project[approver_group_ids]"
Add an approver suggestion for each merge request .input-group.input-btn-group
= form.label :approver_group_ids, class: 'label-light' do = hidden_field_tag :approver_user_and_group_ids, '', { class: 'js-select-user-and-group input-large', tabindex: 1, 'data-name': 'project' }
Approver groups %button.btn.btn-success.js-add-approvers{ type: 'button', title: 'Add approvers(s)' }
- skip_groups = project.approver_groups.pluck(:group_id) Add
= groups_select_tag('project[approver_group_ids]', multiple: true, data: { skip_groups: skip_groups, all_available: true }, class: 'input-large')
.help-block .help-block
Add a group as an approver suggestion for each merge request Add an approver or group suggestion for each merge request
.panel.panel-default.prepend-top-10 .panel.panel-default.prepend-top-10.js-current-approvers
.panel-heading .panel-heading
Approvers Approvers
%span.badge
- ids = []
- project.approvers.each do |user|
- ids << user.user_id
- project.approver_groups.each do |group|
- group.users.each do |user|
- unless ids.include?(user.id)
- ids << user.id
= ids.count
%ul.well-list.approver-list %ul.well-list.approver-list
.load-wrapper.hidden
= icon('spinner spin', class: 'approver-list-loader')
- project.approvers.each do |approver| - project.approvers.each do |approver|
%li.approver %li.approver.settings-flex-row.js-approver{ data: { id: approver.user_id } }
= link_to approver.user.name, approver.user = link_to approver.user.name, approver.user
.pull-right .pull-right
= link_to namespace_project_approver_path(project.namespace, project, approver), data: { confirm: "Are you sure you want to remove approver #{approver.user.name}"}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove approver' do %button{ href: namespace_project_approver_path(project.namespace, project, approver), data: { confirm: "Are you sure you want to remove approver #{approver.user.name}"}, class: "btn btn-remove js-approver-remove", title: 'Remove approver' }
= icon("sign-out") = icon("trash")
Remove
- project.approver_groups.each do |approver_group| - project.approver_groups.each do |approver_group|
%li.approver-group %li.approver-group.settings-flex-row.js-approver-group{ data: { id: approver_group.group.id } }
.span
%span.light
Group: Group:
= link_to approver_group.group.name, approver_group.group = link_to approver_group.group.name, approver_group.group
%span.badge
= approver_group.group.members.count
.pull-right .pull-right
= link_to namespace_project_approver_group_path(project.namespace, project, approver_group), data: { confirm: "Are you sure you want to remove group #{approver_group.group.name}" }, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove group' do %button{ href: namespace_project_approver_group_path(project.namespace, project, approver_group), data: { confirm: "Are you sure you want to remove group #{approver_group.group.name}" }, class: "btn btn-remove js-approver-remove", title: 'Remove group' }
= icon("sign-out") = icon("trash")
Remove
- if project.approvers.empty? && project.approver_groups.empty? - if project.approvers.empty? && project.approver_groups.empty?
%li There are no approvers %li There are no approvers
.form-group
= form.label :approvals_before_merge, class: 'label-light' do
Approvals required
= form.number_field :approvals_before_merge, class: "form-control", min: 0
.help-block
.form-group.reset-approvals-on-push
.checkbox
= form.label :reset_approvals_on_push do
= form.check_box :reset_approvals_on_push
%strong Reset approvals on push
.descr Approvals are reset when new data is pushed to the merge request
:javascript :javascript
new UsersSelect(); new UsersSelect();
new GroupsSelect(); new GroupsSelect();
---
title: Fix pre-receive hooks when using Git 2.11 or later.
merge_request: 1525
author:
---
title: Return 404 instead of a 500 error on API status endpoint if Geo tracking DB is not enabled
merge_request:
author:
---
title: Add shortcuts and counters to MRs and issues in navbar
merge_request:
author:
---
title: Handle SSH keys that have multiple spaces between each marker
merge_request:
author:
...@@ -304,6 +304,17 @@ Additional pagination headers are also sent back. ...@@ -304,6 +304,17 @@ Additional pagination headers are also sent back.
| `X-Next-Page` | The index of the next page | | `X-Next-Page` | The index of the next page |
| `X-Prev-Page` | The index of the previous page | | `X-Prev-Page` | The index of the previous page |
## Namespaced path encoding
If using namespaced API calls, make sure that the `NAMESPACE/PROJECT_NAME` is
URL-encoded.
For example, `/` is represented by `%2F`:
```
/api/v4/projects/diaspora%2Fdiaspora
```
## `id` vs `iid` ## `id` vs `iid`
When you work with the API, you may notice two similar fields in API entities: When you work with the API, you may notice two similar fields in API entities:
...@@ -399,7 +410,6 @@ Content-Type: application/json ...@@ -399,7 +410,6 @@ Content-Type: application/json
} }
``` ```
## Clients ## Clients
There are many unofficial GitLab API Clients for most of the popular There are many unofficial GitLab API Clients for most of the popular
......
...@@ -25,7 +25,7 @@ GET /projects/:id/access_requests ...@@ -25,7 +25,7 @@ GET /projects/:id/access_requests
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/:id/access_requests curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/:id/access_requests
...@@ -66,7 +66,7 @@ POST /projects/:id/access_requests ...@@ -66,7 +66,7 @@ POST /projects/:id/access_requests
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/:id/access_requests curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/:id/access_requests
...@@ -97,7 +97,7 @@ PUT /projects/:id/access_requests/:user_id/approve ...@@ -97,7 +97,7 @@ PUT /projects/:id/access_requests/:user_id/approve
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the access requester | | `user_id` | integer | yes | The user ID of the access requester |
| `access_level` | integer | no | A valid access level (defaults: `30`, developer access level) | | `access_level` | integer | no | A valid access level (defaults: `30`, developer access level) |
...@@ -130,7 +130,7 @@ DELETE /projects/:id/access_requests/:user_id ...@@ -130,7 +130,7 @@ DELETE /projects/:id/access_requests/:user_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the access requester | | `user_id` | integer | yes | The user ID of the access requester |
```bash ```bash
......
...@@ -23,7 +23,7 @@ Parameters: ...@@ -23,7 +23,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `awardable_id` | integer | yes | The ID (`iid` for merge requests/issues, `id` for snippets) of an awardable | | `awardable_id` | integer | yes | The ID (`iid` for merge requests/issues, `id` for snippets) of an awardable |
```bash ```bash
...@@ -83,7 +83,7 @@ Parameters: ...@@ -83,7 +83,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `awardable_id` | integer | yes | The ID (`iid` for merge requests/issues, `id` for snippets) of an awardable | | `awardable_id` | integer | yes | The ID (`iid` for merge requests/issues, `id` for snippets) of an awardable |
| `award_id` | integer | yes | The ID of the award emoji | | `award_id` | integer | yes | The ID of the award emoji |
...@@ -126,7 +126,7 @@ Parameters: ...@@ -126,7 +126,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `awardable_id` | integer | yes | The ID (`iid` for merge requests/issues, `id` for snippets) of an awardable | | `awardable_id` | integer | yes | The ID (`iid` for merge requests/issues, `id` for snippets) of an awardable |
| `name` | string | yes | The name of the emoji, without colons | | `name` | string | yes | The name of the emoji, without colons |
...@@ -170,7 +170,7 @@ Parameters: ...@@ -170,7 +170,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The internal ID of an issue | | `issue_iid` | integer | yes | The internal ID of an issue |
| `award_id` | integer | yes | The ID of a award_emoji | | `award_id` | integer | yes | The ID of a award_emoji |
...@@ -195,7 +195,7 @@ Parameters: ...@@ -195,7 +195,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The internal ID of an issue | | `issue_iid` | integer | yes | The internal ID of an issue |
| `note_id` | integer | yes | The ID of an note | | `note_id` | integer | yes | The ID of an note |
...@@ -237,7 +237,7 @@ Parameters: ...@@ -237,7 +237,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The internal ID of an issue | | `issue_iid` | integer | yes | The internal ID of an issue |
| `note_id` | integer | yes | The ID of a note | | `note_id` | integer | yes | The ID of a note |
| `award_id` | integer | yes | The ID of the award emoji | | `award_id` | integer | yes | The ID of the award emoji |
...@@ -277,7 +277,7 @@ Parameters: ...@@ -277,7 +277,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The internal ID of an issue | | `issue_iid` | integer | yes | The internal ID of an issue |
| `note_id` | integer | yes | The ID of a note | | `note_id` | integer | yes | The ID of a note |
| `name` | string | yes | The name of the emoji, without colons | | `name` | string | yes | The name of the emoji, without colons |
...@@ -320,7 +320,7 @@ Parameters: ...@@ -320,7 +320,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The internal ID of an issue | | `issue_iid` | integer | yes | The internal ID of an issue |
| `note_id` | integer | yes | The ID of a note | | `note_id` | integer | yes | The ID of a note |
| `award_id` | integer | yes | The ID of a award_emoji | | `award_id` | integer | yes | The ID of a award_emoji |
......
...@@ -15,7 +15,7 @@ GET /projects/:id/boards ...@@ -15,7 +15,7 @@ GET /projects/:id/boards
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/:id/boards curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/:id/boards
...@@ -84,7 +84,7 @@ GET /projects/:id/boards/:board_id/lists ...@@ -84,7 +84,7 @@ GET /projects/:id/boards/:board_id/lists
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `board_id` | integer | yes | The ID of a board | | `board_id` | integer | yes | The ID of a board |
```bash ```bash
...@@ -135,7 +135,7 @@ GET /projects/:id/boards/:board_id/lists/:list_id ...@@ -135,7 +135,7 @@ GET /projects/:id/boards/:board_id/lists/:list_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `board_id` | integer | yes | The ID of a board | | `board_id` | integer | yes | The ID of a board |
| `list_id`| integer | yes | The ID of a board's list | | `list_id`| integer | yes | The ID of a board's list |
...@@ -167,7 +167,7 @@ POST /projects/:id/boards/:board_id/lists ...@@ -167,7 +167,7 @@ POST /projects/:id/boards/:board_id/lists
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `board_id` | integer | yes | The ID of a board | | `board_id` | integer | yes | The ID of a board |
| `label_id` | integer | yes | The ID of a label | | `label_id` | integer | yes | The ID of a label |
...@@ -199,7 +199,7 @@ PUT /projects/:id/boards/:board_id/lists/:list_id ...@@ -199,7 +199,7 @@ PUT /projects/:id/boards/:board_id/lists/:list_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `board_id` | integer | yes | The ID of a board | | `board_id` | integer | yes | The ID of a board |
| `list_id` | integer | yes | The ID of a board's list | | `list_id` | integer | yes | The ID of a board's list |
| `position` | integer | yes | The position of the list | | `position` | integer | yes | The position of the list |
...@@ -232,7 +232,7 @@ DELETE /projects/:id/boards/:board_id/lists/:list_id ...@@ -232,7 +232,7 @@ DELETE /projects/:id/boards/:board_id/lists/:list_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `board_id` | integer | yes | The ID of a board | | `board_id` | integer | yes | The ID of a board |
| `list_id` | integer | yes | The ID of a board's list | | `list_id` | integer | yes | The ID of a board's list |
......
...@@ -12,7 +12,7 @@ GET /projects/:id/repository/branches ...@@ -12,7 +12,7 @@ GET /projects/:id/repository/branches
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/repository/branches curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/repository/branches
...@@ -59,7 +59,7 @@ GET /projects/:id/repository/branches/:branch ...@@ -59,7 +59,7 @@ GET /projects/:id/repository/branches/:branch
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `branch` | string | yes | The name of the branch | | `branch` | string | yes | The name of the branch |
```bash ```bash
...@@ -109,7 +109,7 @@ curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab ...@@ -109,7 +109,7 @@ curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `branch` | string | yes | The name of the branch | | `branch` | string | yes | The name of the branch |
| `developers_can_push` | boolean | no | Flag if developers can push to the branch | | `developers_can_push` | boolean | no | Flag if developers can push to the branch |
| `developers_can_merge` | boolean | no | Flag if developers can merge to the branch | | `developers_can_merge` | boolean | no | Flag if developers can merge to the branch |
...@@ -157,7 +157,7 @@ curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab ...@@ -157,7 +157,7 @@ curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `branch` | string | yes | The name of the branch | | `branch` | string | yes | The name of the branch |
Example response: Example response:
...@@ -195,7 +195,7 @@ POST /projects/:id/repository/branches ...@@ -195,7 +195,7 @@ POST /projects/:id/repository/branches
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `branch` | string | yes | The name of the branch | | `branch` | string | yes | The name of the branch |
| `ref` | string | yes | The branch name or commit SHA to create branch from | | `ref` | string | yes | The branch name or commit SHA to create branch from |
...@@ -238,7 +238,7 @@ DELETE /projects/:id/repository/branches/:branch ...@@ -238,7 +238,7 @@ DELETE /projects/:id/repository/branches/:branch
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `branch` | string | yes | The name of the branch | | `branch` | string | yes | The name of the branch |
In case of an error, an explaining message is provided. In case of an error, an explaining message is provided.
...@@ -257,7 +257,7 @@ DELETE /projects/:id/repository/merged_branches ...@@ -257,7 +257,7 @@ DELETE /projects/:id/repository/merged_branches
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
......
...@@ -10,7 +10,7 @@ GET /projects/:id/variables ...@@ -10,7 +10,7 @@ GET /projects/:id/variables
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID of a project or [urlencoded NAMESPACE/PROJECT_NAME of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
``` ```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/variables" curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/variables"
...@@ -39,7 +39,7 @@ GET /projects/:id/variables/:key ...@@ -39,7 +39,7 @@ GET /projects/:id/variables/:key
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|-----------|---------|----------|-----------------------| |-----------|---------|----------|-----------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID of a project or [urlencoded NAMESPACE/PROJECT_NAME of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `key` | string | yes | The `key` of a variable | | `key` | string | yes | The `key` of a variable |
``` ```
...@@ -63,7 +63,7 @@ POST /projects/:id/variables ...@@ -63,7 +63,7 @@ POST /projects/:id/variables
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|-----------|---------|----------|-----------------------| |-----------|---------|----------|-----------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID of a project or [urlencoded NAMESPACE/PROJECT_NAME of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `key` | string | yes | The `key` of a variable; must have no more than 255 characters; only `A-Z`, `a-z`, `0-9`, and `_` are allowed | | `key` | string | yes | The `key` of a variable; must have no more than 255 characters; only `A-Z`, `a-z`, `0-9`, and `_` are allowed |
| `value` | string | yes | The `value` of a variable | | `value` | string | yes | The `value` of a variable |
...@@ -88,7 +88,7 @@ PUT /projects/:id/variables/:key ...@@ -88,7 +88,7 @@ PUT /projects/:id/variables/:key
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|-----------|---------|----------|-------------------------| |-----------|---------|----------|-------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID of a project or [urlencoded NAMESPACE/PROJECT_NAME of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `key` | string | yes | The `key` of a variable | | `key` | string | yes | The `key` of a variable |
| `value` | string | yes | The `value` of a variable | | `value` | string | yes | The `value` of a variable |
...@@ -113,7 +113,7 @@ DELETE /projects/:id/variables/:key ...@@ -113,7 +113,7 @@ DELETE /projects/:id/variables/:key
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|-----------|---------|----------|-------------------------| |-----------|---------|----------|-------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID of a project or [urlencoded NAMESPACE/PROJECT_NAME of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `key` | string | yes | The `key` of a variable | | `key` | string | yes | The `key` of a variable |
``` ```
......
...@@ -10,7 +10,7 @@ GET /projects/:id/repository/commits ...@@ -10,7 +10,7 @@ GET /projects/:id/repository/commits
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME owned by the authenticated user | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| `ref_name` | string | no | The name of a repository branch or tag or if not given the default branch | | `ref_name` | string | no | The name of a repository branch or tag or if not given the default branch |
| `since` | string | no | Only commits after or on this date will be returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ | | `since` | string | no | Only commits after or on this date will be returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ |
| `until` | string | no | Only commits before or on this date will be returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ | | `until` | string | no | Only commits before or on this date will be returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ |
...@@ -68,7 +68,7 @@ POST /projects/:id/repository/commits ...@@ -68,7 +68,7 @@ POST /projects/:id/repository/commits
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `branch` | string | yes | The name of a branch | | `branch` | string | yes | The name of a branch |
| `commit_message` | string | yes | Commit message | | `commit_message` | string | yes | Commit message |
| `actions[]` | array | yes | An array of action hashes to commit as a batch. See the next table for what attributes it can take. | | `actions[]` | array | yes | An array of action hashes to commit as a batch. See the next table for what attributes it can take. |
...@@ -155,7 +155,7 @@ Parameters: ...@@ -155,7 +155,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME owned by the authenticated user | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| `sha` | string | yes | The commit hash or name of a repository branch or tag | | `sha` | string | yes | The commit hash or name of a repository branch or tag |
```bash ```bash
...@@ -203,7 +203,7 @@ Parameters: ...@@ -203,7 +203,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME owned by the authenticated user | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| `sha` | string | yes | The commit hash | | `sha` | string | yes | The commit hash |
| `branch` | string | yes | The name of the branch | | `branch` | string | yes | The name of the branch |
...@@ -245,7 +245,7 @@ Parameters: ...@@ -245,7 +245,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME owned by the authenticated user | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| `sha` | string | yes | The commit hash or name of a repository branch or tag | | `sha` | string | yes | The commit hash or name of a repository branch or tag |
```bash ```bash
...@@ -281,7 +281,7 @@ Parameters: ...@@ -281,7 +281,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME owned by the authenticated user | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| `sha` | string | yes | The commit hash or name of a repository branch or tag | | `sha` | string | yes | The commit hash or name of a repository branch or tag |
```bash ```bash
...@@ -330,7 +330,7 @@ POST /projects/:id/repository/commits/:sha/comments ...@@ -330,7 +330,7 @@ POST /projects/:id/repository/commits/:sha/comments
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME owned by the authenticated user | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| `sha` | string | yes | The commit SHA or name of a repository branch or tag | | `sha` | string | yes | The commit SHA or name of a repository branch or tag |
| `note` | string | yes | The text of the comment | | `note` | string | yes | The text of the comment |
| `path` | string | no | The file path relative to the repository | | `path` | string | no | The file path relative to the repository |
...@@ -375,7 +375,7 @@ GET /projects/:id/repository/commits/:sha/statuses ...@@ -375,7 +375,7 @@ GET /projects/:id/repository/commits/:sha/statuses
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME owned by the authenticated user | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| `sha` | string | yes | The commit SHA | `sha` | string | yes | The commit SHA
| `ref` | string | no | The name of a repository branch or tag or, if not given, the default branch | `ref` | string | no | The name of a repository branch or tag or, if not given, the default branch
| `stage` | string | no | Filter by [build stage](../ci/yaml/README.md#stages), e.g., `test` | `stage` | string | no | Filter by [build stage](../ci/yaml/README.md#stages), e.g., `test`
...@@ -449,7 +449,7 @@ POST /projects/:id/statuses/:sha ...@@ -449,7 +449,7 @@ POST /projects/:id/statuses/:sha
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME owned by the authenticated user | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| `sha` | string | yes | The commit SHA | `sha` | string | yes | The commit SHA
| `state` | string | yes | The state of the status. Can be one of the following: `pending`, `running`, `success`, `failed`, `canceled` | `state` | string | yes | The state of the status. Can be one of the following: `pending`, `running`, `success`, `failed`, `canceled`
| `ref` | string | no | The `ref` (branch or tag) to which the status refers | `ref` | string | no | The `ref` (branch or tag) to which the status refers
......
...@@ -43,7 +43,7 @@ GET /projects/:id/deploy_keys ...@@ -43,7 +43,7 @@ GET /projects/:id/deploy_keys
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/5/deploy_keys" curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/5/deploy_keys"
...@@ -82,7 +82,7 @@ Parameters: ...@@ -82,7 +82,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `key_id` | integer | yes | The ID of the deploy key | | `key_id` | integer | yes | The ID of the deploy key |
```bash ```bash
...@@ -114,7 +114,7 @@ POST /projects/:id/deploy_keys ...@@ -114,7 +114,7 @@ POST /projects/:id/deploy_keys
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `title` | string | yes | New deploy key's title | | `title` | string | yes | New deploy key's title |
| `key` | string | yes | New deploy key | | `key` | string | yes | New deploy key |
| `can_push` | boolean | no | Can deploy key push to the project's repository | | `can_push` | boolean | no | Can deploy key push to the project's repository |
...@@ -145,7 +145,7 @@ DELETE /projects/:id/deploy_keys/:key_id ...@@ -145,7 +145,7 @@ DELETE /projects/:id/deploy_keys/:key_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `key_id` | integer | yes | The ID of the deploy key | | `key_id` | integer | yes | The ID of the deploy key |
```bash ```bash
...@@ -162,7 +162,7 @@ curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitla ...@@ -162,7 +162,7 @@ curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitla
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `key_id` | integer | yes | The ID of the deploy key | | `key_id` | integer | yes | The ID of the deploy key |
Example response: Example response:
......
...@@ -10,7 +10,7 @@ GET /projects/:id/deployments ...@@ -10,7 +10,7 @@ GET /projects/:id/deployments
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/deployments" curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/deployments"
...@@ -147,7 +147,7 @@ GET /projects/:id/deployments/:deployment_id ...@@ -147,7 +147,7 @@ GET /projects/:id/deployments/:deployment_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `deployment_id` | integer | yes | The ID of the deployment | | `deployment_id` | integer | yes | The ID of the deployment |
```bash ```bash
......
...@@ -10,7 +10,7 @@ GET /projects/:id/environments ...@@ -10,7 +10,7 @@ GET /projects/:id/environments
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- | | --------- | ------- | -------- | --------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/1/environments curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/1/environments
...@@ -41,7 +41,7 @@ POST /projects/:id/environment ...@@ -41,7 +41,7 @@ POST /projects/:id/environment
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| ------------- | ------- | -------- | ---------------------------- | | ------------- | ------- | -------- | ---------------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the environment | | `name` | string | yes | The name of the environment |
| `external_url` | string | no | Place to link to for this environment | | `external_url` | string | no | Place to link to for this environment |
...@@ -72,7 +72,7 @@ PUT /projects/:id/environments/:environments_id ...@@ -72,7 +72,7 @@ PUT /projects/:id/environments/:environments_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------------- | ------- | --------------------------------- | ------------------------------- | | --------------- | ------- | --------------------------------- | ------------------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `environment_id` | integer | yes | The ID of the environment | The ID of the environment | | `environment_id` | integer | yes | The ID of the environment | The ID of the environment |
| `name` | string | no | The new name of the environment | | `name` | string | no | The new name of the environment |
| `external_url` | string | no | The new external_url | | `external_url` | string | no | The new external_url |
...@@ -102,7 +102,7 @@ DELETE /projects/:id/environments/:environment_id ...@@ -102,7 +102,7 @@ DELETE /projects/:id/environments/:environment_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- | | --------- | ------- | -------- | --------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `environment_id` | integer | yes | The ID of the environment | | `environment_id` | integer | yes | The ID of the environment |
```bash ```bash
...@@ -119,7 +119,7 @@ POST /projects/:id/environments/:environment_id/stop ...@@ -119,7 +119,7 @@ POST /projects/:id/environments/:environment_id/stop
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- | | --------- | ------- | -------- | --------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `environment_id` | integer | yes | The ID of the environment | | `environment_id` | integer | yes | The ID of the environment |
```bash ```bash
......
...@@ -53,7 +53,7 @@ Parameters: ...@@ -53,7 +53,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or path of a group | | `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `archived` | boolean | no | Limit by archived status | | `archived` | boolean | no | Limit by archived status |
| `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` | | `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
| `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` | | `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
...@@ -119,7 +119,7 @@ Parameters: ...@@ -119,7 +119,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or path of a group | | `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/4 curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/4
...@@ -301,7 +301,7 @@ POST /groups/:id/projects/:project_id ...@@ -301,7 +301,7 @@ POST /groups/:id/projects/:project_id
Parameters: Parameters:
- `id` (required) - The ID or path of a group - `id` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user
- `project_id` (required) - The ID or path of a project - `project_id` (required) - The ID or path of a project
## Update group ## Update group
......
This diff is collapsed.
...@@ -10,7 +10,7 @@ GET /projects/:id/jobs ...@@ -10,7 +10,7 @@ GET /projects/:id/jobs
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `scope` | string **or** array of strings | no | The scope of jobs to show, one or array of: `created`, `pending`, `running`, `failed`, `success`, `canceled`, `skipped`; showing all jobs if none provided | | `scope` | string **or** array of strings | no | The scope of jobs to show, one or array of: `created`, `pending`, `running`, `failed`, `success`, `canceled`, `skipped`; showing all jobs if none provided |
``` ```
...@@ -125,7 +125,7 @@ GET /projects/:id/pipeline/:pipeline_id/jobs ...@@ -125,7 +125,7 @@ GET /projects/:id/pipeline/:pipeline_id/jobs
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|---------------|--------------------------------|----------|----------------------| |---------------|--------------------------------|----------|----------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `pipeline_id` | integer | yes | The ID of a pipeline | | `pipeline_id` | integer | yes | The ID of a pipeline |
| `scope` | string **or** array of strings | no | The scope of jobs to show, one or array of: `created`, `pending`, `running`, `failed`, `success`, `canceled`, `skipped`; showing all jobs if none provided | | `scope` | string **or** array of strings | no | The scope of jobs to show, one or array of: `created`, `pending`, `running`, `failed`, `success`, `canceled`, `skipped`; showing all jobs if none provided |
...@@ -241,7 +241,7 @@ GET /projects/:id/jobs/:job_id ...@@ -241,7 +241,7 @@ GET /projects/:id/jobs/:job_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `job_id` | integer | yes | The ID of a job | | `job_id` | integer | yes | The ID of a job |
``` ```
...@@ -309,7 +309,7 @@ GET /projects/:id/jobs/:job_id/artifacts ...@@ -309,7 +309,7 @@ GET /projects/:id/jobs/:job_id/artifacts
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `job_id` | integer | yes | The ID of a job | | `job_id` | integer | yes | The ID of a job |
``` ```
...@@ -340,7 +340,7 @@ Parameters ...@@ -340,7 +340,7 @@ Parameters
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-------------|---------|----------|-------------------------- | |-------------|---------|----------|-------------------------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `ref_name` | string | yes | The ref from a repository | | `ref_name` | string | yes | The ref from a repository |
| `job` | string | yes | The name of the job | | `job` | string | yes | The name of the job |
...@@ -369,7 +369,7 @@ GET /projects/:id/jobs/:job_id/trace ...@@ -369,7 +369,7 @@ GET /projects/:id/jobs/:job_id/trace
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| id | integer | yes | The ID of a project | | id | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| job_id | integer | yes | The ID of a job | | job_id | integer | yes | The ID of a job |
``` ```
...@@ -393,7 +393,7 @@ POST /projects/:id/jobs/:job_id/cancel ...@@ -393,7 +393,7 @@ POST /projects/:id/jobs/:job_id/cancel
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `job_id` | integer | yes | The ID of a job | | `job_id` | integer | yes | The ID of a job |
``` ```
...@@ -439,7 +439,7 @@ POST /projects/:id/jobs/:job_id/retry ...@@ -439,7 +439,7 @@ POST /projects/:id/jobs/:job_id/retry
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `job_id` | integer | yes | The ID of a job | | `job_id` | integer | yes | The ID of a job |
``` ```
...@@ -487,7 +487,7 @@ Parameters ...@@ -487,7 +487,7 @@ Parameters
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-------------|---------|----------|---------------------| |-------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `job_id` | integer | yes | The ID of a job | | `job_id` | integer | yes | The ID of a job |
Example of request Example of request
...@@ -537,7 +537,7 @@ Parameters ...@@ -537,7 +537,7 @@ Parameters
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-------------|---------|----------|---------------------| |-------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `job_id` | integer | yes | The ID of a job | | `job_id` | integer | yes | The ID of a job |
Example request: Example request:
...@@ -585,7 +585,7 @@ POST /projects/:id/jobs/:job_id/play ...@@ -585,7 +585,7 @@ POST /projects/:id/jobs/:job_id/play
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `job_id` | integer | yes | The ID of a job | | `job_id` | integer | yes | The ID of a job |
``` ```
......
...@@ -10,7 +10,7 @@ GET /projects/:id/labels ...@@ -10,7 +10,7 @@ GET /projects/:id/labels
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- | | --------- | ------- | -------- | --------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/1/labels curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/1/labels
...@@ -88,7 +88,7 @@ POST /projects/:id/labels ...@@ -88,7 +88,7 @@ POST /projects/:id/labels
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| ------------- | ------- | -------- | ---------------------------- | | ------------- | ------- | -------- | ---------------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the label | | `name` | string | yes | The name of the label |
| `color` | string | yes | The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) | | `color` | string | yes | The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) |
| `description` | string | no | The description of the label | | `description` | string | no | The description of the label |
...@@ -124,7 +124,7 @@ DELETE /projects/:id/labels ...@@ -124,7 +124,7 @@ DELETE /projects/:id/labels
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- | | --------- | ------- | -------- | --------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the label | | `name` | string | yes | The name of the label |
```bash ```bash
...@@ -142,7 +142,7 @@ PUT /projects/:id/labels ...@@ -142,7 +142,7 @@ PUT /projects/:id/labels
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------------- | ------- | --------------------------------- | ------------------------------- | | --------------- | ------- | --------------------------------- | ------------------------------- |
| `id` | integer | yes | The ID of the project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the existing label | | `name` | string | yes | The name of the existing label |
| `new_name` | string | yes if `color` is not provided | The new name of the label | | `new_name` | string | yes if `color` is not provided | The new name of the label |
| `color` | string | yes if `new_name` is not provided | The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) | | `color` | string | yes if `new_name` is not provided | The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) |
...@@ -182,7 +182,7 @@ POST /projects/:id/labels/:label_id/subscribe ...@@ -182,7 +182,7 @@ POST /projects/:id/labels/:label_id/subscribe
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ | | ---------- | ----------------- | -------- | ------------------------------------ |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `label_id` | integer or string | yes | The ID or title of a project's label | | `label_id` | integer or string | yes | The ID or title of a project's label |
```bash ```bash
...@@ -217,7 +217,7 @@ POST /projects/:id/labels/:label_id/unsubscribe ...@@ -217,7 +217,7 @@ POST /projects/:id/labels/:label_id/unsubscribe
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ | | ---------- | ----------------- | -------- | ------------------------------------ |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `label_id` | integer or string | yes | The ID or title of a project's label | | `label_id` | integer or string | yes | The ID or title of a project's label |
```bash ```bash
......
...@@ -23,7 +23,7 @@ GET /projects/:id/members ...@@ -23,7 +23,7 @@ GET /projects/:id/members
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `query` | string | no | A query string to search for members | | `query` | string | no | A query string to search for members |
```bash ```bash
...@@ -65,7 +65,7 @@ GET /projects/:id/members/:user_id ...@@ -65,7 +65,7 @@ GET /projects/:id/members/:user_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the member | | `user_id` | integer | yes | The user ID of the member |
```bash ```bash
...@@ -98,7 +98,7 @@ POST /projects/:id/members ...@@ -98,7 +98,7 @@ POST /projects/:id/members
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the new member | | `user_id` | integer | yes | The user ID of the new member |
| `access_level` | integer | yes | A valid access level | | `access_level` | integer | yes | A valid access level |
| `expires_at` | string | no | A date string in the format YEAR-MONTH-DAY | | `expires_at` | string | no | A date string in the format YEAR-MONTH-DAY |
...@@ -132,7 +132,7 @@ PUT /projects/:id/members/:user_id ...@@ -132,7 +132,7 @@ PUT /projects/:id/members/:user_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the member | | `user_id` | integer | yes | The user ID of the member |
| `access_level` | integer | yes | A valid access level | | `access_level` | integer | yes | A valid access level |
| `expires_at` | string | no | A date string in the format YEAR-MONTH-DAY | | `expires_at` | string | no | A date string in the format YEAR-MONTH-DAY |
...@@ -166,7 +166,7 @@ DELETE /projects/:id/members/:user_id ...@@ -166,7 +166,7 @@ DELETE /projects/:id/members/:user_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The group/project ID or path | | `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the member | | `user_id` | integer | yes | The user ID of the member |
```bash ```bash
......
This diff is collapsed.
...@@ -17,7 +17,7 @@ Parameters: ...@@ -17,7 +17,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `iids` | Array[integer] | optional | Return only the milestones having the given `iids` | | `iids` | Array[integer] | optional | Return only the milestones having the given `iids` |
| `state` | string | optional | Return only `active` or `closed` milestones` | | `state` | string | optional | Return only `active` or `closed` milestones` |
| `search` | string | optional | Return only milestones with a title or description matching the provided string | | `search` | string | optional | Return only milestones with a title or description matching the provided string |
...@@ -56,8 +56,8 @@ GET /projects/:id/milestones/:milestone_id ...@@ -56,8 +56,8 @@ GET /projects/:id/milestones/:milestone_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `milestone_id` (required) - The ID of a project milestone - `milestone_id` (required) - The ID of the project's milestone
## Create new milestone ## Create new milestone
...@@ -69,7 +69,7 @@ POST /projects/:id/milestones ...@@ -69,7 +69,7 @@ POST /projects/:id/milestones
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `title` (required) - The title of an milestone - `title` (required) - The title of an milestone
- `description` (optional) - The description of the milestone - `description` (optional) - The description of the milestone
- `due_date` (optional) - The due date of the milestone - `due_date` (optional) - The due date of the milestone
...@@ -85,7 +85,7 @@ PUT /projects/:id/milestones/:milestone_id ...@@ -85,7 +85,7 @@ PUT /projects/:id/milestones/:milestone_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `milestone_id` (required) - The ID of a project milestone - `milestone_id` (required) - The ID of a project milestone
- `title` (optional) - The title of a milestone - `title` (optional) - The title of a milestone
- `description` (optional) - The description of a milestone - `description` (optional) - The description of a milestone
...@@ -103,7 +103,7 @@ GET /projects/:id/milestones/:milestone_id/issues ...@@ -103,7 +103,7 @@ GET /projects/:id/milestones/:milestone_id/issues
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `milestone_id` (required) - The ID of a project milestone - `milestone_id` (required) - The ID of a project milestone
## Get all merge requests assigned to a single milestone ## Get all merge requests assigned to a single milestone
...@@ -116,5 +116,5 @@ GET /projects/:id/milestones/:milestone_id/merge_requests ...@@ -116,5 +116,5 @@ GET /projects/:id/milestones/:milestone_id/merge_requests
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `milestone_id` (required) - The ID of a project milestone - `milestone_id` (required) - The ID of a project milestone
...@@ -14,7 +14,7 @@ GET /projects/:id/issues/:issue_iid/notes ...@@ -14,7 +14,7 @@ GET /projects/:id/issues/:issue_iid/notes
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `issue_iid` (required) - The IID of an issue - `issue_iid` (required) - The IID of an issue
```json ```json
...@@ -68,7 +68,7 @@ GET /projects/:id/issues/:issue_iid/notes/:note_id ...@@ -68,7 +68,7 @@ GET /projects/:id/issues/:issue_iid/notes/:note_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `issue_iid` (required) - The IID of a project issue - `issue_iid` (required) - The IID of a project issue
- `note_id` (required) - The ID of an issue note - `note_id` (required) - The ID of an issue note
...@@ -83,7 +83,7 @@ POST /projects/:id/issues/:issue_iid/notes ...@@ -83,7 +83,7 @@ POST /projects/:id/issues/:issue_iid/notes
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `issue_id` (required) - The IID of an issue - `issue_id` (required) - The IID of an issue
- `body` (required) - The content of a note - `body` (required) - The content of a note
- `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z - `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z
...@@ -98,7 +98,7 @@ PUT /projects/:id/issues/:issue_iid/notes/:note_id ...@@ -98,7 +98,7 @@ PUT /projects/:id/issues/:issue_iid/notes/:note_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `issue_iid` (required) - The IID of an issue - `issue_iid` (required) - The IID of an issue
- `note_id` (required) - The ID of a note - `note_id` (required) - The ID of a note
- `body` (required) - The content of a note - `body` (required) - The content of a note
...@@ -115,7 +115,7 @@ Parameters: ...@@ -115,7 +115,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The IID of an issue | | `issue_iid` | integer | yes | The IID of an issue |
| `note_id` | integer | yes | The ID of a note | | `note_id` | integer | yes | The ID of a note |
...@@ -135,7 +135,7 @@ GET /projects/:id/snippets/:snippet_id/notes ...@@ -135,7 +135,7 @@ GET /projects/:id/snippets/:snippet_id/notes
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `snippet_id` (required) - The ID of a project snippet - `snippet_id` (required) - The ID of a project snippet
### Get single snippet note ### Get single snippet note
...@@ -148,7 +148,7 @@ GET /projects/:id/snippets/:snippet_id/notes/:note_id ...@@ -148,7 +148,7 @@ GET /projects/:id/snippets/:snippet_id/notes/:note_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `snippet_id` (required) - The ID of a project snippet - `snippet_id` (required) - The ID of a project snippet
- `note_id` (required) - The ID of an snippet note - `note_id` (required) - The ID of an snippet note
...@@ -182,7 +182,7 @@ POST /projects/:id/snippets/:snippet_id/notes ...@@ -182,7 +182,7 @@ POST /projects/:id/snippets/:snippet_id/notes
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `snippet_id` (required) - The ID of a snippet - `snippet_id` (required) - The ID of a snippet
- `body` (required) - The content of a note - `body` (required) - The content of a note
...@@ -196,7 +196,7 @@ PUT /projects/:id/snippets/:snippet_id/notes/:note_id ...@@ -196,7 +196,7 @@ PUT /projects/:id/snippets/:snippet_id/notes/:note_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `snippet_id` (required) - The ID of a snippet - `snippet_id` (required) - The ID of a snippet
- `note_id` (required) - The ID of a note - `note_id` (required) - The ID of a note
- `body` (required) - The content of a note - `body` (required) - The content of a note
...@@ -213,7 +213,7 @@ Parameters: ...@@ -213,7 +213,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `snippet_id` | integer | yes | The ID of a snippet | | `snippet_id` | integer | yes | The ID of a snippet |
| `note_id` | integer | yes | The ID of a note | | `note_id` | integer | yes | The ID of a note |
...@@ -233,7 +233,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/notes ...@@ -233,7 +233,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/notes
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `merge_request_iid` (required) - The IID of a project merge request - `merge_request_iid` (required) - The IID of a project merge request
### Get single merge request note ### Get single merge request note
...@@ -246,7 +246,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/notes/:note_id ...@@ -246,7 +246,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/notes/:note_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `merge_request_iid` (required) - The IID of a project merge request - `merge_request_iid` (required) - The IID of a project merge request
- `note_id` (required) - The ID of a merge request note - `note_id` (required) - The ID of a merge request note
...@@ -283,7 +283,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/notes ...@@ -283,7 +283,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/notes
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `merge_request_iid` (required) - The IID of a merge request - `merge_request_iid` (required) - The IID of a merge request
- `body` (required) - The content of a note - `body` (required) - The content of a note
...@@ -297,7 +297,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid/notes/:note_id ...@@ -297,7 +297,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid/notes/:note_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `merge_request_iid` (required) - The IID of a merge request - `merge_request_iid` (required) - The IID of a merge request
- `note_id` (required) - The ID of a note - `note_id` (required) - The ID of a note
- `body` (required) - The content of a note - `body` (required) - The content of a note
...@@ -314,7 +314,7 @@ Parameters: ...@@ -314,7 +314,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `merge_request_iid` | integer | yes | The IID of a merge request | | `merge_request_iid` | integer | yes | The IID of a merge request |
| `note_id` | integer | yes | The ID of a note | | `note_id` | integer | yes | The ID of a note |
......
...@@ -12,7 +12,7 @@ GET /projects/:id/triggers ...@@ -12,7 +12,7 @@ GET /projects/:id/triggers
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
``` ```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/triggers" curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/triggers"
...@@ -43,7 +43,7 @@ GET /projects/:id/triggers/:trigger_id ...@@ -43,7 +43,7 @@ GET /projects/:id/triggers/:trigger_id
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|--------------|---------|----------|--------------------------| |--------------|---------|----------|--------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `trigger_id` | integer | yes | The trigger id | | `trigger_id` | integer | yes | The trigger id |
``` ```
...@@ -73,7 +73,7 @@ POST /projects/:id/triggers ...@@ -73,7 +73,7 @@ POST /projects/:id/triggers
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|---------------|---------|----------|--------------------------| |---------------|---------|----------|--------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `description` | string | yes | The trigger name | | `description` | string | yes | The trigger name |
``` ```
...@@ -103,7 +103,7 @@ PUT /projects/:id/triggers/:trigger_id ...@@ -103,7 +103,7 @@ PUT /projects/:id/triggers/:trigger_id
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|---------------|---------|----------|--------------------------| |---------------|---------|----------|--------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `trigger_id` | integer | yes | The trigger id | | `trigger_id` | integer | yes | The trigger id |
| `description` | string | no | The trigger name | | `description` | string | no | The trigger name |
...@@ -134,7 +134,7 @@ POST /projects/:id/triggers/:trigger_id/take_ownership ...@@ -134,7 +134,7 @@ POST /projects/:id/triggers/:trigger_id/take_ownership
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|---------------|---------|----------|--------------------------| |---------------|---------|----------|--------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `trigger_id` | integer | yes | The trigger id | | `trigger_id` | integer | yes | The trigger id |
``` ```
...@@ -164,7 +164,7 @@ DELETE /projects/:id/triggers/:trigger_id ...@@ -164,7 +164,7 @@ DELETE /projects/:id/triggers/:trigger_id
| Attribute | Type | required | Description | | Attribute | Type | required | Description |
|----------------|---------|----------|--------------------------| |----------------|---------|----------|--------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `trigger_id` | integer | yes | The trigger id | | `trigger_id` | integer | yes | The trigger id |
``` ```
......
...@@ -10,7 +10,7 @@ GET /projects/:id/pipelines ...@@ -10,7 +10,7 @@ GET /projects/:id/pipelines
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
``` ```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/pipelines" curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/pipelines"
...@@ -45,7 +45,7 @@ GET /projects/:id/pipelines/:pipeline_id ...@@ -45,7 +45,7 @@ GET /projects/:id/pipelines/:pipeline_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `pipeline_id` | integer | yes | The ID of a pipeline | | `pipeline_id` | integer | yes | The ID of a pipeline |
``` ```
...@@ -91,7 +91,7 @@ POST /projects/:id/pipeline ...@@ -91,7 +91,7 @@ POST /projects/:id/pipeline
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `ref` | string | yes | Reference to commit | | `ref` | string | yes | Reference to commit |
``` ```
...@@ -137,7 +137,7 @@ POST /projects/:id/pipelines/:pipeline_id/retry ...@@ -137,7 +137,7 @@ POST /projects/:id/pipelines/:pipeline_id/retry
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `pipeline_id` | integer | yes | The ID of a pipeline | | `pipeline_id` | integer | yes | The ID of a pipeline |
``` ```
...@@ -183,7 +183,7 @@ POST /projects/:id/pipelines/:pipeline_id/cancel ...@@ -183,7 +183,7 @@ POST /projects/:id/pipelines/:pipeline_id/cancel
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|------------|---------|----------|---------------------| |------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `pipeline_id` | integer | yes | The ID of a pipeline | | `pipeline_id` | integer | yes | The ID of a pipeline |
``` ```
......
...@@ -23,7 +23,7 @@ GET /projects/:id/snippets ...@@ -23,7 +23,7 @@ GET /projects/:id/snippets
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
## Single snippet ## Single snippet
...@@ -35,7 +35,7 @@ GET /projects/:id/snippets/:snippet_id ...@@ -35,7 +35,7 @@ GET /projects/:id/snippets/:snippet_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `snippet_id` (required) - The ID of a project's snippet - `snippet_id` (required) - The ID of a project's snippet
```json ```json
...@@ -67,7 +67,7 @@ POST /projects/:id/snippets ...@@ -67,7 +67,7 @@ POST /projects/:id/snippets
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `title` (required) - The title of a snippet - `title` (required) - The title of a snippet
- `file_name` (required) - The name of a snippet file - `file_name` (required) - The name of a snippet file
- `code` (required) - The content of a snippet - `code` (required) - The content of a snippet
...@@ -83,7 +83,7 @@ PUT /projects/:id/snippets/:snippet_id ...@@ -83,7 +83,7 @@ PUT /projects/:id/snippets/:snippet_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `snippet_id` (required) - The ID of a project's snippet - `snippet_id` (required) - The ID of a project's snippet
- `title` (optional) - The title of a snippet - `title` (optional) - The title of a snippet
- `file_name` (optional) - The name of a snippet file - `file_name` (optional) - The name of a snippet file
...@@ -101,7 +101,7 @@ DELETE /projects/:id/snippets/:snippet_id ...@@ -101,7 +101,7 @@ DELETE /projects/:id/snippets/:snippet_id
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `snippet_id` (required) - The ID of a project's snippet - `snippet_id` (required) - The ID of a project's snippet
## Snippet content ## Snippet content
...@@ -114,5 +114,5 @@ GET /projects/:id/snippets/:snippet_id/raw ...@@ -114,5 +114,5 @@ GET /projects/:id/snippets/:snippet_id/raw
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `snippet_id` (required) - The ID of a project's snippet - `snippet_id` (required) - The ID of a project's snippet
This diff is collapsed.
...@@ -13,7 +13,7 @@ GET /projects/:id/repository/tree ...@@ -13,7 +13,7 @@ GET /projects/:id/repository/tree
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `path` (optional) - The path inside repository. Used to get contend of subdirectories - `path` (optional) - The path inside repository. Used to get contend of subdirectories
- `ref` (optional) - The name of a repository branch or tag or if not given the default branch - `ref` (optional) - The name of a repository branch or tag or if not given the default branch
- `recursive` (optional) - Boolean value used to get a recursive tree (false by default) - `recursive` (optional) - Boolean value used to get a recursive tree (false by default)
...@@ -84,7 +84,7 @@ GET /projects/:id/repository/blobs/:sha ...@@ -84,7 +84,7 @@ GET /projects/:id/repository/blobs/:sha
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `sha` (required) - The commit or branch name - `sha` (required) - The commit or branch name
## Raw blob content ## Raw blob content
...@@ -98,7 +98,7 @@ GET /projects/:id/repository/blobs/:sha/raw ...@@ -98,7 +98,7 @@ GET /projects/:id/repository/blobs/:sha/raw
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `sha` (required) - The blob SHA - `sha` (required) - The blob SHA
## Get file archive ## Get file archive
...@@ -112,7 +112,7 @@ GET /projects/:id/repository/archive ...@@ -112,7 +112,7 @@ GET /projects/:id/repository/archive
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `sha` (optional) - The commit SHA to download defaults to the tip of the default branch - `sha` (optional) - The commit SHA to download defaults to the tip of the default branch
## Compare branches, tags or commits ## Compare branches, tags or commits
...@@ -126,7 +126,7 @@ GET /projects/:id/repository/compare ...@@ -126,7 +126,7 @@ GET /projects/:id/repository/compare
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `from` (required) - the commit SHA or branch name - `from` (required) - the commit SHA or branch name
- `to` (required) - the commit SHA or branch name - `to` (required) - the commit SHA or branch name
...@@ -181,7 +181,7 @@ GET /projects/:id/repository/contributors ...@@ -181,7 +181,7 @@ GET /projects/:id/repository/contributors
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
Response: Response:
......
...@@ -222,7 +222,7 @@ GET /projects/:id/runners ...@@ -222,7 +222,7 @@ GET /projects/:id/runners
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
``` ```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/9/runners" curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/9/runners"
...@@ -259,7 +259,7 @@ POST /projects/:id/runners ...@@ -259,7 +259,7 @@ POST /projects/:id/runners
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-------------|---------|----------|---------------------| |-------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `runner_id` | integer | yes | The ID of a runner | | `runner_id` | integer | yes | The ID of a runner |
``` ```
...@@ -290,7 +290,7 @@ DELETE /projects/:id/runners/:runner_id ...@@ -290,7 +290,7 @@ DELETE /projects/:id/runners/:runner_id
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-------------|---------|----------|---------------------| |-------------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `runner_id` | integer | yes | The ID of a runner | | `runner_id` | integer | yes | The ID of a runner |
``` ```
......
...@@ -12,7 +12,7 @@ GET /projects/:id/repository/tags ...@@ -12,7 +12,7 @@ GET /projects/:id/repository/tags
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
```json ```json
[ [
...@@ -53,7 +53,7 @@ Parameters: ...@@ -53,7 +53,7 @@ Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `tag_name` | string | yes | The name of the tag | | `tag_name` | string | yes | The name of the tag |
```bash ```bash
...@@ -93,7 +93,7 @@ POST /projects/:id/repository/tags ...@@ -93,7 +93,7 @@ POST /projects/:id/repository/tags
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `tag_name` (required) - The name of a tag - `tag_name` (required) - The name of a tag
- `ref` (required) - Create tag using commit SHA, another tag name, or branch name. - `ref` (required) - Create tag using commit SHA, another tag name, or branch name.
- `message` (optional) - Creates annotated tag. - `message` (optional) - Creates annotated tag.
...@@ -138,7 +138,7 @@ DELETE /projects/:id/repository/tags/:tag_name ...@@ -138,7 +138,7 @@ DELETE /projects/:id/repository/tags/:tag_name
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `tag_name` (required) - The name of a tag - `tag_name` (required) - The name of a tag
...@@ -153,7 +153,7 @@ POST /projects/:id/repository/tags/:tag_name/release ...@@ -153,7 +153,7 @@ POST /projects/:id/repository/tags/:tag_name/release
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `tag_name` (required) - The name of a tag - `tag_name` (required) - The name of a tag
- `description` (required) - Release notes with markdown support - `description` (required) - Release notes with markdown support
...@@ -174,7 +174,7 @@ PUT /projects/:id/repository/tags/:tag_name/release ...@@ -174,7 +174,7 @@ PUT /projects/:id/repository/tags/:tag_name/release
Parameters: Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `tag_name` (required) - The name of a tag - `tag_name` (required) - The name of a tag
- `description` (required) - Release notes with markdown support - `description` (required) - Release notes with markdown support
......
...@@ -250,6 +250,8 @@ Currently, this is what is synced: ...@@ -250,6 +250,8 @@ Currently, this is what is synced:
* Git repositories * Git repositories
* Wikis * Wikis
* LFS objects * LFS objects
* Issue, merge request, and comment attachments
* User, group, and project avatars
You can monitor the status of the syncing process on a secondary node You can monitor the status of the syncing process on a secondary node
by visiting the primary node's **Admin Area ➔ Geo Nodes** (`/admin/geo_nodes`) by visiting the primary node's **Admin Area ➔ Geo Nodes** (`/admin/geo_nodes`)
......
...@@ -12,12 +12,10 @@ manually [promote a secondary node](disaster-recovery.md) into primary. ...@@ -12,12 +12,10 @@ manually [promote a secondary node](disaster-recovery.md) into primary.
## What data is replicated to a secondary node? ## What data is replicated to a secondary node?
We currently replicate project repositories, LFS objects and the whole We currently replicate project repositories, LFS objects, generated
database. This means user accounts, issues, merge requests, groups, project attachments / avatars and the whole database. This means user accounts,
data, etc., will be available for query. issues, merge requests, groups, project data, etc., will be available for
We currently don't replicate user generated attachments / avatars or any query. We currently don't replicate artifact data (`shared/folder`).
other file in `public/upload`. We also don't replicate artifact data
data (`shared/folder`).
## Can I git push to a secondary node? ## Can I git push to a secondary node?
......
# Service Desk
> [Introduced][ee-149] in [GitLab Enterprise Edition Premium][ee] 9.1.
GitLab Service Desk is a simple way to allow people to create issues in your
GitLab instance without needing their own user account.
It provides a unique email address for end users to create issues in a project,
and replies can be sent either through the GitLab interface or by email. End
users will only see the thread through email.
## Configuring Service Desk
1. [Set up reply by email][reply-by-email] for the GitLab instance. This must
support [email sub-addressing][email-sub-addressing].
2. As an administrator user on your GitLab instance, go to a project's settings
page.
3. If you have the correct access and an Enterprise Edition Premium license,
you will see an option to set up Service Desk:
![Activate Service Desk option](img/service_desk_disabled.png)
4. Checking that box will enable Service Desk for the project, and show a
unique email address to email issues to the project. These issues will be
[confidential], so they will only be visible to project members.
**Warning**: as the screenshot below shows, this email address can be used
by anyone to create an issue on this project, whether or not they have
access to your GitLab instance. We recommend **putting this behind an
alias** so that it can be changed if needed, and
**[enabling Akismet][akismet]** on your GitLab instance to add spam
checking to this service.
![Service Desk enabled](img/service_desk_enabled.png)
5. Service Desk is now enabled for this project!
## Using Service Desk
### As an end user (issue creator)
To create a Service Desk issue, an end user doesn't need to know anything about
the GitLab instance. They just send an email to the address they are given, and
receive an email back confirming receipt:
![Service Desk enabled](img/service_desk_confirmation_email.png)
This also gives the end user an option to unsubscribe.
If they don't choose to unsubscribe, then any new comments added to the issue
will be sent as emails:
![Service Desk reply email](img/service_desk_reply.png)
And any responses they send will be displayed in the issue itself.
### As a responder to the issue
For responders to the issue, everything works as normal. Messages from the end
user will show as coming from the special Support Bot user, but apart from that,
you can read and write comments as normal:
![Service Desk issue thread](img/service_desk_thread.png)
[ee-149]: https://gitlab.com/gitlab-org/gitlab-ee/issues/149 "Service Desk with email"
[ee]: https://about.gitlab.com/gitlab-ee/ "GitLab Enterprise Edition landing page"
[reply-by-email]: ../../administration/reply_by_email.md#set-it-up
[email-sub-addressing]: ../../administration/reply_by_email.md#email-sub-addressing
[confidential]: ./issues/confidential_issues.md "Confidential issues"
[akismet]: ../../integration/akismet.md
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
- (EE) [Merge request approvals](../user/project/merge_requests/merge_request_approvals.md) - (EE) [Merge request approvals](../user/project/merge_requests/merge_request_approvals.md)
- (EE) [Fast-forward merge requests](../user/project/merge_requests/fast_forward_merge.md) - (EE) [Fast-forward merge requests](../user/project/merge_requests/fast_forward_merge.md)
- (EE) [Repository mirroring](repository_mirroring.md) - (EE) [Repository mirroring](repository_mirroring.md)
- (EE Premium) [Service Desk](../user/project/service_desk.md)
- [Manage large binaries with Git LFS](lfs/manage_large_binaries_with_git_lfs.md) - [Manage large binaries with Git LFS](lfs/manage_large_binaries_with_git_lfs.md)
- [Importing from SVN, GitHub, Bitbucket, etc](importing/README.md) - [Importing from SVN, GitHub, Bitbucket, etc](importing/README.md)
- [Todos](todos.md) - [Todos](todos.md)
......
...@@ -59,12 +59,12 @@ module API ...@@ -59,12 +59,12 @@ module API
::Users::ActivityService.new(actor, 'Git SSH').execute if commands.include?(params[:action]) ::Users::ActivityService.new(actor, 'Git SSH').execute if commands.include?(params[:action])
end end
def parse_allowed_environment_variables def parse_env
return if params[:env].blank? return {} if params[:env].blank?
JSON.parse(params[:env]) JSON.parse(params[:env])
rescue JSON::ParserError rescue JSON::ParserError
{}
end end
end end
end end
......
...@@ -11,14 +11,16 @@ module API ...@@ -11,14 +11,16 @@ module API
# Params: # Params:
# key_id - ssh key id for Git over SSH # key_id - ssh key id for Git over SSH
# user_id - user id for Git over HTTP # user_id - user id for Git over HTTP
# protocol - Git access protocol being used, e.g. HTTP or SSH
# project - project path with namespace # project - project path with namespace
# action - git action (git-upload-pack or git-receive-pack) # action - git action (git-upload-pack or git-receive-pack)
# ref - branch name # changes - changes as "oldrev newrev ref", see Gitlab::ChangesList
# forced_push - forced_push
# protocol - Git access protocol being used, e.g. HTTP or SSH
post "/allowed" do post "/allowed" do
status 200 status 200
# Stores some Git-specific env thread-safely
Gitlab::Git::Env.set(parse_env)
actor = actor =
if params[:key_id] if params[:key_id]
Key.find_by(id: params[:key_id]) Key.find_by(id: params[:key_id])
...@@ -30,18 +32,10 @@ module API ...@@ -30,18 +32,10 @@ module API
actor.update_last_used_at if actor.is_a?(Key) actor.update_last_used_at if actor.is_a?(Key)
access = access_checker = wiki? ? Gitlab::GitAccessWiki : Gitlab::GitAccess
if wiki? access_status = access_checker
Gitlab::GitAccessWiki.new(actor, project, protocol, authentication_abilities: ssh_authentication_abilities) .new(actor, project, protocol, authentication_abilities: ssh_authentication_abilities)
else .check(params[:action], params[:changes])
Gitlab::GitAccess.new(actor,
project,
protocol,
authentication_abilities: ssh_authentication_abilities,
env: parse_allowed_environment_variables)
end
access_status = access.check(params[:action], params[:changes])
response = { status: access_status.status, message: access_status.message } response = { status: access_status.status, message: access_status.message }
......
...@@ -7,7 +7,7 @@ module Gitlab ...@@ -7,7 +7,7 @@ module Gitlab
attr_reader :user_access, :project, :skip_authorization, :protocol attr_reader :user_access, :project, :skip_authorization, :protocol
def initialize( def initialize(
change, user_access:, project:, env: {}, skip_authorization: false, change, user_access:, project:, skip_authorization: false,
protocol: protocol:
) )
@oldrev, @newrev, @ref = change.values_at(:oldrev, :newrev, :ref) @oldrev, @newrev, @ref = change.values_at(:oldrev, :newrev, :ref)
...@@ -15,7 +15,6 @@ module Gitlab ...@@ -15,7 +15,6 @@ module Gitlab
@tag_name = Gitlab::Git.tag_name(@ref) @tag_name = Gitlab::Git.tag_name(@ref)
@user_access = user_access @user_access = user_access
@project = project @project = project
@env = env
@skip_authorization = skip_authorization @skip_authorization = skip_authorization
@protocol = protocol @protocol = protocol
end end
...@@ -99,7 +98,7 @@ module Gitlab ...@@ -99,7 +98,7 @@ module Gitlab
end end
def forced_push? def forced_push?
Gitlab::Checks::ForcePush.force_push?(@project, @oldrev, @newrev, env: @env) Gitlab::Checks::ForcePush.force_push?(@project, @oldrev, @newrev)
end end
def update? def update?
......
module Gitlab module Gitlab
module Checks module Checks
class ForcePush class ForcePush
def self.force_push?(project, oldrev, newrev, env: {}) def self.force_push?(project, oldrev, newrev)
return false if project.empty_repo? return false if project.empty_repo?
# Created or deleted branch # Created or deleted branch
if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev) if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev)
false false
else else
missed_ref, exit_status = Gitlab::Git::RevList.new(oldrev, newrev, project: project, env: env).execute Gitlab::Git::RevList.new(
path_to_repo: project.repository.path_to_repo,
if exit_status == 0 oldrev: oldrev, newrev: newrev).missed_ref.present?
missed_ref.present?
else
raise "Got a non-zero exit code while calling out to `git rev-list` in the force-push check."
end
end end
end end
end end
......
module Gitlab
module Git
# Ephemeral (per request) storage for environment variables that some Git
# commands may need.
#
# For example, in pre-receive hooks, new objects are put in a temporary
# $GIT_OBJECT_DIRECTORY. Without it set, the new objects cannot be retrieved
# (this would break push rules for instance).
#
# This class is thread-safe via RequestStore.
class Env
WHITELISTED_GIT_VARIABLES = %w[
GIT_OBJECT_DIRECTORY
GIT_ALTERNATE_OBJECT_DIRECTORIES
].freeze
def self.set(env)
return unless RequestStore.active?
RequestStore.store[:gitlab_git_env] = whitelist_git_env(env)
end
def self.all
return {} unless RequestStore.active?
RequestStore.fetch(:gitlab_git_env) { {} }
end
def self.[](key)
all[key]
end
def self.whitelist_git_env(env)
env.select { |key, _| WHITELISTED_GIT_VARIABLES.include?(key.to_s) }.with_indifferent_access
end
end
end
end
...@@ -8,6 +8,10 @@ module Gitlab ...@@ -8,6 +8,10 @@ module Gitlab
class Repository class Repository
include Gitlab::Git::Popen include Gitlab::Git::Popen
ALLOWED_OBJECT_DIRECTORIES_VARIABLES = %w[
GIT_OBJECT_DIRECTORY
GIT_ALTERNATE_OBJECT_DIRECTORIES
].freeze
SEARCH_CONTEXT_LINES = 3 SEARCH_CONTEXT_LINES = 3
NoRepository = Class.new(StandardError) NoRepository = Class.new(StandardError)
...@@ -58,7 +62,7 @@ module Gitlab ...@@ -58,7 +62,7 @@ module Gitlab
end end
def rugged def rugged
@rugged ||= Rugged::Repository.new(path) @rugged ||= Rugged::Repository.new(path, alternates: alternate_object_directories)
rescue Rugged::RepositoryError, Rugged::OSError rescue Rugged::RepositoryError, Rugged::OSError
raise NoRepository.new('no repository for such path') raise NoRepository.new('no repository for such path')
end end
...@@ -978,6 +982,10 @@ module Gitlab ...@@ -978,6 +982,10 @@ module Gitlab
private private
def alternate_object_directories
Gitlab::Git::Env.all.values_at(*ALLOWED_OBJECT_DIRECTORIES_VARIABLES).compact
end
# Get the content of a blob for a given commit. If the blob is a commit # Get the content of a blob for a given commit. If the blob is a commit
# (for submodules) then return the blob's OID. # (for submodules) then return the blob's OID.
def blob_content(commit, blob_name) def blob_content(commit, blob_name)
......
module Gitlab module Gitlab
module Git module Git
class RevList class RevList
attr_reader :project, :env attr_reader :oldrev, :newrev, :path_to_repo
ALLOWED_VARIABLES = %w[GIT_OBJECT_DIRECTORY GIT_ALTERNATE_OBJECT_DIRECTORIES].freeze def initialize(path_to_repo:, newrev:, oldrev: nil)
@oldrev = oldrev
def initialize(oldrev, newrev, project:, env: nil) @newrev = newrev
@project = project @path_to_repo = path_to_repo
@env = env.presence || {}
@args = [Gitlab.config.git.bin_path,
"--git-dir=#{project.repository.path_to_repo}",
"rev-list",
"--max-count=1",
oldrev,
"^#{newrev}"]
end end
def execute # This method returns an array of new references
Gitlab::Popen.popen(@args, nil, parse_environment_variables) def new_refs
execute([*base_args, newrev, '--not', '--all'])
end end
def valid? # This methods returns an array of missed references
environment_variables.all? do |(name, value)| def missed_ref
value.to_s.start_with?(project.repository.path_to_repo) execute([*base_args, '--max-count=1', oldrev, "^#{newrev}"])
end
end end
private private
def parse_environment_variables def execute(args)
return {} unless valid? output, status = Gitlab::Popen.popen(args, nil, Gitlab::Git::Env.all.stringify_keys)
unless status.zero?
raise "Got a non-zero exit code while calling out `#{args.join(' ')}`."
end
environment_variables output.split("\n")
end end
def environment_variables def base_args
@environment_variables ||= env.slice(*ALLOWED_VARIABLES).compact [
Gitlab.config.git.bin_path,
"--git-dir=#{path_to_repo}",
'rev-list'
]
end end
end end
end end
......
...@@ -20,13 +20,12 @@ module Gitlab ...@@ -20,13 +20,12 @@ module Gitlab
attr_reader :actor, :project, :protocol, :user_access, :authentication_abilities attr_reader :actor, :project, :protocol, :user_access, :authentication_abilities
def initialize(actor, project, protocol, authentication_abilities:, env: {}) def initialize(actor, project, protocol, authentication_abilities:)
@actor = actor @actor = actor
@project = project @project = project
@protocol = protocol @protocol = protocol
@authentication_abilities = authentication_abilities @authentication_abilities = authentication_abilities
@user_access = UserAccess.new(user, project: project) @user_access = UserAccess.new(user, project: project)
@env = env
end end
def check(cmd, changes) def check(cmd, changes)
...@@ -191,7 +190,6 @@ module Gitlab ...@@ -191,7 +190,6 @@ module Gitlab
change, change,
user_access: user_access, user_access: user_access,
project: project, project: project,
env: @env,
skip_authorization: deploy_key?, skip_authorization: deploy_key?,
protocol: protocol protocol: protocol
).exec ).exec
......
...@@ -5,7 +5,7 @@ describe 'Project settings > [EE] Merge Requests', feature: true, js: true do ...@@ -5,7 +5,7 @@ describe 'Project settings > [EE] Merge Requests', feature: true, js: true do
include WaitForAjax include WaitForAjax
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:empty_project) } let(:project) { create(:empty_project, approvals_before_merge: 1) }
let(:group) { create(:group) } let(:group) { create(:group) }
let(:approver) { create(:user) } let(:approver) { create(:user) }
...@@ -16,20 +16,42 @@ describe 'Project settings > [EE] Merge Requests', feature: true, js: true do ...@@ -16,20 +16,42 @@ describe 'Project settings > [EE] Merge Requests', feature: true, js: true do
group.add_developer(user) group.add_developer(user)
end end
scenario 'adds approver' do
visit edit_project_path(project)
find('#s2id_approver_user_and_group_ids .select2-input').click
wait_for_ajax
expect(find('.select2-results')).to have_content(user.name)
find('.user-result', text: user.name).click
click_button 'Add'
expect(find('.js-current-approvers')).to have_content(user.name)
end
scenario 'adds approver group' do scenario 'adds approver group' do
visit edit_project_path(project) visit edit_project_path(project)
find('#s2id_project_approver_group_ids .select2-input').click find('#s2id_approver_user_and_group_ids .select2-input').click
wait_for_ajax wait_for_ajax
expect(find('.select2-results')).to have_content(group.name) within('.js-current-approvers') do
expect(find('.panel-heading .badge')).to have_content('0')
end
find('.select2-results').click expect(find('.select2-results')).to have_content(group.name)
find('.select2-results .group-result').click
click_button 'Add'
click_button 'Save changes' expect(find('.approver-list-loader')).to be_visible
expect(page).to have_css('.js-current-approvers li.approver-group', count: 1)
expect(page).to have_css('.approver-list li.approver-group', count: 1) expect(page).to have_css('.js-current-approvers li.approver-group', count: 1)
within('.js-current-approvers') do
expect(find('.panel-heading .badge')).to have_content('2')
end
end end
context 'with an approver group' do context 'with an approver group' do
...@@ -40,13 +62,13 @@ describe 'Project settings > [EE] Merge Requests', feature: true, js: true do ...@@ -40,13 +62,13 @@ describe 'Project settings > [EE] Merge Requests', feature: true, js: true do
scenario 'removes approver group' do scenario 'removes approver group' do
visit edit_project_path(project) visit edit_project_path(project)
expect(find('.approver-list')).to have_content(group.name) expect(find('.js-current-approvers')).to have_content(group.name)
within('.approver-list') do within('.js-current-approvers') do
click_on "Remove" click_on "Remove"
end end
expect(find('.approver-list')).not_to have_content(group.name) expect(find('.js-current-approvers')).not_to have_content(group.name)
end end
end end
end end
...@@ -25,4 +25,13 @@ describe ProjectsController, '(JavaScript fixtures)', type: :controller do ...@@ -25,4 +25,13 @@ describe ProjectsController, '(JavaScript fixtures)', type: :controller do
expect(response).to be_success expect(response).to be_success
store_frontend_fixture(response, example.description) store_frontend_fixture(response, example.description)
end end
it 'projects/edit.html.raw' do |example|
get :edit,
namespace_id: project.namespace.to_param,
id: project
expect(response).to be_success
store_frontend_fixture(response, example.description)
end
end end
require('~/project_new');
describe('ApproversSelect', function () {
const projectSettingsTemplate = 'projects/edit.html.raw';
preloadFixtures(projectSettingsTemplate);
beforeEach(() => {
loadFixtures(projectSettingsTemplate);
this.$requireApprovalsToggle = $('.js-require-approvals-toggle');
this.project = new window.ProjectNew();
});
it('shows approver settings if enabled', () => {
expect(this.$requireApprovalsToggle).not.toBeChecked();
expect($('.nested-settings').hasClass('hidden')).toBe(true);
this.$requireApprovalsToggle.click();
expect($('.js-current-approvers').hasClass('hidden')).toBe(false);
});
it('hides approver settings if disabled', () => {
expect('#require_approvals').not.toBeChecked();
expect($('.nested-settings').hasClass('hidden')).toBe(true);
this.$requireApprovalsToggle.click();
this.$requireApprovalsToggle.click();
expect($('.nested-settings').hasClass('hidden')).toBe(true);
});
it('sets required approvers to 0 if approvers disabled', () => {
expect($('[name="project[approvals_before_merge]"]').val()).toBe('0');
});
it('sets required approvers to 1 if approvers enabled', () => {
this.$requireApprovalsToggle.click();
expect($('[name="project[approvals_before_merge]"]').val()).toBe('1');
});
it('sets minimum for approvers field if enabled', () => {
expect($('[name="project[approvals_before_merge]"]').attr('min')).toBe('0');
this.$requireApprovalsToggle.click();
expect($('[name="project[approvals_before_merge]"]').attr('min')).toBe('1');
});
});
require 'spec_helper'
describe Gitlab::Git::Env do
describe "#set" do
context 'with RequestStore.store disabled' do
before do
allow(RequestStore).to receive(:active?).and_return(false)
end
it 'does not store anything' do
described_class.set(GIT_OBJECT_DIRECTORY: 'foo')
expect(described_class.all).to be_empty
end
end
context 'with RequestStore.store enabled' do
before do
allow(RequestStore).to receive(:active?).and_return(true)
end
it 'whitelist some `GIT_*` variables and stores them using RequestStore' do
described_class.set(
GIT_OBJECT_DIRECTORY: 'foo',
GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar',
GIT_EXEC_PATH: 'baz',
PATH: '~/.bin:/bin')
expect(described_class[:GIT_OBJECT_DIRECTORY]).to eq('foo')
expect(described_class[:GIT_ALTERNATE_OBJECT_DIRECTORIES]).to eq('bar')
expect(described_class[:GIT_EXEC_PATH]).to be_nil
expect(described_class[:bar]).to be_nil
end
end
end
describe "#all" do
context 'with RequestStore.store enabled' do
before do
allow(RequestStore).to receive(:active?).and_return(true)
described_class.set(
GIT_OBJECT_DIRECTORY: 'foo',
GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar')
end
it 'returns an env hash' do
expect(described_class.all).to eq({
'GIT_OBJECT_DIRECTORY' => 'foo',
'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar'
})
end
end
end
describe "#[]" do
context 'with RequestStore.store enabled' do
before do
allow(RequestStore).to receive(:active?).and_return(true)
end
before do
described_class.set(
GIT_OBJECT_DIRECTORY: 'foo',
GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar')
end
it 'returns a stored value for an existing key' do
expect(described_class[:GIT_OBJECT_DIRECTORY]).to eq('foo')
end
it 'returns nil for an non-existing key' do
expect(described_class[:foo]).to be_nil
end
end
end
describe 'thread-safety' do
context 'with RequestStore.store enabled' do
before do
allow(RequestStore).to receive(:active?).and_return(true)
described_class.set(GIT_OBJECT_DIRECTORY: 'foo')
end
it 'is thread-safe' do
another_thread = Thread.new do
described_class.set(GIT_OBJECT_DIRECTORY: 'bar')
Thread.stop
described_class[:GIT_OBJECT_DIRECTORY]
end
# Ensure another_thread runs first
sleep 0.1 until another_thread.stop?
expect(described_class[:GIT_OBJECT_DIRECTORY]).to eq('foo')
another_thread.run
expect(another_thread.value).to eq('bar')
end
end
end
end
...@@ -40,6 +40,36 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -40,6 +40,36 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
end end
describe "#rugged" do
context 'with no Git env stored' do
before do
expect(Gitlab::Git::Env).to receive(:all).and_return({})
end
it "whitelist some variables and pass them via the alternates keyword argument" do
expect(Rugged::Repository).to receive(:new).with(repository.path, alternates: [])
repository.rugged
end
end
context 'with some Git env stored' do
before do
expect(Gitlab::Git::Env).to receive(:all).and_return({
'GIT_OBJECT_DIRECTORY' => 'foo',
'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar',
'GIT_OTHER' => 'another_env'
})
end
it "whitelist some variables and pass them via the alternates keyword argument" do
expect(Rugged::Repository).to receive(:new).with(repository.path, alternates: %w[foo bar])
repository.rugged
end
end
end
describe "#discover_default_branch" do describe "#discover_default_branch" do
let(:master) { 'master' } let(:master) { 'master' }
let(:feature) { 'feature' } let(:feature) { 'feature' }
......
...@@ -3,58 +3,54 @@ require 'spec_helper' ...@@ -3,58 +3,54 @@ require 'spec_helper'
describe Gitlab::Git::RevList, lib: true do describe Gitlab::Git::RevList, lib: true do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
context "validations" do before do
described_class::ALLOWED_VARIABLES.each do |var| expect(Gitlab::Git::Env).to receive(:all).and_return({
context var do GIT_OBJECT_DIRECTORY: 'foo',
it "accepts values starting with the project repo path" do GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar'
env = { var => "#{project.repository.path_to_repo}/objects" } })
rev_list = described_class.new('oldrev', 'newrev', project: project, env: env) end
expect(rev_list).to be_valid context "#new_refs" do
end let(:rev_list) { Gitlab::Git::RevList.new(newrev: 'newrev', path_to_repo: project.repository.path_to_repo) }
it "rejects values starting not with the project repo path" do it 'calls out to `popen`' do
env = { var => "/some/other/path" } expect(Gitlab::Popen).to receive(:popen).with([
rev_list = described_class.new('oldrev', 'newrev', project: project, env: env) Gitlab.config.git.bin_path,
"--git-dir=#{project.repository.path_to_repo}",
expect(rev_list).not_to be_valid 'rev-list',
end 'newrev',
'--not',
it "rejects values containing the project repo path but not starting with it" do '--all'
env = { var => "/some/other/path/#{project.repository.path_to_repo}" } ],
rev_list = described_class.new('oldrev', 'newrev', project: project, env: env) nil,
{
expect(rev_list).not_to be_valid 'GIT_OBJECT_DIRECTORY' => 'foo',
end 'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar'
}).and_return(["sha1\nsha2", 0])
it "ignores nil values" do
env = { var => nil } expect(rev_list.new_refs).to eq(%w[sha1 sha2])
rev_list = described_class.new('oldrev', 'newrev', project: project, env: env) end
end
expect(rev_list).to be_valid
end context "#missed_ref" do
end let(:rev_list) { Gitlab::Git::RevList.new(oldrev: 'oldrev', newrev: 'newrev', path_to_repo: project.repository.path_to_repo) }
end
end it 'calls out to `popen`' do
expect(Gitlab::Popen).to receive(:popen).with([
context "#execute" do Gitlab.config.git.bin_path,
let(:env) { { "GIT_OBJECT_DIRECTORY" => project.repository.path_to_repo } } "--git-dir=#{project.repository.path_to_repo}",
let(:rev_list) { Gitlab::Git::RevList.new('oldrev', 'newrev', project: project, env: env) } 'rev-list',
'--max-count=1',
it "calls out to `popen` without environment variables if the record is invalid" do 'oldrev',
allow(rev_list).to receive(:valid?).and_return(false) '^newrev'
],
expect(Open3).to receive(:popen3).with(hash_excluding(env), any_args) nil,
{
rev_list.execute 'GIT_OBJECT_DIRECTORY' => 'foo',
end 'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar'
}).and_return(["sha1\nsha2", 0])
it "calls out to `popen` with environment variables if the record is valid" do
allow(rev_list).to receive(:valid?).and_return(true) expect(rev_list.missed_ref).to eq(%w[sha1 sha2])
expect(Open3).to receive(:popen3).with(hash_including(env), any_args)
rev_list.execute
end end
end end
end end
...@@ -527,7 +527,7 @@ describe Gitlab::GitAccess, lib: true do ...@@ -527,7 +527,7 @@ describe Gitlab::GitAccess, lib: true do
before do before do
project.team << [user, :developer] project.team << [user, :developer]
allow_any_instance_of(Repository).to receive(:new_commits).and_return( allow(project.repository).to receive(:new_commits).and_return(
project.repository.commits_between('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d') project.repository.commits_between('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
) )
end end
...@@ -568,7 +568,7 @@ describe Gitlab::GitAccess, lib: true do ...@@ -568,7 +568,7 @@ describe Gitlab::GitAccess, lib: true do
bad_commit = double("Commit", safe_message: 'Some change').as_null_object bad_commit = double("Commit", safe_message: 'Some change').as_null_object
ref_object = double(name: 'heads/master') ref_object = double(name: 'heads/master')
allow(bad_commit).to receive(:refs).and_return([ref_object]) allow(bad_commit).to receive(:refs).and_return([ref_object])
allow_any_instance_of(Repository).to receive(:commits_between).and_return([bad_commit]) allow(project.repository).to receive(:commits_between).and_return([bad_commit])
project.create_push_rule project.create_push_rule
project.push_rule.update(commit_message_regex: "Change some files") project.push_rule.update(commit_message_regex: "Change some files")
...@@ -582,8 +582,8 @@ describe Gitlab::GitAccess, lib: true do ...@@ -582,8 +582,8 @@ describe Gitlab::GitAccess, lib: true do
# We use tmp ref a a temporary for Web UI commiting # We use tmp ref a a temporary for Web UI commiting
ref_object = double(name: 'refs/tmp') ref_object = double(name: 'refs/tmp')
allow(bad_commit).to receive(:refs).and_return([ref_object]) allow(bad_commit).to receive(:refs).and_return([ref_object])
allow_any_instance_of(Repository).to receive(:commits_between).and_return([bad_commit]) allow(project.repository).to receive(:commits_between).and_return([bad_commit])
allow_any_instance_of(Repository).to receive(:new_commits).and_return([bad_commit]) allow(project.repository).to receive(:new_commits).and_return([bad_commit])
project.create_push_rule project.create_push_rule
project.push_rule.update(commit_message_regex: "Change some files") project.push_rule.update(commit_message_regex: "Change some files")
...@@ -612,7 +612,7 @@ describe Gitlab::GitAccess, lib: true do ...@@ -612,7 +612,7 @@ describe Gitlab::GitAccess, lib: true do
describe "file names check" do describe "file names check" do
before do before do
allow_any_instance_of(Repository).to receive(:new_commits).and_return( allow(project.repository).to receive(:new_commits).and_return(
project.repository.commits_between('913c66a37b4a45b9769037c55c2d238bd0942d2e', '33f3729a45c02fc67d00adb1b8bca394b0e761d9') project.repository.commits_between('913c66a37b4a45b9769037c55c2d238bd0942d2e', '33f3729a45c02fc67d00adb1b8bca394b0e761d9')
) )
end end
......
require 'spec_helper'
describe EE::Repository, models: true do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
describe '#new_commits' do
let(:new_refs) do
double(:git_rev_list, new_refs: %w[
c1acaa58bbcbc3eafe538cb8274ba387047b69f8
5937ac0a7beb003549fc5fd26fc247adbce4a52e
])
end
it 'delegates to Gitlab::Git::RevList' do
expect(Gitlab::Git::RevList).to receive(:new).with(
path_to_repo: repository.path_to_repo,
newrev: 'aaaabbbbccccddddeeeeffffgggghhhhiiiijjjj').and_return(new_refs)
commits = repository.new_commits('aaaabbbbccccddddeeeeffffgggghhhhiiiijjjj')
expect(commits).to eq([
repository.commit('c1acaa58bbcbc3eafe538cb8274ba387047b69f8'),
repository.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e')
])
end
end
end
...@@ -206,6 +206,22 @@ describe API::Internal, api: true do ...@@ -206,6 +206,22 @@ describe API::Internal, api: true do
Timecop.return Timecop.return
end end
context 'with env passed as a JSON' do
it 'sets env in RequestStore' do
expect(Gitlab::Git::Env).to receive(:set).with({
'GIT_OBJECT_DIRECTORY' => 'foo',
'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar'
})
push(key, project.wiki, env: {
GIT_OBJECT_DIRECTORY: 'foo',
GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar'
}.to_json)
expect(response).to have_http_status(200)
end
end
context "git push with project.wiki" do context "git push with project.wiki" do
it 'responds with success' do it 'responds with success' do
push(key, project.wiki) push(key, project.wiki)
...@@ -524,7 +540,7 @@ describe API::Internal, api: true do ...@@ -524,7 +540,7 @@ describe API::Internal, api: true do
) )
end end
def push(key, project, protocol = 'ssh') def push(key, project, protocol = 'ssh', env: nil)
post( post(
api("/internal/allowed"), api("/internal/allowed"),
changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master', changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master',
...@@ -532,7 +548,8 @@ describe API::Internal, api: true do ...@@ -532,7 +548,8 @@ describe API::Internal, api: true do
project: project.repository.path_to_repo, project: project.repository.path_to_repo,
action: 'git-receive-pack', action: 'git-receive-pack',
secret_token: secret_token, secret_token: secret_token,
protocol: protocol protocol: protocol,
env: env
) )
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment