Merge remote-tracking branch 'upstream/master' into 27762-add-default-artifacts-expiration
* upstream/master: (37 commits) Show merge errors in merge request widget Clarify that stage is needed to stop environments Fix broken link in university docs allow clicking on text or icon to trigger expand style links on system notes to look clickable Clean up terms used for issues. Use New instead of Add. Fix most of broken docs links Set `Auto-Submitted: auto-generated` header to emails Fix Rubocop offense Fix regression where cmd-click stopped working for todos and merge request tabs Remove changelog entries for 8.16.5 release Merge branch 'fix-github-import-MR-wrong-project' into 'security' Merge branch 'svg-xss-fix' into 'security' Merge branch 'fix-rdoc-xss' into 'security' Merge branch 'asciidoctor-xss-patch' into 'security' Specify that only project owners can transfer a project only load istanbul plugin in development mode Make Karma output look nicer for CI (!9165) Centers loading icon vertically and horizontally in pipelines table in commit view Rename builds to jobs in docs ...
|
@ -20,7 +20,10 @@ $(() => {
|
|||
gl.commits.PipelinesTableBundle.$destroy(true);
|
||||
}
|
||||
|
||||
gl.commits.pipelines.PipelinesTableBundle = new gl.commits.pipelines.PipelinesTableView({
|
||||
el: document.querySelector('#commit-pipeline-table-view'),
|
||||
});
|
||||
const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
|
||||
gl.commits.pipelines.PipelinesTableBundle = new gl.commits.pipelines.PipelinesTableView();
|
||||
|
||||
if (pipelineTableViewEl && pipelineTableViewEl.dataset.disableInitialization === undefined) {
|
||||
gl.commits.pipelines.PipelinesTableBundle.$mount(pipelineTableViewEl);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -56,15 +56,14 @@ require('./pipelines_store');
|
|||
},
|
||||
|
||||
/**
|
||||
* When the component is created the service to fetch the data will be
|
||||
* initialized with the correct endpoint.
|
||||
* When the component is about to be mounted, tell the service to fetch the data
|
||||
*
|
||||
* A request to fetch the pipelines will be made.
|
||||
* In case of a successfull response we will store the data in the provided
|
||||
* store, in case of a failed response we need to warn the user.
|
||||
*
|
||||
*/
|
||||
created() {
|
||||
beforeMount() {
|
||||
const pipelinesService = new gl.commits.pipelines.PipelinesService(this.endpoint);
|
||||
|
||||
this.isLoading = true;
|
||||
|
@ -82,8 +81,8 @@ require('./pipelines_store');
|
|||
},
|
||||
|
||||
template: `
|
||||
<div>
|
||||
<div class="pipelines realtime-loading" v-if="isLoading">
|
||||
<div class="pipelines">
|
||||
<div class="realtime-loading" v-if="isLoading">
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
const calendar = new Pikaday({
|
||||
field: $dueDateInput.get(0),
|
||||
theme: 'gitlab-theme',
|
||||
format: 'YYYY-MM-DD',
|
||||
format: 'yyyy-mm-dd',
|
||||
onSelect: (dateText) => {
|
||||
const formattedDate = dateFormat(new Date(dateText), 'yyyy-mm-dd');
|
||||
|
||||
|
@ -63,6 +63,7 @@
|
|||
}
|
||||
});
|
||||
|
||||
calendar.setDate(new Date($dueDateInput.val()));
|
||||
this.$datePicker.append(calendar.el);
|
||||
this.$datePicker.data('pikaday', calendar);
|
||||
}
|
||||
|
@ -169,11 +170,12 @@
|
|||
const calendar = new Pikaday({
|
||||
field: $datePicker.get(0),
|
||||
theme: 'gitlab-theme',
|
||||
format: 'YYYY-MM-DD',
|
||||
format: 'yyyy-mm-dd',
|
||||
onSelect(dateText) {
|
||||
$datePicker.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
|
||||
}
|
||||
});
|
||||
calendar.setDate(new Date($datePicker.val()));
|
||||
|
||||
$datePicker.data('pikaday', calendar);
|
||||
});
|
||||
|
|
|
@ -40,11 +40,12 @@
|
|||
calendar = new Pikaday({
|
||||
field: $issuableDueDate.get(0),
|
||||
theme: 'gitlab-theme',
|
||||
format: 'YYYY-MM-DD',
|
||||
format: 'yyyy-mm-dd',
|
||||
onSelect: function(dateText) {
|
||||
$issuableDueDate.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
|
||||
}
|
||||
});
|
||||
calendar.setDate(new Date($issuableDueDate.val()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
const calendar = new Pikaday({
|
||||
field: $input.get(0),
|
||||
theme: 'gitlab-theme',
|
||||
format: 'YYYY-MM-DD',
|
||||
format: 'yyyy-mm-dd',
|
||||
minDate: new Date(),
|
||||
onSelect(dateText) {
|
||||
$input.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
|
||||
|
@ -30,6 +30,7 @@
|
|||
},
|
||||
});
|
||||
|
||||
calendar.setDate(new Date($input.val()));
|
||||
$input.data('pikaday', calendar);
|
||||
});
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ require('./flash');
|
|||
|
||||
constructor({ action, setUrl, stubLocation } = {}) {
|
||||
this.diffsLoaded = false;
|
||||
this.pipelinesLoaded = false;
|
||||
this.commitsLoaded = false;
|
||||
this.fixedLayoutPref = null;
|
||||
|
||||
|
@ -102,9 +103,10 @@ require('./flash');
|
|||
}
|
||||
|
||||
clickTab(e) {
|
||||
if (e.target && gl.utils.isMetaClick(e)) {
|
||||
const targetLink = e.target.getAttribute('href');
|
||||
if (e.currentTarget && gl.utils.isMetaClick(e)) {
|
||||
const targetLink = e.currentTarget.getAttribute('href');
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
window.open(targetLink, '_blank');
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +130,13 @@ require('./flash');
|
|||
$.scrollTo('.merge-request-details .merge-request-tabs', {
|
||||
offset: 0,
|
||||
});
|
||||
} else if (action === 'pipelines') {
|
||||
if (this.pipelinesLoaded) {
|
||||
return;
|
||||
}
|
||||
const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
|
||||
gl.commits.pipelines.PipelinesTableBundle.$mount(pipelineTableViewEl);
|
||||
this.pipelinesLoaded = true;
|
||||
} else {
|
||||
this.expandView();
|
||||
this.resetViewContainer();
|
||||
|
|
|
@ -110,7 +110,7 @@ require('./smart_interval');
|
|||
urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : '';
|
||||
return window.location.href = window.location.pathname + urlSuffix;
|
||||
} else if (data.merge_error) {
|
||||
return _this.$widgetBody.html("<h4>" + data.merge_error + "</h4>");
|
||||
return $('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>");
|
||||
} else {
|
||||
callback = function() {
|
||||
return merge_request_widget.mergeInProgress(deleteSourceBranch);
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
if (selected.id == null) {
|
||||
return selected.text;
|
||||
} else {
|
||||
return selected.kind + ": " + selected.path;
|
||||
return selected.kind + ": " + selected.full_path;
|
||||
}
|
||||
},
|
||||
data: function(term, dataCallback) {
|
||||
|
@ -50,7 +50,7 @@
|
|||
if (namespace.id == null) {
|
||||
return namespace.text;
|
||||
} else {
|
||||
return namespace.kind + ": " + namespace.path;
|
||||
return namespace.kind + ": " + namespace.full_path;
|
||||
}
|
||||
},
|
||||
renderRow: this.renderRow,
|
||||
|
|
|
@ -923,9 +923,10 @@ require('vendor/task_list');
|
|||
};
|
||||
|
||||
Notes.prototype.toggleCommitList = function(e) {
|
||||
const $element = $(e.target);
|
||||
const $element = $(e.currentTarget);
|
||||
const $closestSystemCommitList = $element.siblings('.system-note-commit-list');
|
||||
|
||||
$element.find('.fa').toggleClass('fa-angle-down').toggleClass('fa-angle-up');
|
||||
$closestSystemCommitList.toggleClass('hide-shade');
|
||||
};
|
||||
|
||||
|
|
|
@ -147,24 +147,21 @@
|
|||
|
||||
goToTodoUrl(e) {
|
||||
const todoLink = this.dataset.url;
|
||||
let targetLink = e.target.getAttribute('href');
|
||||
|
||||
if (e.target.tagName === 'IMG') { // See if clicked target was Avatar
|
||||
targetLink = e.target.parentElement.getAttribute('href'); // Parent of Avatar is link
|
||||
}
|
||||
|
||||
if (!todoLink) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gl.utils.isMetaClick(e)) {
|
||||
const windowTarget = '_blank';
|
||||
const selected = e.target;
|
||||
e.preventDefault();
|
||||
// Meta-Click on username leads to different URL than todoLink.
|
||||
// Turbolinks can resolve that URL, but window.open requires URL manually.
|
||||
if (targetLink !== todoLink) {
|
||||
return window.open(targetLink, '_blank');
|
||||
|
||||
if (selected.tagName === 'IMG') {
|
||||
const avatarUrl = selected.parentElement.getAttribute('href');
|
||||
return window.open(avatarUrl, windowTarget);
|
||||
} else {
|
||||
return window.open(todoLink, '_blank');
|
||||
return window.open(todoLink, windowTarget);
|
||||
}
|
||||
} else {
|
||||
return gl.utils.visitUrl(todoLink);
|
||||
|
|
|
@ -72,6 +72,7 @@ ul.notes {
|
|||
overflow: hidden;
|
||||
|
||||
.system-note-commit-list-toggler {
|
||||
color: $gl-link-color;
|
||||
display: none;
|
||||
padding: 10px 0 0;
|
||||
cursor: pointer;
|
||||
|
@ -107,16 +108,6 @@ ul.notes {
|
|||
display: none;
|
||||
}
|
||||
|
||||
p:last-child {
|
||||
a {
|
||||
color: $gl-text-color;
|
||||
|
||||
&:hover {
|
||||
color: $gl-link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 100%;
|
||||
|
|
|
@ -35,12 +35,8 @@
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.project-path {
|
||||
padding-right: 0;
|
||||
|
||||
.form-control {
|
||||
border-radius: $border-radius-base;
|
||||
}
|
||||
.project-path .form-control {
|
||||
border-radius: $border-radius-base;
|
||||
}
|
||||
|
||||
.input-group > div {
|
||||
|
|
|
@ -27,7 +27,7 @@ class Projects::TagsController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
result = CreateTagService.new(@project, current_user).
|
||||
result = Tags::CreateService.new(@project, current_user).
|
||||
execute(params[:tag_name], params[:ref], params[:message], params[:release_description])
|
||||
|
||||
if result[:status] == :success
|
||||
|
@ -41,7 +41,7 @@ class Projects::TagsController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
DeleteTagService.new(project, current_user).execute(params[:id])
|
||||
Tags::DestroyService.new(project, current_user).execute(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
|
|
|
@ -75,10 +75,10 @@ module MergeRequestsHelper
|
|||
new_namespace_project_merge_request_path(
|
||||
@project.namespace, @project,
|
||||
merge_request: {
|
||||
source_project_id: @merge_request.source_project_id,
|
||||
target_project_id: @merge_request.target_project_id,
|
||||
source_branch: @merge_request.source_branch,
|
||||
target_branch: @merge_request.target_branch,
|
||||
source_project_id: merge_request.source_project_id,
|
||||
target_project_id: merge_request.target_project_id,
|
||||
source_branch: merge_request.source_branch,
|
||||
target_branch: merge_request.target_branch,
|
||||
},
|
||||
change_branches: true
|
||||
)
|
||||
|
|
|
@ -10,7 +10,7 @@ module NamespacesHelper
|
|||
data_attr_users = { 'data-options-parent' => 'users' }
|
||||
|
||||
group_opts = [
|
||||
"Groups", groups.sort_by(&:human_name).map { |g| [display_path ? g.path : g.human_name, g.id, data_attr_group] }
|
||||
"Groups", groups.sort_by(&:human_name).map { |g| [display_path ? g.full_path : g.human_name, g.id, data_attr_group] }
|
||||
]
|
||||
|
||||
users_opts = [
|
||||
|
|
|
@ -63,7 +63,7 @@ module SubmoduleHelper
|
|||
namespace = components.pop.gsub(/^\.\.$/, '')
|
||||
|
||||
if namespace.empty?
|
||||
namespace = @project.namespace.path
|
||||
namespace = @project.namespace.full_path
|
||||
end
|
||||
|
||||
[
|
||||
|
|
|
@ -598,7 +598,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
|
||||
def source_project_namespace
|
||||
if source_project && source_project.namespace
|
||||
source_project.namespace.path
|
||||
source_project.namespace.full_path
|
||||
else
|
||||
"(removed)"
|
||||
end
|
||||
|
@ -606,7 +606,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
|
||||
def target_project_namespace
|
||||
if target_project && target_project.namespace
|
||||
target_project.namespace.path
|
||||
target_project.namespace.full_path
|
||||
else
|
||||
"(removed)"
|
||||
end
|
||||
|
|
|
@ -454,7 +454,7 @@ class Project < ActiveRecord::Base
|
|||
if forked?
|
||||
job_id = RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path,
|
||||
forked_from_project.path_with_namespace,
|
||||
self.namespace.path)
|
||||
self.namespace.full_path)
|
||||
else
|
||||
job_id = RepositoryImportWorker.perform_async(self.id)
|
||||
end
|
||||
|
@ -942,8 +942,8 @@ class Project < ActiveRecord::Base
|
|||
|
||||
Gitlab::AppLogger.info "Project was renamed: #{old_path_with_namespace} -> #{new_path_with_namespace}"
|
||||
|
||||
Gitlab::UploadsTransfer.new.rename_project(path_was, path, namespace.path)
|
||||
Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.path)
|
||||
Gitlab::UploadsTransfer.new.rename_project(path_was, path, namespace.full_path)
|
||||
Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.full_path)
|
||||
end
|
||||
|
||||
# Expires various caches before a project is renamed.
|
||||
|
@ -1150,19 +1150,25 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def pages_url
|
||||
subdomain, _, url_path = full_path.partition('/')
|
||||
|
||||
# The hostname always needs to be in downcased
|
||||
# All web servers convert hostname to lowercase
|
||||
host = "#{namespace.path}.#{Settings.pages.host}".downcase
|
||||
host = "#{subdomain}.#{Settings.pages.host}".downcase
|
||||
|
||||
# The host in URL always needs to be downcased
|
||||
url = Gitlab.config.pages.url.sub(/^https?:\/\//) do |prefix|
|
||||
"#{prefix}#{namespace.path}."
|
||||
"#{prefix}#{subdomain}."
|
||||
end.downcase
|
||||
|
||||
# If the project path is the same as host, we serve it as group page
|
||||
return url if host == path
|
||||
return url if host == url_path
|
||||
|
||||
"#{url}/#{path}"
|
||||
"#{url}/#{url_path}"
|
||||
end
|
||||
|
||||
def pages_subdomain
|
||||
full_path.partition('/').first
|
||||
end
|
||||
|
||||
def pages_path
|
||||
|
@ -1179,8 +1185,8 @@ class Project < ActiveRecord::Base
|
|||
# 3. We asynchronously remove pages with force
|
||||
temp_path = "#{path}.#{SecureRandom.hex}.deleted"
|
||||
|
||||
if Gitlab::PagesTransfer.new.rename_project(path, temp_path, namespace.path)
|
||||
PagesWorker.perform_in(5.minutes, :remove, namespace.path, temp_path)
|
||||
if Gitlab::PagesTransfer.new.rename_project(path, temp_path, namespace.full_path)
|
||||
PagesWorker.perform_in(5.minutes, :remove, namespace.full_path, temp_path)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1230,7 +1236,7 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def ensure_dir_exist
|
||||
gitlab_shell.add_namespace(repository_storage_path, namespace.path)
|
||||
gitlab_shell.add_namespace(repository_storage_path, namespace.full_path)
|
||||
end
|
||||
|
||||
def predefined_variables
|
||||
|
@ -1238,7 +1244,7 @@ class Project < ActiveRecord::Base
|
|||
{ key: 'CI_PROJECT_ID', value: id.to_s, public: true },
|
||||
{ key: 'CI_PROJECT_NAME', value: path, public: true },
|
||||
{ key: 'CI_PROJECT_PATH', value: path_with_namespace, public: true },
|
||||
{ key: 'CI_PROJECT_NAMESPACE', value: namespace.path, public: true },
|
||||
{ key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path, public: true },
|
||||
{ key: 'CI_PROJECT_URL', value: web_url, public: true }
|
||||
]
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ class DroneCiService < CiService
|
|||
def compose_service_hook
|
||||
hook = service_hook || build_service_hook
|
||||
# If using a service template, project may not be available
|
||||
hook.url = [drone_url, "/api/hook", "?owner=#{project.namespace.path}", "&name=#{project.path}", "&access_token=#{token}"].join if project
|
||||
hook.url = [drone_url, "/api/hook", "?owner=#{project.namespace.full_path}", "&name=#{project.path}", "&access_token=#{token}"].join if project
|
||||
hook.enable_ssl_verification = !!enable_ssl_verification
|
||||
hook.save
|
||||
end
|
||||
|
@ -38,7 +38,7 @@ class DroneCiService < CiService
|
|||
|
||||
def commit_status_path(sha, ref)
|
||||
url = [drone_url,
|
||||
"gitlab/#{project.namespace.path}/#{project.path}/commits/#{sha}",
|
||||
"gitlab/#{project.full_path}/commits/#{sha}",
|
||||
"?branch=#{URI::encode(ref.to_s)}&access_token=#{token}"]
|
||||
|
||||
URI.join(*url).to_s
|
||||
|
@ -73,7 +73,7 @@ class DroneCiService < CiService
|
|||
|
||||
def build_page(sha, ref)
|
||||
url = [drone_url,
|
||||
"gitlab/#{project.namespace.path}/#{project.path}/redirect/commits/#{sha}",
|
||||
"gitlab/#{project.full_path}/redirect/commits/#{sha}",
|
||||
"?branch=#{URI::encode(ref.to_s)}"]
|
||||
|
||||
URI.join(*url).to_s
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
# TODO(ayufan): The GitLabCiService is deprecated and the type should be removed when the database entries are removed
|
||||
class GitlabCiService < CiService
|
||||
# We override the active accessor to always make GitLabCiService disabled
|
||||
# Otherwise the GitLabCiService can be picked, but should never be since it's deprecated
|
||||
def active
|
||||
false
|
||||
end
|
||||
end
|
|
@ -27,7 +27,7 @@ class Service < ActiveRecord::Base
|
|||
|
||||
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
|
||||
|
||||
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
|
||||
scope :visible, -> { where.not(type: 'GitlabIssueTrackerService') }
|
||||
scope :issue_trackers, -> { where(category: 'issue_tracker') }
|
||||
scope :external_wikis, -> { where(type: 'ExternalWikiService').active }
|
||||
scope :active, -> { where(active: true) }
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
class CreateTagService < BaseService
|
||||
def execute(tag_name, target, message, release_description = nil)
|
||||
valid_tag = Gitlab::GitRefValidator.validate(tag_name)
|
||||
return error('Tag name invalid') unless valid_tag
|
||||
|
||||
repository = project.repository
|
||||
message&.strip!
|
||||
|
||||
new_tag = nil
|
||||
|
||||
begin
|
||||
new_tag = repository.add_tag(current_user, tag_name, target, message)
|
||||
rescue Rugged::TagError
|
||||
return error("Tag #{tag_name} already exists")
|
||||
rescue GitHooksService::PreReceiveError => ex
|
||||
return error(ex.message)
|
||||
end
|
||||
|
||||
if new_tag
|
||||
if release_description
|
||||
CreateReleaseService.new(@project, @current_user).
|
||||
execute(tag_name, release_description)
|
||||
end
|
||||
|
||||
success.merge(tag: new_tag)
|
||||
else
|
||||
error("Target #{target} is invalid")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,42 +0,0 @@
|
|||
class DeleteTagService < BaseService
|
||||
def execute(tag_name)
|
||||
repository = project.repository
|
||||
tag = repository.find_tag(tag_name)
|
||||
|
||||
unless tag
|
||||
return error('No such tag', 404)
|
||||
end
|
||||
|
||||
if repository.rm_tag(current_user, tag_name)
|
||||
release = project.releases.find_by(tag: tag_name)
|
||||
release&.destroy
|
||||
|
||||
push_data = build_push_data(tag)
|
||||
EventCreateService.new.push(project, current_user, push_data)
|
||||
project.execute_hooks(push_data.dup, :tag_push_hooks)
|
||||
project.execute_services(push_data.dup, :tag_push_hooks)
|
||||
|
||||
success('Tag was removed')
|
||||
else
|
||||
error('Failed to remove tag')
|
||||
end
|
||||
end
|
||||
|
||||
def error(message, return_code = 400)
|
||||
super(message).merge(return_code: return_code)
|
||||
end
|
||||
|
||||
def success(message)
|
||||
super().merge(message: message)
|
||||
end
|
||||
|
||||
def build_push_data(tag)
|
||||
Gitlab::DataBuilder::Push.build(
|
||||
project,
|
||||
current_user,
|
||||
tag.dereferenced_target.sha,
|
||||
Gitlab::Git::BLANK_SHA,
|
||||
"#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}",
|
||||
[])
|
||||
end
|
||||
end
|
|
@ -11,18 +11,20 @@ module MergeRequests
|
|||
def execute(merge_request)
|
||||
@merge_request = merge_request
|
||||
|
||||
return log_merge_error('Merge request is not mergeable', true) unless @merge_request.mergeable?
|
||||
unless @merge_request.mergeable?
|
||||
return log_merge_error('Merge request is not mergeable', save_message_on_model: true)
|
||||
end
|
||||
|
||||
@source = find_merge_source
|
||||
|
||||
return log_merge_error('No source for merge', true) unless @source
|
||||
unless @source
|
||||
log_merge_error('No source for merge', save_message_on_model: true)
|
||||
end
|
||||
|
||||
merge_request.in_locked_state do
|
||||
if commit
|
||||
after_merge
|
||||
success
|
||||
else
|
||||
log_merge_error('Can not merge changes', true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -43,11 +45,11 @@ module MergeRequests
|
|||
if commit_id
|
||||
merge_request.update(merge_commit_sha: commit_id)
|
||||
else
|
||||
merge_request.update(merge_error: 'Conflicts detected during merge')
|
||||
log_merge_error('Conflicts detected during merge', save_message_on_model: true)
|
||||
false
|
||||
end
|
||||
rescue GitHooksService::PreReceiveError => e
|
||||
merge_request.update(merge_error: e.message)
|
||||
log_merge_error(e.message, save_message_on_model: true)
|
||||
false
|
||||
rescue StandardError => e
|
||||
merge_request.update(merge_error: "Something went wrong during merge: #{e.message}")
|
||||
|
@ -70,10 +72,10 @@ module MergeRequests
|
|||
@merge_request.force_remove_source_branch? ? @merge_request.author : current_user
|
||||
end
|
||||
|
||||
def log_merge_error(message, http_error = false)
|
||||
def log_merge_error(message, save_message_on_model: false)
|
||||
Rails.logger.error("MergeService ERROR: #{merge_request_info} - #{message}")
|
||||
|
||||
error(message) if http_error
|
||||
@merge_request.update(merge_error: message) if save_message_on_model
|
||||
end
|
||||
|
||||
def merge_request_info
|
||||
|
|
|
@ -30,7 +30,7 @@ module Projects
|
|||
Project.transaction do
|
||||
old_path = project.path_with_namespace
|
||||
old_group = project.group
|
||||
new_path = File.join(new_namespace.try(:path) || '', project.path)
|
||||
new_path = File.join(new_namespace.try(:full_path) || '', project.path)
|
||||
|
||||
if Project.where(path: project.path, namespace_id: new_namespace.try(:id)).present?
|
||||
raise TransferError.new("Project with same path in target namespace already exists")
|
||||
|
@ -63,10 +63,10 @@ module Projects
|
|||
Labels::TransferService.new(current_user, old_group, project).execute
|
||||
|
||||
# Move uploads
|
||||
Gitlab::UploadsTransfer.new.move_project(project.path, old_namespace.path, new_namespace.path)
|
||||
Gitlab::UploadsTransfer.new.move_project(project.path, old_namespace.full_path, new_namespace.full_path)
|
||||
|
||||
# Move pages
|
||||
Gitlab::PagesTransfer.new.move_project(project.path, old_namespace.path, new_namespace.path)
|
||||
Gitlab::PagesTransfer.new.move_project(project.path, old_namespace.full_path, new_namespace.full_path)
|
||||
|
||||
project.old_path_with_namespace = old_path
|
||||
|
||||
|
|
32
app/services/tags/create_service.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
module Tags
|
||||
class CreateService < BaseService
|
||||
def execute(tag_name, target, message, release_description = nil)
|
||||
valid_tag = Gitlab::GitRefValidator.validate(tag_name)
|
||||
return error('Tag name invalid') unless valid_tag
|
||||
|
||||
repository = project.repository
|
||||
message&.strip!
|
||||
|
||||
new_tag = nil
|
||||
|
||||
begin
|
||||
new_tag = repository.add_tag(current_user, tag_name, target, message)
|
||||
rescue Rugged::TagError
|
||||
return error("Tag #{tag_name} already exists")
|
||||
rescue GitHooksService::PreReceiveError => ex
|
||||
return error(ex.message)
|
||||
end
|
||||
|
||||
if new_tag
|
||||
if release_description
|
||||
CreateReleaseService.new(@project, @current_user).
|
||||
execute(tag_name, release_description)
|
||||
end
|
||||
|
||||
success.merge(tag: new_tag)
|
||||
else
|
||||
error("Target #{target} is invalid")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
44
app/services/tags/destroy_service.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
module Tags
|
||||
class DestroyService < BaseService
|
||||
def execute(tag_name)
|
||||
repository = project.repository
|
||||
tag = repository.find_tag(tag_name)
|
||||
|
||||
unless tag
|
||||
return error('No such tag', 404)
|
||||
end
|
||||
|
||||
if repository.rm_tag(current_user, tag_name)
|
||||
release = project.releases.find_by(tag: tag_name)
|
||||
release&.destroy
|
||||
|
||||
push_data = build_push_data(tag)
|
||||
EventCreateService.new.push(project, current_user, push_data)
|
||||
project.execute_hooks(push_data.dup, :tag_push_hooks)
|
||||
project.execute_services(push_data.dup, :tag_push_hooks)
|
||||
|
||||
success('Tag was removed')
|
||||
else
|
||||
error('Failed to remove tag')
|
||||
end
|
||||
end
|
||||
|
||||
def error(message, return_code = 400)
|
||||
super(message).merge(return_code: return_code)
|
||||
end
|
||||
|
||||
def success(message)
|
||||
super().merge(message: message)
|
||||
end
|
||||
|
||||
def build_push_data(tag)
|
||||
Gitlab::DataBuilder::Push.build(
|
||||
project,
|
||||
current_user,
|
||||
tag.dereferenced_target.sha,
|
||||
Gitlab::Git::BLANK_SHA,
|
||||
"#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}",
|
||||
[])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -36,7 +36,7 @@ class FileUploader < GitlabUploader
|
|||
escaped_filename = filename.gsub("]", "\\]")
|
||||
|
||||
markdown = "[#{escaped_filename}](#{self.secure_url})"
|
||||
markdown.prepend("!") if image_or_video?
|
||||
markdown.prepend("!") if image_or_video? || dangerous?
|
||||
|
||||
{
|
||||
alt: filename,
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
# Extra methods for uploader
|
||||
module UploaderHelper
|
||||
IMAGE_EXT = %w[png jpg jpeg gif bmp tiff svg]
|
||||
IMAGE_EXT = %w[png jpg jpeg gif bmp tiff]
|
||||
# We recommend using the .mp4 format over .mov. Videos in .mov format can
|
||||
# still be used but you really need to make sure they are served with the
|
||||
# proper MIME type video/mp4 and not video/quicktime or your videos won't play
|
||||
# on IE >= 9.
|
||||
# http://archive.sublimevideo.info/20150912/docs.sublimevideo.net/troubleshooting.html
|
||||
VIDEO_EXT = %w[mp4 m4v mov webm ogv]
|
||||
# These extension types can contain dangerous code and should only be embedded inline with
|
||||
# proper filtering. They should always be tagged as "Content-Disposition: attachment", not "inline".
|
||||
DANGEROUS_EXT = %w[svg]
|
||||
|
||||
def image?
|
||||
extension_match?(IMAGE_EXT)
|
||||
|
@ -20,6 +23,10 @@ module UploaderHelper
|
|||
image? || video?
|
||||
end
|
||||
|
||||
def dangerous?
|
||||
extension_match?(DANGEROUS_EXT)
|
||||
end
|
||||
|
||||
def extension_match?(extensions)
|
||||
return false unless file
|
||||
|
||||
|
|
|
@ -163,6 +163,6 @@
|
|||
- @groups.each do |group|
|
||||
%p
|
||||
= link_to [:admin, group], class: 'str-truncated-60' do
|
||||
= group.name
|
||||
= group.full_name
|
||||
%span.light.pull-right
|
||||
#{time_ago_with_tooltip(group.created_at)}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
- toggle_text = 'Namespace'
|
||||
- if params[:namespace_id].present?
|
||||
- namespace = Namespace.find(params[:namespace_id])
|
||||
- toggle_text = "#{namespace.kind}: #{namespace.path}"
|
||||
- toggle_text = "#{namespace.kind}: #{namespace.full_path}"
|
||||
= dropdown_toggle(toggle_text, { toggle: 'dropdown' }, { toggle_class: 'js-namespace-select large' })
|
||||
.dropdown-menu.dropdown-select.dropdown-menu-align-right
|
||||
= dropdown_title('Namespaces')
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
%td
|
||||
#{runner.builds.count(:all)}
|
||||
%td
|
||||
- runner.tag_list.each do |tag|
|
||||
- runner.tag_list.sort.each do |tag|
|
||||
%span.label.label-primary
|
||||
= tag
|
||||
%td
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import_button = tr.find(".btn-import")
|
||||
origin_target = target_field.text()
|
||||
project_name = "#{@project_name}"
|
||||
origin_namespace = "#{@target_namespace.path}"
|
||||
origin_namespace = "#{@target_namespace.full_path}"
|
||||
target_field.empty()
|
||||
target_field.append("<p class='alert alert-danger'>This namespace has already been taken! Please choose another one.</p>")
|
||||
target_field.append("<input type='text' name='target_namespace' />")
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
new Pikaday({
|
||||
field: $dateField.get(0),
|
||||
theme: 'gitlab-theme',
|
||||
format: 'YYYY-MM-DD',
|
||||
format: 'yyyy-mm-dd',
|
||||
minDate: new Date(),
|
||||
onSelect: function(dateText) {
|
||||
$dateField.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
|
||||
|
|
|
@ -28,9 +28,11 @@
|
|||
.project-clone-holder
|
||||
= render "shared/clone_panel"
|
||||
|
||||
- if current_user && can?(current_user, :download_code, @project)
|
||||
= render 'projects/buttons/download', project: @project, ref: @ref
|
||||
= render 'projects/buttons/dropdown'
|
||||
- if current_user
|
||||
- if can?(current_user, :download_code, @project)
|
||||
= render 'projects/buttons/download', project: @project, ref: @ref
|
||||
= render 'projects/buttons/dropdown'
|
||||
= render 'projects/buttons/koding'
|
||||
|
||||
= render 'shared/notifications/button', notification_setting: @notification_setting
|
||||
= render 'projects/buttons/koding'
|
||||
= render 'shared/members/access_request_buttons', source: @project
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#commit-pipeline-table-view{ data: { endpoint: endpoint } }
|
||||
- disable_initialization = local_assigns.fetch(:disable_initialization, false)
|
||||
#commit-pipeline-table-view{ data: { disable_initialization: disable_initialization,
|
||||
endpoint: endpoint,
|
||||
} }
|
||||
.pipeline-svgs{ data: { "commit_icon_svg" => custom_icon("icon_commit"),
|
||||
"icon_status_canceled" => custom_icon("icon_status_canceled"),
|
||||
"icon_status_running" => custom_icon("icon_status_running"),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
.col-lg-9
|
||||
.project-edit-errors
|
||||
= form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit-project" }, authenticity_token: true do |f|
|
||||
%fieldset.append-bottom-0
|
||||
%fieldset
|
||||
.row
|
||||
.form-group.col-md-9
|
||||
= f.label :name, class: 'label-light', for: 'project_name_edit' do
|
||||
|
@ -33,7 +33,7 @@
|
|||
= f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control"
|
||||
%p.help-block Separate tags with commas.
|
||||
%hr
|
||||
%fieldset.append-bottom-0
|
||||
%fieldset
|
||||
%h5.prepend-top-0
|
||||
Sharing & Permissions
|
||||
.form_group.prepend-top-20.sharing-and-permissions
|
||||
|
@ -232,7 +232,7 @@
|
|||
.form-group
|
||||
.input-group
|
||||
.input-group-addon
|
||||
#{URI.join(root_url, @project.namespace.path)}/
|
||||
#{URI.join(root_url, @project.namespace.full_path)}/
|
||||
= f.text_field :path, class: 'form-control'
|
||||
%ul
|
||||
%li Be careful. Renaming a project's repository can have unintended side effects.
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
= icon("folder-open-o", class: "settings-list-icon")
|
||||
.pull-left
|
||||
= link_to group do
|
||||
= group.name
|
||||
= group.full_name
|
||||
%br
|
||||
up to #{group_link.human_access}
|
||||
- if group_link.expires?
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
-# This tab is always loaded via AJAX
|
||||
#pipelines.pipelines.tab-pane
|
||||
- if @pipelines.any?
|
||||
= render 'projects/commit/pipelines_list', endpoint: pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
|
||||
= render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
|
||||
#diffs.diffs.tab-pane
|
||||
-# This tab is always loaded via AJAX
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
Create or Import your project from popular Git services
|
||||
.col-lg-9
|
||||
= form_for @project, html: { class: 'new_project' } do |f|
|
||||
%fieldset.append-bottom-0
|
||||
.row
|
||||
.form-group.col-xs-12.col-sm-6
|
||||
= f.label :namespace_id, class: 'label-light' do
|
||||
%span
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
- supports_slash_commands = local_assigns.fetch(:supports_slash_commands, false)
|
||||
.comment-toolbar.clearfix
|
||||
.toolbar-text
|
||||
Styling with
|
||||
= link_to 'Markdown', help_page_path('user/markdown'), target: '_blank', tabindex: -1
|
||||
- if supports_slash_commands
|
||||
and
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
- if note.system
|
||||
.system-note-commit-list-toggler
|
||||
Toggle commit list
|
||||
%i.fa.fa-angle-down
|
||||
- if note.attachment.url
|
||||
.note-attachment
|
||||
- if note.attachment.image?
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
%p
|
||||
To access the domain create a new DNS record:
|
||||
%pre
|
||||
#{@domain.domain} CNAME #{@domain.project.namespace.path}.#{Settings.pages.host}.
|
||||
#{@domain.domain} CNAME #{@domain.project.pages_subdomain}.#{Settings.pages.host}.
|
||||
%tr
|
||||
%td
|
||||
Certificate
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
= label_tag :tag_list, class: 'control-label' do
|
||||
Tags
|
||||
.col-sm-10
|
||||
= f.text_field :tag_list, value: runner.tag_list.to_s, class: 'form-control'
|
||||
= f.text_field :tag_list, value: runner.tag_list.sort.join(', '), class: 'form-control'
|
||||
.help-block You can setup jobs to only use Runners with specific tags
|
||||
.form-actions
|
||||
= f.submit 'Save changes', class: 'btn btn-save'
|
||||
|
|
|
@ -31,6 +31,6 @@
|
|||
= runner.description
|
||||
- if runner.tag_list.present?
|
||||
%p
|
||||
- runner.tag_list.each do |tag|
|
||||
- runner.tag_list.sort.each do |tag|
|
||||
%span.label.label-primary
|
||||
= tag
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
%tr
|
||||
%td Tags
|
||||
%td
|
||||
- @runner.tag_list.each do |tag|
|
||||
- @runner.tag_list.sort.each do |tag|
|
||||
%span.label.label-primary
|
||||
= tag
|
||||
%tr
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
%span.list-item-name
|
||||
= image_tag group_icon(group), class: "avatar s40", alt: ''
|
||||
%strong
|
||||
= link_to group.name, group_path(group)
|
||||
= link_to group.full_name, group_path(group)
|
||||
.cgray
|
||||
Joined #{time_ago_with_tooltip(group.created_at)}
|
||||
- if group_link.expires?
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Specify in the documentation that only projects owners can transfer projects
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix regression where cmd-click stopped working for todos and merge request
|
||||
tabs
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Fix stray pipelines API request when showing MR
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Show merge errors in merge request widget
|
||||
merge_request: 9229
|
||||
author:
|
5
changelogs/unreleased/28229-pipelines-loading-icon.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Centers loading icon vertically and horizontally in pipelines table in commit
|
||||
view
|
||||
merge_request:
|
||||
author:
|
4
changelogs/unreleased/add-auto-submited-header.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Set Auto-Submitted header to mails
|
||||
merge_request:
|
||||
author: Semyon Pupkov
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Alphabetically sort tags on runner list
|
||||
merge_request: 8922
|
||||
author: blackst0ne
|
4
changelogs/unreleased/api-entities.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: "Use an entity for RepoBranch commits and enhance RepoCommit"
|
||||
merge_request: 7138
|
||||
author: Ben Boeckel
|
4
changelogs/unreleased/beautiful-karma-output.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Make Karma output look nicer for CI
|
||||
merge_request: 9165
|
||||
author: winniehell
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Show notifications settings dropdown even if repository feature is disabled
|
||||
merge_request: 9180
|
||||
author:
|
4
changelogs/unreleased/issue_25112.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Disable invalid service templates
|
||||
merge_request:
|
||||
author:
|
4
changelogs/unreleased/move_tags_service_to_namespace.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Move tag services to Tags namespace
|
||||
merge_request:
|
||||
author: dixpac
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Make it possible to pass coverage value to commit status API
|
||||
merge_request: 9214
|
||||
author: wendy0402
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Remove deprecated GitlabCiService
|
||||
merge_request:
|
||||
author:
|
1
config/initializers/additional_headers_interceptor.rb
Normal file
|
@ -0,0 +1 @@
|
|||
ActionMailer::Base.register_interceptor(AdditionalEmailHeadersInterceptor)
|
|
@ -4,6 +4,7 @@ var ROOT_PATH = path.resolve(__dirname, '..');
|
|||
|
||||
// Karma configuration
|
||||
module.exports = function(config) {
|
||||
var progressReporter = process.env.CI ? 'mocha' : 'progress';
|
||||
config.set({
|
||||
basePath: ROOT_PATH,
|
||||
browsers: ['PhantomJS'],
|
||||
|
@ -15,7 +16,7 @@ module.exports = function(config) {
|
|||
preprocessors: {
|
||||
'spec/javascripts/**/*.js?(.es6)': ['webpack', 'sourcemap'],
|
||||
},
|
||||
reporters: ['progress', 'coverage-istanbul'],
|
||||
reporters: [progressReporter, 'coverage-istanbul'],
|
||||
coverageIstanbulReporter: {
|
||||
reports: ['html', 'text-summary'],
|
||||
dir: 'coverage-javascript/',
|
||||
|
|
|
@ -54,7 +54,7 @@ var config = {
|
|||
exclude: /(node_modules|vendor\/assets)/,
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
plugins: ['istanbul'],
|
||||
plugins: IS_PRODUCTION ? [] : ['istanbul'],
|
||||
presets: [
|
||||
["es2015", {"modules": false}],
|
||||
'stage-2'
|
||||
|
@ -83,6 +83,7 @@ var config = {
|
|||
new CompressionPlugin({
|
||||
asset: '[path].gz[query]',
|
||||
}),
|
||||
new webpack.IgnorePlugin(/moment/, /pikaday/),
|
||||
],
|
||||
|
||||
resolve: {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
class DisableInvalidServiceTemplates < ActiveRecord::Migration
|
||||
DOWNTIME = false
|
||||
|
||||
unless defined?(Service)
|
||||
class Service < ActiveRecord::Base
|
||||
self.inheritance_column = nil
|
||||
end
|
||||
end
|
||||
|
||||
def up
|
||||
Service.where(template: true, active: true).each do |template|
|
||||
template.update(active: false) unless template.valid?
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
class DeleteDeprecatedGitlabCiService < ActiveRecord::Migration
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
disable_statement_timeout
|
||||
|
||||
execute("DELETE FROM services WHERE type = 'GitlabCiService';")
|
||||
end
|
||||
|
||||
def down
|
||||
# noop
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20170210075922) do
|
||||
ActiveRecord::Schema.define(version: 20170214111112) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -1351,4 +1351,4 @@ ActiveRecord::Schema.define(version: 20170210075922) do
|
|||
add_foreign_key "timelogs", "merge_requests", name: "fk_timelogs_merge_requests_merge_request_id", on_delete: :cascade
|
||||
add_foreign_key "trending_projects", "projects", on_delete: :cascade
|
||||
add_foreign_key "u2f_registrations", "users"
|
||||
end
|
||||
end
|
|
@ -1,96 +1 @@
|
|||
# Build artifacts administration
|
||||
|
||||
>**Notes:**
|
||||
>- Introduced in GitLab 8.2 and GitLab Runner 0.7.0.
|
||||
>- Starting from GitLab 8.4 and GitLab Runner 1.0, the artifacts archive format
|
||||
changed to `ZIP`.
|
||||
>- This is the administration documentation. For the user guide see
|
||||
[user/project/builds/artifacts.md](../user/project/builds/artifacts.md).
|
||||
|
||||
Artifacts is a list of files and directories which are attached to a build
|
||||
after it completes successfully. This feature is enabled by default in all
|
||||
GitLab installations. Keep reading if you want to know how to disable it.
|
||||
|
||||
## Disabling build artifacts
|
||||
|
||||
To disable artifacts site-wide, follow the steps below.
|
||||
|
||||
---
|
||||
|
||||
**In Omnibus installations:**
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb` and add the following line:
|
||||
|
||||
```ruby
|
||||
gitlab_rails['artifacts_enabled'] = false
|
||||
```
|
||||
|
||||
1. Save the file and [reconfigure GitLab][] for the changes to take effect.
|
||||
|
||||
---
|
||||
|
||||
**In installations from source:**
|
||||
|
||||
1. Edit `/home/git/gitlab/config/gitlab.yml` and add or amend the following lines:
|
||||
|
||||
```yaml
|
||||
artifacts:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
1. Save the file and [restart GitLab][] for the changes to take effect.
|
||||
|
||||
## Storing build artifacts
|
||||
|
||||
After a successful build, GitLab Runner uploads an archive containing the build
|
||||
artifacts to GitLab.
|
||||
|
||||
To change the location where the artifacts are stored, follow the steps below.
|
||||
|
||||
---
|
||||
|
||||
**In Omnibus installations:**
|
||||
|
||||
_The artifacts are stored by default in
|
||||
`/var/opt/gitlab/gitlab-rails/shared/artifacts`._
|
||||
|
||||
1. To change the storage path for example to `/mnt/storage/artifacts`, edit
|
||||
`/etc/gitlab/gitlab.rb` and add the following line:
|
||||
|
||||
```ruby
|
||||
gitlab_rails['artifacts_path'] = "/mnt/storage/artifacts"
|
||||
```
|
||||
|
||||
1. Save the file and [reconfigure GitLab][] for the changes to take effect.
|
||||
|
||||
---
|
||||
|
||||
**In installations from source:**
|
||||
|
||||
_The artifacts are stored by default in
|
||||
`/home/git/gitlab/shared/artifacts`._
|
||||
|
||||
1. To change the storage path for example to `/mnt/storage/artifacts`, edit
|
||||
`/home/git/gitlab/config/gitlab.yml` and add or amend the following lines:
|
||||
|
||||
```yaml
|
||||
artifacts:
|
||||
enabled: true
|
||||
path: /mnt/storage/artifacts
|
||||
```
|
||||
|
||||
1. Save the file and [restart GitLab][] for the changes to take effect.
|
||||
|
||||
## Set the maximum file size of the artifacts
|
||||
|
||||
Provided the artifacts are enabled, you can change the maximum file size of the
|
||||
artifacts through the [Admin area settings](../user/admin_area/settings/continuous_integration.md#maximum-artifacts-size).
|
||||
|
||||
[reconfigure gitlab]: restart_gitlab.md "How to restart GitLab"
|
||||
[restart gitlab]: restart_gitlab.md "How to restart GitLab"
|
||||
|
||||
## Storage statistics
|
||||
|
||||
You can see the total storage used for build artifacts on groups and projects
|
||||
in the administration area, as well as through the [groups](../api/groups.md)
|
||||
and [projects APIs](../api/projects.md).
|
||||
This document was moved to [job_artifacts](job_artifacts.md).
|
||||
|
|
114
doc/administration/job_artifacts.md
Normal file
|
@ -0,0 +1,114 @@
|
|||
# Jobs artifacts administration
|
||||
|
||||
>**Notes:**
|
||||
>- Introduced in GitLab 8.2 and GitLab Runner 0.7.0.
|
||||
>- Starting with GitLab 8.4 and GitLab Runner 1.0, the artifacts archive format
|
||||
changed to `ZIP`.
|
||||
>- Starting with GitLab 8.17, builds are renamed to jobs.
|
||||
>- This is the administration documentation. For the user guide see
|
||||
[pipelines/job_artifacts](../user/project/pipelines/job_artifacts.md).
|
||||
|
||||
Artifacts is a list of files and directories which are attached to a job
|
||||
after it completes successfully. This feature is enabled by default in all
|
||||
GitLab installations. Keep reading if you want to know how to disable it.
|
||||
|
||||
## Disabling job artifacts
|
||||
|
||||
To disable artifacts site-wide, follow the steps below.
|
||||
|
||||
---
|
||||
|
||||
**In Omnibus installations:**
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb` and add the following line:
|
||||
|
||||
```ruby
|
||||
gitlab_rails['artifacts_enabled'] = false
|
||||
```
|
||||
|
||||
1. Save the file and [reconfigure GitLab][] for the changes to take effect.
|
||||
|
||||
---
|
||||
|
||||
**In installations from source:**
|
||||
|
||||
1. Edit `/home/git/gitlab/config/gitlab.yml` and add or amend the following lines:
|
||||
|
||||
```yaml
|
||||
artifacts:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
1. Save the file and [restart GitLab][] for the changes to take effect.
|
||||
|
||||
## Storing job artifacts
|
||||
|
||||
After a successful job, GitLab Runner uploads an archive containing the job
|
||||
artifacts to GitLab.
|
||||
|
||||
To change the location where the artifacts are stored, follow the steps below.
|
||||
|
||||
---
|
||||
|
||||
**In Omnibus installations:**
|
||||
|
||||
_The artifacts are stored by default in
|
||||
`/var/opt/gitlab/gitlab-rails/shared/artifacts`._
|
||||
|
||||
1. To change the storage path for example to `/mnt/storage/artifacts`, edit
|
||||
`/etc/gitlab/gitlab.rb` and add the following line:
|
||||
|
||||
```ruby
|
||||
gitlab_rails['artifacts_path'] = "/mnt/storage/artifacts"
|
||||
```
|
||||
|
||||
1. Save the file and [reconfigure GitLab][] for the changes to take effect.
|
||||
|
||||
---
|
||||
|
||||
**In installations from source:**
|
||||
|
||||
_The artifacts are stored by default in
|
||||
`/home/git/gitlab/shared/artifacts`._
|
||||
|
||||
1. To change the storage path for example to `/mnt/storage/artifacts`, edit
|
||||
`/home/git/gitlab/config/gitlab.yml` and add or amend the following lines:
|
||||
|
||||
```yaml
|
||||
artifacts:
|
||||
enabled: true
|
||||
path: /mnt/storage/artifacts
|
||||
```
|
||||
|
||||
1. Save the file and [restart GitLab][] for the changes to take effect.
|
||||
|
||||
## Set the maximum file size of the artifacts
|
||||
|
||||
Provided the artifacts are enabled, you can change the maximum file size of the
|
||||
artifacts through the [Admin area settings](../user/admin_area/settings/continuous_integration.md#maximum-artifacts-size).
|
||||
|
||||
## Storage statistics
|
||||
|
||||
You can see the total storage used for job artifacts on groups and projects
|
||||
in the administration area, as well as through the [groups](../api/groups.md)
|
||||
and [projects APIs](../api/projects.md).
|
||||
|
||||
## Implementation details
|
||||
|
||||
When GitLab receives an artifacts archive, an archive metadata file is also
|
||||
generated. This metadata file describes all the entries that are located in the
|
||||
artifacts archive itself. The metadata file is in a binary format, with
|
||||
additional GZIP compression.
|
||||
|
||||
GitLab does not extract the artifacts archive in order to save space, memory
|
||||
and disk I/O. It instead inspects the metadata file which contains all the
|
||||
relevant information. This is especially important when there is a lot of
|
||||
artifacts, or an archive is a very large file.
|
||||
|
||||
When clicking on a specific file, [GitLab Workhorse] extracts it
|
||||
from the archive and the download begins. This implementation saves space,
|
||||
memory and disk I/O.
|
||||
|
||||
[reconfigure gitlab]: restart_gitlab.md "How to restart GitLab"
|
||||
[restart gitlab]: restart_gitlab.md "How to restart GitLab"
|
||||
[gitlab workhorse]: https://gitlab.com/gitlab-org/gitlab-workhorse "GitLab Workhorse repository"
|
|
@ -54,7 +54,7 @@ Before proceeding with the Pages configuration, you will need to:
|
|||
1. Configure a **wildcard DNS record**.
|
||||
1. (Optional) Have a **wildcard certificate** for that domain if you decide to
|
||||
serve Pages under HTTPS.
|
||||
1. (Optional but recommended) Enable [Shared runners](../ci/runners/README.md)
|
||||
1. (Optional but recommended) Enable [Shared runners](../../ci/runners/README.md)
|
||||
so that your users don't have to bring their own.
|
||||
|
||||
### DNS configuration
|
||||
|
@ -236,7 +236,7 @@ latest previous version.
|
|||
[8-3-docs]: https://gitlab.com/gitlab-org/gitlab-ee/blob/8-3-stable-ee/doc/pages/administration.md
|
||||
[8-5-docs]: https://gitlab.com/gitlab-org/gitlab-ee/blob/8-5-stable-ee/doc/pages/administration.md
|
||||
[8-17-docs]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-17-stable-ce/doc/administration/pages/index.md
|
||||
[backup]: ../raketasks/backup_restore.md
|
||||
[backup]: ../../raketasks/backup_restore.md
|
||||
[ce-14605]: https://gitlab.com/gitlab-org/gitlab-ce/issues/14605
|
||||
[ee-80]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/80
|
||||
[ee-173]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/173
|
||||
|
@ -244,6 +244,6 @@ latest previous version.
|
|||
[NGINX configs]: https://gitlab.com/gitlab-org/gitlab-ee/tree/8-5-stable-ee/lib/support/nginx
|
||||
[pages-readme]: https://gitlab.com/gitlab-org/gitlab-pages/blob/master/README.md
|
||||
[pages-userguide]: ../../user/project/pages/index.md
|
||||
[reconfigure]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
|
||||
[restart]: ../administration/restart_gitlab.md#installations-from-source
|
||||
[reconfigure]: ../restart_gitlab.md#omnibus-gitlab-reconfigure
|
||||
[restart]: ../restart_gitlab.md#installations-from-source
|
||||
[gitlab-pages]: https://gitlab.com/gitlab-org/gitlab-pages/tree/v0.2.4
|
||||
|
|
|
@ -311,13 +311,13 @@ Pages are part of the [regular backup][backup] so there is nothing to configure.
|
|||
You should strongly consider running GitLab pages under a different hostname
|
||||
than GitLab to prevent XSS attacks.
|
||||
|
||||
[backup]: ../raketasks/backup_restore.md
|
||||
[backup]: ../../raketasks/backup_restore.md
|
||||
[ee-80]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/80
|
||||
[ee-173]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/173
|
||||
[gitlab pages daemon]: https://gitlab.com/gitlab-org/gitlab-pages
|
||||
[NGINX configs]: https://gitlab.com/gitlab-org/gitlab-ee/tree/8-5-stable-ee/lib/support/nginx
|
||||
[pages-readme]: https://gitlab.com/gitlab-org/gitlab-pages/blob/master/README.md
|
||||
[pages-userguide]: ../../user/project/pages/index.md
|
||||
[reconfigure]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
|
||||
[restart]: ../administration/restart_gitlab.md#installations-from-source
|
||||
[reconfigure]: ../restart_gitlab.md#omnibus-gitlab-reconfigure
|
||||
[restart]: ../restart_gitlab.md#installations-from-source
|
||||
[gitlab-pages]: https://gitlab.com/gitlab-org/gitlab-pages/tree/v0.2.4
|
||||
|
|
|
@ -34,6 +34,8 @@ Example response:
|
|||
"committer_email": "john@example.com",
|
||||
"committer_name": "John Smith",
|
||||
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
|
||||
"short_id": "7b5c3cc",
|
||||
"title": "add projects API",
|
||||
"message": "add projects API",
|
||||
"parent_ids": [
|
||||
"4ad91d3c1144c406e50c7b33bae684bd6837faf8"
|
||||
|
@ -78,6 +80,8 @@ Example response:
|
|||
"committer_email": "john@example.com",
|
||||
"committer_name": "John Smith",
|
||||
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
|
||||
"short_id": "7b5c3cc",
|
||||
"title": "add projects API",
|
||||
"message": "add projects API",
|
||||
"parent_ids": [
|
||||
"4ad91d3c1144c406e50c7b33bae684bd6837faf8"
|
||||
|
@ -119,6 +123,8 @@ Example response:
|
|||
"committer_email": "john@example.com",
|
||||
"committer_name": "John Smith",
|
||||
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
|
||||
"short_id": "7b5c3cc",
|
||||
"title": "add projects API",
|
||||
"message": "add projects API",
|
||||
"parent_ids": [
|
||||
"4ad91d3c1144c406e50c7b33bae684bd6837faf8"
|
||||
|
@ -163,6 +169,8 @@ Example response:
|
|||
"committer_email": "john@example.com",
|
||||
"committer_name": "John Smith",
|
||||
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
|
||||
"short_id": "7b5c3cc",
|
||||
"title": "add projects API",
|
||||
"message": "add projects API",
|
||||
"parent_ids": [
|
||||
"4ad91d3c1144c406e50c7b33bae684bd6837faf8"
|
||||
|
@ -204,6 +212,8 @@ Example response:
|
|||
"committer_email": "john@example.com",
|
||||
"committer_name": "John Smith",
|
||||
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
|
||||
"short_id": "7b5c3cc",
|
||||
"title": "add projects API",
|
||||
"message": "add projects API",
|
||||
"parent_ids": [
|
||||
"4ad91d3c1144c406e50c7b33bae684bd6837faf8"
|
||||
|
|
|
@ -29,11 +29,15 @@ Example response:
|
|||
"title": "Replace sanitize with escape once",
|
||||
"author_name": "Dmitriy Zaporozhets",
|
||||
"author_email": "dzaporozhets@sphereconsultinginc.com",
|
||||
"authored_date": "2012-09-20T11:50:22+03:00",
|
||||
"committer_name": "Administrator",
|
||||
"committer_email": "admin@example.com",
|
||||
"committed_date": "2012-09-20T11:50:22+03:00",
|
||||
"created_at": "2012-09-20T11:50:22+03:00",
|
||||
"message": "Replace sanitize with escape once",
|
||||
"allow_failure": false
|
||||
"parent_ids": [
|
||||
"6104942438c14ec7bd21c6cd5bd995272b3faff6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "6104942438c14ec7bd21c6cd5bd995272b3faff6",
|
||||
|
@ -45,7 +49,9 @@ Example response:
|
|||
"committer_email": "dmitriy.zaporozhets@gmail.com",
|
||||
"created_at": "2012-09-20T09:06:12+03:00",
|
||||
"message": "Sanitize for network graph",
|
||||
"allow_failure": false
|
||||
"parent_ids": [
|
||||
"ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba"
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -214,10 +220,16 @@ Example response:
|
|||
"title": "Feature added",
|
||||
"author_name": "Dmitriy Zaporozhets",
|
||||
"author_email": "dmitriy.zaporozhets@gmail.com",
|
||||
"authored_date": "2016-12-12T20:10:39.000+01:00",
|
||||
"created_at": "2016-12-12T20:10:39.000+01:00",
|
||||
"committer_name": "Administrator",
|
||||
"committer_email": "admin@example.com",
|
||||
"message": "Feature added\n\nSigned-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>\n"
|
||||
"committed_date": "2016-12-12T20:10:39.000+01:00",
|
||||
"title": "Feature added",
|
||||
"message": "Feature added\n\nSigned-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>\n",
|
||||
"parent_ids": [
|
||||
"a738f717824ff53aebad8b090c1b79a14f2bd9e8"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -444,6 +456,7 @@ POST /projects/:id/statuses/:sha
|
|||
| `name` or `context` | string | no | The label to differentiate this status from the status of other systems. Default value is `default`
|
||||
| `target_url` | string | no | The target URL to associate with this status
|
||||
| `description` | string | no | The short description of the status
|
||||
| `coverage` | float | no | The total code coverage
|
||||
|
||||
```bash
|
||||
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/17/statuses/18f3e63d05582537db6d183d9d557be09e1f90c8?state=success"
|
||||
|
@ -464,6 +477,7 @@ Example response:
|
|||
"name" : "default",
|
||||
"sha" : "18f3e63d05582537db6d183d9d557be09e1f90c8",
|
||||
"status" : "success",
|
||||
"coverage": 100.0,
|
||||
"description" : null,
|
||||
"id" : 93,
|
||||
"target_url" : null,
|
||||
|
|
|
@ -35,6 +35,12 @@ Example response:
|
|||
"id": 2,
|
||||
"path": "group1",
|
||||
"kind": "group"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"path": "bar",
|
||||
"kind": "group",
|
||||
"full_path": "foo/bar",
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -64,7 +70,8 @@ Example response:
|
|||
{
|
||||
"id": 4,
|
||||
"path": "twitter",
|
||||
"kind": "group"
|
||||
"kind": "group",
|
||||
"full_path": "twitter",
|
||||
}
|
||||
]
|
||||
```
|
||||
|
|
|
@ -77,7 +77,8 @@ Parameters:
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"path": "diaspora",
|
||||
"kind": "group"
|
||||
"kind": "group",
|
||||
"full_path": "diaspora"
|
||||
},
|
||||
"archived": false,
|
||||
"avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",
|
||||
|
@ -127,7 +128,8 @@ Parameters:
|
|||
"id": 4,
|
||||
"name": "Brightbox",
|
||||
"path": "brightbox",
|
||||
"kind": "group"
|
||||
"kind": "group",
|
||||
"full_path": "brightbox"
|
||||
},
|
||||
"permissions": {
|
||||
"project_access": {
|
||||
|
@ -207,7 +209,8 @@ Parameters:
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"path": "diaspora",
|
||||
"kind": "group"
|
||||
"kind": "group",
|
||||
"full_path": "diaspora"
|
||||
},
|
||||
"permissions": {
|
||||
"project_access": {
|
||||
|
@ -585,7 +588,8 @@ Example response:
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"path": "diaspora",
|
||||
"kind": "group"
|
||||
"kind": "group",
|
||||
"full_path": "diaspora"
|
||||
},
|
||||
"archived": true,
|
||||
"avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png",
|
||||
|
@ -650,7 +654,8 @@ Example response:
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"path": "diaspora",
|
||||
"kind": "group"
|
||||
"kind": "group",
|
||||
"full_path": "diaspora"
|
||||
},
|
||||
"archived": true,
|
||||
"avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png",
|
||||
|
@ -721,7 +726,8 @@ Example response:
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"path": "diaspora",
|
||||
"kind": "group"
|
||||
"kind": "group",
|
||||
"full_path": "diaspora"
|
||||
},
|
||||
"permissions": {
|
||||
"project_access": {
|
||||
|
@ -803,7 +809,8 @@ Example response:
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"path": "diaspora",
|
||||
"kind": "group"
|
||||
"kind": "group",
|
||||
"full_path": "diaspora"
|
||||
},
|
||||
"permissions": {
|
||||
"project_access": {
|
||||
|
@ -1187,4 +1194,4 @@ Parameters:
|
|||
| --------- | ---- | -------- | ----------- |
|
||||
| `query` | string | yes | A string contained in the project name |
|
||||
| `order_by` | string | no | Return requests ordered by `id`, `name`, `created_at` or `last_activity_at` fields |
|
||||
| `sort` | string | no | Return requests sorted in `asc` or `desc` order |
|
||||
| `sort` | string | no | Return requests sorted in `asc` or `desc` order |
|
|
@ -2,22 +2,22 @@
|
|||
|
||||
## CI User documentation
|
||||
|
||||
- [Get started with GitLab CI](quick_start/README.md)
|
||||
- [Getting started with GitLab CI](quick_start/README.md)
|
||||
- [CI examples for various languages](examples/README.md)
|
||||
- [Learn how to enable or disable GitLab CI](enable_or_disable_ci.md)
|
||||
- [Pipelines and builds](pipelines.md)
|
||||
- [Pipelines and jobs](pipelines.md)
|
||||
- [Environments and deployments](environments.md)
|
||||
- [Learn how `.gitlab-ci.yml` works](yaml/README.md)
|
||||
- [Configure a Runner, the application that runs your builds](runners/README.md)
|
||||
- [Configure a Runner, the application that runs your jobs](runners/README.md)
|
||||
- [Use Docker images with GitLab Runner](docker/using_docker_images.md)
|
||||
- [Use CI to build Docker images](docker/using_docker_build.md)
|
||||
- [CI Variables](variables/README.md) - Learn how to use variables defined in
|
||||
your `.gitlab-ci.yml` or secured ones defined in your project's settings
|
||||
- [Use SSH keys in your build environment](ssh_keys/README.md)
|
||||
- [Trigger builds through the API](triggers/README.md)
|
||||
- [Build artifacts](../user/project/builds/artifacts.md)
|
||||
- [Trigger jobs through the API](triggers/README.md)
|
||||
- [Job artifacts](../user/project/pipelines/job_artifacts.md)
|
||||
- [User permissions](../user/permissions.md#gitlab-ci)
|
||||
- [Build permissions](../user/permissions.md#build-permissions)
|
||||
- [Jobs permissions](../user/permissions.md#jobs-permissions)
|
||||
- [API](../api/ci/README.md)
|
||||
- [CI services (linked docker containers)](services/README.md)
|
||||
- [CI/CD pipelines settings](../user/project/pipelines/settings.md)
|
||||
|
@ -27,6 +27,6 @@
|
|||
|
||||
## Breaking changes
|
||||
|
||||
- [New CI build permissions model](../user/project/new_ci_build_permissions_model.md)
|
||||
Read about what changed in GitLab 8.12 and how that affects your builds.
|
||||
There's a new way to access your Git submodules and LFS objects in builds.
|
||||
- [New CI job permissions model](../user/project/new_ci_build_permissions_model.md)
|
||||
Read about what changed in GitLab 8.12 and how that affects your jobs.
|
||||
There's a new way to access your Git submodules and LFS objects in jobs.
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
This document was moved to:
|
||||
|
||||
- [user/project/builds/artifacts.md](../../user/project/builds/artifacts.md) - user guide
|
||||
- [administration/build_artifacts.md](../../administration/build_artifacts.md) - administrator guide
|
||||
This document was moved to [pipelines/job_artifacts.md](../../user/project/pipelines/job_artifacts.md).
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Docker integration
|
||||
|
||||
+ [Using Docker Images](using_docker_images.md)
|
||||
+ [Using Docker Build](using_docker_build.md)
|
||||
- [Using Docker Images](using_docker_images.md)
|
||||
- [Using Docker Build](using_docker_build.md)
|
||||
|
|
|
@ -12,6 +12,7 @@ One of the new trends in Continuous Integration/Deployment is to:
|
|||
1. deploy to a server from the pushed image.
|
||||
|
||||
It's also useful when your application already has the `Dockerfile` that can be used to create and test an image:
|
||||
|
||||
```bash
|
||||
$ docker build -t my-image dockerfiles/
|
||||
$ docker run my-docker-image /script/to/run/tests
|
||||
|
@ -19,23 +20,23 @@ $ docker tag my-image my-registry:5000/my-image
|
|||
$ docker push my-registry:5000/my-image
|
||||
```
|
||||
|
||||
This requires special configuration of GitLab Runner to enable `docker` support during builds.
|
||||
This requires special configuration of GitLab Runner to enable `docker` support during jobs.
|
||||
|
||||
## Runner Configuration
|
||||
|
||||
There are three methods to enable the use of `docker build` and `docker run` during builds; each with their own tradeoffs.
|
||||
There are three methods to enable the use of `docker build` and `docker run` during jobs; each with their own tradeoffs.
|
||||
|
||||
### Use shell executor
|
||||
|
||||
The simplest approach is to install GitLab Runner in `shell` execution mode.
|
||||
GitLab Runner then executes build scripts as the `gitlab-runner` user.
|
||||
GitLab Runner then executes job scripts as the `gitlab-runner` user.
|
||||
|
||||
1. Install [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/#installation).
|
||||
|
||||
1. During GitLab Runner installation select `shell` as method of executing build scripts or use command:
|
||||
1. During GitLab Runner installation select `shell` as method of executing job scripts or use command:
|
||||
|
||||
```bash
|
||||
$ sudo gitlab-ci-multi-runner register -n \
|
||||
sudo gitlab-ci-multi-runner register -n \
|
||||
--url https://gitlab.com/ci \
|
||||
--registration-token REGISTRATION_TOKEN \
|
||||
--executor shell \
|
||||
|
@ -50,16 +51,17 @@ GitLab Runner then executes build scripts as the `gitlab-runner` user.
|
|||
3. Add `gitlab-runner` user to `docker` group:
|
||||
|
||||
```bash
|
||||
$ sudo usermod -aG docker gitlab-runner
|
||||
sudo usermod -aG docker gitlab-runner
|
||||
```
|
||||
|
||||
4. Verify that `gitlab-runner` has access to Docker:
|
||||
|
||||
```bash
|
||||
$ sudo -u gitlab-runner -H docker info
|
||||
sudo -u gitlab-runner -H docker info
|
||||
```
|
||||
|
||||
You can now verify that everything works by adding `docker info` to `.gitlab-ci.yml`:
|
||||
|
||||
```yaml
|
||||
before_script:
|
||||
- docker info
|
||||
|
@ -80,12 +82,12 @@ For more information please read [On Docker security: `docker` group considered
|
|||
|
||||
The second approach is to use the special docker-in-docker (dind)
|
||||
[Docker image](https://hub.docker.com/_/docker/) with all tools installed
|
||||
(`docker` and `docker-compose`) and run the build script in context of that
|
||||
(`docker` and `docker-compose`) and run the job script in context of that
|
||||
image in privileged mode.
|
||||
|
||||
In order to do that, follow the steps:
|
||||
|
||||
1. Install [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/#installation).
|
||||
1. Install [GitLab Runner](https://docs.gitlab.com/runner/install).
|
||||
|
||||
1. Register GitLab Runner from the command line to use `docker` and `privileged`
|
||||
mode:
|
||||
|
@ -155,10 +157,10 @@ not without its own challenges:
|
|||
escalation which can lead to container breakout. For more information, check
|
||||
out the official Docker documentation on
|
||||
[Runtime privilege and Linux capabilities][docker-cap].
|
||||
- Using docker-in-docker, each build is in a clean environment without the past
|
||||
history. Concurrent builds work fine because every build gets it's own
|
||||
- When using docker-in-docker, each job is in a clean environment without the past
|
||||
history. Concurrent jobs work fine because every build gets it's own
|
||||
instance of Docker engine so they won't conflict with each other. But this
|
||||
also means builds can be slower because there's no caching of layers.
|
||||
also means jobs can be slower because there's no caching of layers.
|
||||
- By default, `docker:dind` uses `--storage-driver vfs` which is the slowest
|
||||
form offered. To use a different driver, see
|
||||
[Using the overlayfs driver](#using-the-overlayfs-driver).
|
||||
|
@ -171,7 +173,7 @@ The third approach is to bind-mount `/var/run/docker.sock` into the container so
|
|||
|
||||
In order to do that, follow the steps:
|
||||
|
||||
1. Install [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/#installation).
|
||||
1. Install [GitLab Runner](https://docs.gitlab.com/runner/install).
|
||||
|
||||
1. Register GitLab Runner from the command line to use `docker` and share `/var/run/docker.sock`:
|
||||
|
||||
|
@ -187,7 +189,9 @@ In order to do that, follow the steps:
|
|||
|
||||
The above command will register a new Runner to use the special
|
||||
`docker:latest` image which is provided by Docker. **Notice that it's using
|
||||
the Docker daemon of the Runner itself, and any containers spawned by docker commands will be siblings of the Runner rather than children of the runner.** This may have complications and limitations that are unsuitable for your workflow.
|
||||
the Docker daemon of the Runner itself, and any containers spawned by docker
|
||||
commands will be siblings of the Runner rather than children of the runner.**
|
||||
This may have complications and limitations that are unsuitable for your workflow.
|
||||
|
||||
The above command will create a `config.toml` entry similar to this:
|
||||
|
||||
|
@ -206,7 +210,8 @@ In order to do that, follow the steps:
|
|||
Insecure = false
|
||||
```
|
||||
|
||||
1. You can now use `docker` in the build script (note that you don't need to include the `docker:dind` service as when using the Docker in Docker executor):
|
||||
1. You can now use `docker` in the build script (note that you don't need to
|
||||
include the `docker:dind` service as when using the Docker in Docker executor):
|
||||
|
||||
```yaml
|
||||
image: docker:latest
|
||||
|
@ -221,18 +226,23 @@ In order to do that, follow the steps:
|
|||
- docker run my-docker-image /script/to/run/tests
|
||||
```
|
||||
|
||||
While the above method avoids using Docker in privileged mode, you should be aware of the following implications:
|
||||
* By sharing the docker daemon, you are effectively disabling all
|
||||
the security mechanisms of containers and exposing your host to privilege
|
||||
escalation which can lead to container breakout. For example, if a project
|
||||
ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner
|
||||
containers.
|
||||
* Concurrent builds may not work; if your tests
|
||||
create containers with specific names, they may conflict with each other.
|
||||
* Sharing files and directories from the source repo into containers may not
|
||||
work as expected since volume mounting is done in the context of the host
|
||||
machine, not the build container.
|
||||
e.g. `docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests`
|
||||
While the above method avoids using Docker in privileged mode, you should be
|
||||
aware of the following implications:
|
||||
|
||||
- By sharing the docker daemon, you are effectively disabling all
|
||||
the security mechanisms of containers and exposing your host to privilege
|
||||
escalation which can lead to container breakout. For example, if a project
|
||||
ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner
|
||||
containers.
|
||||
- Concurrent jobs may not work; if your tests
|
||||
create containers with specific names, they may conflict with each other.
|
||||
- Sharing files and directories from the source repo into containers may not
|
||||
work as expected since volume mounting is done in the context of the host
|
||||
machine, not the build container, e.g.:
|
||||
|
||||
```
|
||||
docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
|
||||
```
|
||||
|
||||
## Using the OverlayFS driver
|
||||
|
||||
|
@ -299,7 +309,7 @@ push to the Registry connected to your project. Its password is provided in the
|
|||
of your Docker images.
|
||||
|
||||
Here's a more elaborate example that splits up the tasks into 4 pipeline stages,
|
||||
including two tests that run in parallel. The build is stored in the container
|
||||
including two tests that run in parallel. The `build` is stored in the container
|
||||
registry and used by subsequent stages, downloading the image
|
||||
when needed. Changes to `master` also get tagged as `latest` and deployed using
|
||||
an application-specific deploy script:
|
||||
|
@ -360,17 +370,17 @@ deploy:
|
|||
Some things you should be aware of when using the Container Registry:
|
||||
|
||||
- You must log in to the container registry before running commands. Putting
|
||||
this in `before_script` will run it before each build job.
|
||||
this in `before_script` will run it before each job.
|
||||
- Using `docker build --pull` makes sure that Docker fetches any changes to base
|
||||
images before building just in case your cache is stale. It takes slightly
|
||||
longer, but means you don’t get stuck without security patches to base images.
|
||||
- Doing an explicit `docker pull` before each `docker run` makes sure to fetch
|
||||
the latest image that was just built. This is especially important if you are
|
||||
using multiple runners that cache images locally. Using the git SHA in your
|
||||
image tag makes this less necessary since each build will be unique and you
|
||||
image tag makes this less necessary since each job will be unique and you
|
||||
shouldn't ever have a stale image, but it's still possible if you re-build a
|
||||
given commit after a dependency has changed.
|
||||
- You don't want to build directly to `latest` in case there are multiple builds
|
||||
- You don't want to build directly to `latest` in case there are multiple jobs
|
||||
happening simultaneously.
|
||||
|
||||
[docker-in-docker]: https://blog.docker.com/2013/09/docker-can-now-run-within-docker/
|
||||
|
|
|
@ -8,7 +8,7 @@ run applications in independent "containers" that are run within a single Linux
|
|||
instance. [Docker Hub][hub] has a rich database of pre-built images that can be
|
||||
used to test and build your applications.
|
||||
|
||||
Docker, when used with GitLab CI, runs each build in a separate and isolated
|
||||
Docker, when used with GitLab CI, runs each job in a separate and isolated
|
||||
container using the predefined image that is set up in
|
||||
[`.gitlab-ci.yml`](../yaml/README.md).
|
||||
|
||||
|
@ -45,12 +45,12 @@ can be found at [Docker Hub][hub]. For more information about images and Docker
|
|||
Hub please read the [Docker Fundamentals][] documentation.
|
||||
|
||||
In short, with `image` we refer to the docker image, which will be used to
|
||||
create a container on which your build will run.
|
||||
create a container on which your job will run.
|
||||
|
||||
## What is a service
|
||||
|
||||
The `services` keyword defines just another docker image that is run during
|
||||
your build and is linked to the docker image that the `image` keyword defines.
|
||||
your job and is linked to the docker image that the `image` keyword defines.
|
||||
This allows you to access the service image during build time.
|
||||
|
||||
The service image can run any application, but the most common use case is to
|
||||
|
@ -61,13 +61,13 @@ time the project is built.
|
|||
You can see some widely used services examples in the relevant documentation of
|
||||
[CI services examples](../services/README.md).
|
||||
|
||||
### How services are linked to the build
|
||||
### How services are linked to the job
|
||||
|
||||
To better understand how the container linking works, read
|
||||
[Linking containers together][linking-containers].
|
||||
|
||||
To summarize, if you add `mysql` as service to your application, the image will
|
||||
then be used to create a container that is linked to the build container.
|
||||
then be used to create a container that is linked to the job container.
|
||||
|
||||
The service container for MySQL will be accessible under the hostname `mysql`.
|
||||
So, in order to access your database service you have to connect to the host
|
||||
|
@ -133,7 +133,7 @@ Look for the `[runners.docker]` section:
|
|||
services = ["mysql:latest", "postgres:latest"]
|
||||
```
|
||||
|
||||
The image and services defined this way will be added to all builds run by
|
||||
The image and services defined this way will be added to all job run by
|
||||
that runner.
|
||||
|
||||
## Define an image from a private Docker registry
|
||||
|
@ -167,7 +167,7 @@ services:
|
|||
- tutum/wordpress:latest
|
||||
```
|
||||
|
||||
When the build is run, `tutum/wordpress` will be started and you will have
|
||||
When the job is run, `tutum/wordpress` will be started and you will have
|
||||
access to it from your build container under the hostname `tutum__wordpress`.
|
||||
|
||||
The alias hostname for the service is made from the image name following these
|
||||
|
@ -202,21 +202,21 @@ See the specific documentation for
|
|||
|
||||
## How Docker integration works
|
||||
|
||||
Below is a high level overview of the steps performed by docker during build
|
||||
Below is a high level overview of the steps performed by docker during job
|
||||
time.
|
||||
|
||||
1. Create any service container: `mysql`, `postgresql`, `mongodb`, `redis`.
|
||||
1. Create cache container to store all volumes as defined in `config.toml` and
|
||||
`Dockerfile` of build image (`ruby:2.1` as in above example).
|
||||
1. Create build container and link any service container to build container.
|
||||
1. Start build container and send build script to the container.
|
||||
1. Run build script.
|
||||
1. Start build container and send job script to the container.
|
||||
1. Run job script.
|
||||
1. Checkout code in: `/builds/group-name/project-name/`.
|
||||
1. Run any step defined in `.gitlab-ci.yml`.
|
||||
1. Check exit status of build script.
|
||||
1. Remove build container and all created service containers.
|
||||
|
||||
## How to debug a build locally
|
||||
## How to debug a job locally
|
||||
|
||||
*Note: The following commands are run without root privileges. You should be
|
||||
able to run docker with your regular user account.*
|
||||
|
|
|
@ -12,7 +12,7 @@ API.
|
|||
---
|
||||
|
||||
GitLab CI is exposed via the `/pipelines` and `/builds` pages of a project.
|
||||
Disabling GitLab CI in a project does not delete any previous builds.
|
||||
Disabling GitLab CI in a project does not delete any previous jobs.
|
||||
In fact, the `/pipelines` and `/builds` pages can still be accessed, although
|
||||
it's hidden from the left sidebar menu.
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ We have defined 3 [stages](yaml/README.md#stages):
|
|||
- deploy
|
||||
|
||||
The jobs assigned to these stages will run in this order. If a job fails, then
|
||||
the builds that are assigned to the next stage won't run, rendering the pipeline
|
||||
the jobs that are assigned to the next stage won't run, rendering the pipeline
|
||||
as failed. In our case, the `test` job will run first, then the `build` and
|
||||
lastly the `deploy_staging`. With this, we ensure that first the tests pass,
|
||||
then our app is able to be built successfully, and lastly we deploy to the
|
||||
|
@ -119,7 +119,7 @@ There's a bunch of information there, specifically you can see:
|
|||
|
||||
- The environment's name with a link to its deployments
|
||||
- The last deployment ID number and who performed it
|
||||
- The build ID of the last deployment with its respective job name
|
||||
- The job ID of the last deployment with its respective job name
|
||||
- The commit information of the last deployment such as who committed, to what
|
||||
branch and the Git SHA of the commit
|
||||
- The exact time the last deployment was performed
|
||||
|
@ -219,9 +219,9 @@ deploy_prod:
|
|||
|
||||
The `when: manual` action exposes a play button in GitLab's UI and the
|
||||
`deploy_prod` job will only be triggered if and when we click that play button.
|
||||
You can find it in the pipeline, build, environment, and deployment views.
|
||||
You can find it in the pipeline, job, environment, and deployment views.
|
||||
|
||||
| Pipelines | Single pipeline | Environments | Deployments | Builds |
|
||||
| Pipelines | Single pipeline | Environments | Deployments | jobs |
|
||||
| --------- | ----------------| ------------ | ----------- | -------|
|
||||
| ![Pipelines manual action](img/environments_manual_action_pipelines.png) | ![Pipelines manual action](img/environments_manual_action_single_pipeline.png) | ![Environments manual action](img/environments_manual_action_environments.png) | ![Deployments manual action](img/environments_manual_action_deployments.png) | ![Builds manual action](img/environments_manual_action_builds.png) |
|
||||
|
||||
|
@ -419,7 +419,7 @@ Behind the scenes:
|
|||
- GitLab Runner picks up the changes and starts running the jobs
|
||||
- The jobs run sequentially as defined in `stages`
|
||||
- First, the tests pass
|
||||
- Then, the build begins and successfully also passes
|
||||
- Then, the job begins and successfully also passes
|
||||
- Lastly, the app is deployed to an environment with a name specific to the
|
||||
branch
|
||||
|
||||
|
@ -535,6 +535,7 @@ deploy_review:
|
|||
- master
|
||||
|
||||
stop_review:
|
||||
stage: deploy
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
script:
|
||||
|
@ -555,7 +556,9 @@ when their associated branch is deleted.
|
|||
|
||||
When you have an environment that has a stop action defined (typically when
|
||||
the environment describes a review app), GitLab will automatically trigger a
|
||||
stop action when the associated branch is deleted.
|
||||
stop action when the associated branch is deleted. The `stop_review` job must
|
||||
be in the same `stage` as the `deploy_review` one in order for the environment
|
||||
to automatically stop.
|
||||
|
||||
You can read more in the [`.gitlab-ci.yml` reference][onstop].
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ Secure Variables can added by going to `Project > Variables > Add Variable`.
|
|||
**This feature requires `gitlab-runner` with version equal or greater than 0.4.0.**
|
||||
The variables that are defined in the project settings are sent along with the build script to the runner.
|
||||
The secure variables are stored out of the repository. Never store secrets in your projects' .gitlab-ci.yml.
|
||||
It is also important that secret's value is hidden in the build log.
|
||||
It is also important that secret's value is hidden in the job log.
|
||||
|
||||
You access added variable by prefixing it's name with `$` (on non-Windows runners) or `%` (for Windows Batch runners):
|
||||
1. `$SECRET_VARIABLE` - use it for non-Windows runners
|
||||
|
|
|
@ -65,7 +65,7 @@ In order, this means that:
|
|||
1. We check if the `ssh-agent` is available and we install it if it's not;
|
||||
2. We create the `~/.ssh` folder;
|
||||
3. We make sure we're running bash;
|
||||
4. We disable host checking (we don't ask for user accept when we first connect to a server; and since every build will equal a first connect, we kind of need this)
|
||||
4. We disable host checking (we don't ask for user accept when we first connect to a server; and since every job will equal a first connect, we kind of need this)
|
||||
|
||||
And this is basically all you need in the `before_script` section.
|
||||
|
||||
|
@ -153,4 +153,4 @@ stage_deploy:
|
|||
- scp -P22 -r build/* server_user@server_host:htdocs/wp-content/themes/_tmp
|
||||
- ssh -p22 server_user@server_host "mv htdocs/wp-content/themes/live htdocs/wp-content/themes/_old && mv htdocs/wp-content/themes/_tmp htdocs/wp-content/themes/live"
|
||||
- ssh -p22 server_user@server_host "rm -rf htdocs/wp-content/themes/_old"
|
||||
```
|
||||
```
|
||||
|
|
|
@ -15,10 +15,10 @@ This will allow us to test PHP projects against different versions of PHP.
|
|||
However, not everything is plug 'n' play, you still need to configure some
|
||||
things manually.
|
||||
|
||||
As with every build, you need to create a valid `.gitlab-ci.yml` describing the
|
||||
As with every job, you need to create a valid `.gitlab-ci.yml` describing the
|
||||
build environment.
|
||||
|
||||
Let's first specify the PHP image that will be used for the build process
|
||||
Let's first specify the PHP image that will be used for the job process
|
||||
(you can read more about what an image means in the Runner's lingo reading
|
||||
about [Using Docker images](../docker/using_docker_images.md#what-is-image)).
|
||||
|
||||
|
@ -58,8 +58,8 @@ docker-php-ext-install pdo_mysql
|
|||
```
|
||||
|
||||
You might wonder what `docker-php-ext-install` is. In short, it is a script
|
||||
provided by the official php docker image that you can use to easilly install
|
||||
extensions. For more information read the the documentation at
|
||||
provided by the official php docker image that you can use to easily install
|
||||
extensions. For more information read the documentation at
|
||||
<https://hub.docker.com/r/_/php/>.
|
||||
|
||||
Now that we created the script that contains all prerequisites for our build
|
||||
|
@ -142,7 +142,7 @@ Of course, `my_php.ini` must be present in the root directory of your repository
|
|||
|
||||
## Test PHP projects using the Shell executor
|
||||
|
||||
The shell executor runs your builds in a terminal session on your server.
|
||||
The shell executor runs your job in a terminal session on your server.
|
||||
Thus, in order to test your projects you first need to make sure that all
|
||||
dependencies are installed.
|
||||
|
||||
|
@ -280,7 +280,7 @@ that runs on [GitLab.com](https://gitlab.com) using our publicly available
|
|||
[shared runners](../runners/README.md).
|
||||
|
||||
Want to hack on it? Simply fork it, commit and push your changes. Within a few
|
||||
moments the changes will be picked by a public runner and the build will begin.
|
||||
moments the changes will be picked by a public runner and the job will begin.
|
||||
|
||||
[php-hub]: https://hub.docker.com/r/_/php/
|
||||
[phpenv]: https://github.com/phpenv/phpenv
|
||||
|
|
|
@ -51,14 +51,14 @@ The `deploy` stage automatically deploys the project to Heroku using dpl.
|
|||
You can use other versions of Scala and SBT by defining them in
|
||||
`build.sbt`.
|
||||
|
||||
## Display test coverage in build
|
||||
## Display test coverage in job
|
||||
|
||||
Add the `Coverage was \[\d+.\d+\%\]` regular expression in the
|
||||
**Settings ➔ Edit Project ➔ Test coverage parsing** project setting to
|
||||
**Settings ➔ CI/CD Pipelines ➔ Coverage report** project setting to
|
||||
retrieve the [test coverage] rate from the build trace and have it
|
||||
displayed with your builds.
|
||||
displayed with your jobs.
|
||||
|
||||
**Builds** must be enabled for this option to appear.
|
||||
**Pipelines** must be enabled for this option to appear.
|
||||
|
||||
## Heroku application
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# Using Git submodules with GitLab CI
|
||||
|
||||
> **Notes:**
|
||||
- GitLab 8.12 introduced a new [CI build permissions model][newperms] and you
|
||||
- GitLab 8.12 introduced a new [CI job permissions model][newperms] and you
|
||||
are encouraged to upgrade your GitLab instance if you haven't done already.
|
||||
If you are **not** using GitLab 8.12 or higher, you would need to work your way
|
||||
around submodules in order to access the sources of e.g., `gitlab.com/group/project`
|
||||
with the use of [SSH keys](ssh_keys/README.md).
|
||||
- With GitLab 8.12 onward, your permissions are used to evaluate what a CI build
|
||||
- With GitLab 8.12 onward, your permissions are used to evaluate what a CI job
|
||||
can access. More information about how this system works can be found in the
|
||||
[Build permissions model](../user/permissions.md#builds-permissions).
|
||||
[Jobs permissions model](../user/permissions.md#jobs-permissions).
|
||||
- The HTTP(S) Git protocol [must be enabled][gitpro] in your GitLab instance.
|
||||
|
||||
## Configuring the `.gitmodules` file
|
||||
|
@ -27,7 +27,7 @@ Let's consider the following example:
|
|||
If you are using GitLab 8.12+ and your submodule is on the same GitLab server,
|
||||
you must update your `.gitmodules` file to use **relative URLs**.
|
||||
Since Git allows the usage of relative URLs for your `.gitmodules` configuration,
|
||||
this easily allows you to use HTTP(S) for cloning all your CI builds and SSH
|
||||
this easily allows you to use HTTP(S) for cloning all your CI jobs and SSH
|
||||
for all your local checkouts. The `.gitmodules` would look like:
|
||||
|
||||
```ini
|
||||
|
@ -38,7 +38,7 @@ for all your local checkouts. The `.gitmodules` would look like:
|
|||
|
||||
The above configuration will instruct Git to automatically deduce the URL that
|
||||
should be used when cloning sources. Whether you use HTTP(S) or SSH, Git will use
|
||||
that same channel and it will allow to make all your CI builds use HTTP(S)
|
||||
that same channel and it will allow to make all your CI jobs use HTTP(S)
|
||||
(because GitLab CI only uses HTTP(S) for cloning your sources), and all your local
|
||||
clones will continue using SSH.
|
||||
|
||||
|
@ -57,13 +57,13 @@ Once `.gitmodules` is correctly configured, you can move on to
|
|||
## Using Git submodules in your CI jobs
|
||||
|
||||
There are a few steps you need to take in order to make submodules work
|
||||
correctly with your CI builds:
|
||||
correctly with your CI jobs:
|
||||
|
||||
1. First, make sure you have used [relative URLs](#configuring-the-gitmodules-file)
|
||||
for the submodules located in the same GitLab server.
|
||||
1. Next, if you are using `gitlab-ci-multi-runner` v1.10+, you can set the
|
||||
`GIT_SUBMODULE_STRATEGY` variable to either `normal` or `recursive` to tell
|
||||
the runner to fetch your submodules before the build:
|
||||
the runner to fetch your submodules before the job:
|
||||
```yaml
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
|
@ -87,9 +87,9 @@ The rationale to set the `sync` and `update` in `before_script` is because of
|
|||
the way Git submodules work. On a fresh Runner workspace, Git will set the
|
||||
submodule URL including the token in `.git/config`
|
||||
(or `.git/modules/<submodule>/config`) based on `.gitmodules` and the current
|
||||
remote URL. On subsequent builds on the same Runner, `.git/config` is cached
|
||||
remote URL. On subsequent jobs on the same Runner, `.git/config` is cached
|
||||
and already contains a full URL for the submodule, corresponding to the previous
|
||||
build, and to **a token from a previous build**. `sync` allows to force updating
|
||||
job, and to **a token from a previous job**. `sync` allows to force updating
|
||||
the full URL.
|
||||
|
||||
[gitpro]: ../user/admin_area/settings/visibility_and_access_controls.md#enabled-git-access-protocols
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# Introduction to pipelines and builds
|
||||
# Introduction to pipelines and jobs
|
||||
|
||||
>**Note:**
|
||||
Introduced in GitLab 8.8.
|
||||
|
||||
## Pipelines
|
||||
|
||||
A pipeline is a group of [builds][] that get executed in [stages][](batches).
|
||||
All of the builds in a stage are executed in parallel (if there are enough
|
||||
A pipeline is a group of [jobs][] that get executed in [stages][](batches).
|
||||
All of the jobs in a stage are executed in parallel (if there are enough
|
||||
concurrent [Runners]), and if they all succeed, the pipeline moves on to the
|
||||
next stage. If one of the builds fails, the next stage is not (usually)
|
||||
next stage. If one of the jobs fails, the next stage is not (usually)
|
||||
executed.
|
||||
|
||||
![Pipelines example](img/pipelines.png)
|
||||
|
@ -21,7 +21,7 @@ There are three types of pipelines that often use the single shorthand of "pipel
|
|||
|
||||
1. **CI Pipeline**: Build and test stages defined in `.gitlab-ci.yml`
|
||||
2. **Deploy Pipeline**: Deploy stage(s) defined in `.gitlab-ci.yml` The flow of deploying code to servers through various stages: e.g. development to staging to production
|
||||
3. **Project Pipeline**: Cross-project CI dependencies [triggered via API]((triggers)), particularly for micro-services, but also for complicated build dependencies: e.g. api -> front-end, ce/ee -> omnibus.
|
||||
3. **Project Pipeline**: Cross-project CI dependencies [triggered via API][triggers], particularly for micro-services, but also for complicated build dependencies: e.g. api -> front-end, ce/ee -> omnibus.
|
||||
|
||||
## Development Workflows
|
||||
|
||||
|
@ -35,10 +35,10 @@ Example continuous delivery flow:
|
|||
|
||||
![CD Flow](img/pipelines-goal.svg)
|
||||
|
||||
## Builds
|
||||
## Jobs
|
||||
|
||||
Builds are individual runs of [jobs]. Not to be confused with a `build` job or
|
||||
`build` stage.
|
||||
Jobs can be defined in the [`.gitlab-ci.yml`][jobs-yaml] file. Not to be
|
||||
confused with a `build` job or `build` stage.
|
||||
|
||||
## Defining pipelines
|
||||
|
||||
|
@ -52,11 +52,11 @@ See full [documentation](yaml/README.md#jobs).
|
|||
You can find the current and historical pipeline runs under **Pipelines** for
|
||||
your project.
|
||||
|
||||
## Seeing build status
|
||||
## Seeing job status
|
||||
|
||||
Clicking on a pipeline will show the builds that were run for that pipeline.
|
||||
Clicking on an individual build will show you its build trace, and allow you to
|
||||
cancel the build, retry it, or erase the build trace.
|
||||
Clicking on a pipeline will show the jobs that were run for that pipeline.
|
||||
Clicking on an individual job will show you its job trace, and allow you to
|
||||
cancel the job, retry it, or erase the job trace.
|
||||
|
||||
## How the pipeline duration is calculated
|
||||
|
||||
|
@ -91,11 +91,12 @@ total running time should be:
|
|||
|
||||
## Badges
|
||||
|
||||
Build status and test coverage report badges are available. You can find their
|
||||
Job status and test coverage report badges are available. You can find their
|
||||
respective link in the [Pipelines settings] page.
|
||||
|
||||
[builds]: #builds
|
||||
[jobs]: yaml/README.md#jobs
|
||||
[jobs]: #jobs
|
||||
[jobs-yaml]: yaml/README.md#jobs
|
||||
[stages]: yaml/README.md#stages
|
||||
[runners]: runners/README.html
|
||||
[pipelines settings]: ../user/project/pipelines/settings.md
|
||||
[triggers]: triggers/README.md
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Quick Start
|
||||
# Getting started with GitLab CI
|
||||
|
||||
>**Note:** Starting from version 8.0, GitLab [Continuous Integration][ci] (CI)
|
||||
is fully integrated into GitLab itself and is [enabled] by default on all
|
||||
|
@ -7,7 +7,7 @@ projects.
|
|||
GitLab offers a [continuous integration][ci] service. If you
|
||||
[add a `.gitlab-ci.yml` file][yaml] to the root directory of your repository,
|
||||
and configure your GitLab project to use a [Runner], then each merge request or
|
||||
push triggers your CI [pipeline].
|
||||
push, triggers your CI [pipeline].
|
||||
|
||||
The `.gitlab-ci.yml` file tells the GitLab runner what to do. By default it runs
|
||||
a pipeline with three [stages]: `build`, `test`, and `deploy`. You don't need to
|
||||
|
@ -31,13 +31,13 @@ So in brief, the steps needed to have a working CI can be summed up to:
|
|||
|
||||
From there on, on every push to your Git repository, the Runner will
|
||||
automagically start the pipeline and the pipeline will appear under the
|
||||
project's `/pipelines` page.
|
||||
project's **Pipelines** page.
|
||||
|
||||
---
|
||||
|
||||
This guide assumes that you:
|
||||
|
||||
- have a working GitLab instance of version 8.0 or higher or are using
|
||||
- have a working GitLab instance of version 8.0+r or are using
|
||||
[GitLab.com](https://gitlab.com)
|
||||
- have a project in GitLab that you would like to use CI for
|
||||
|
||||
|
@ -54,7 +54,7 @@ The `.gitlab-ci.yml` file is where you configure what CI does with your project.
|
|||
It lives in the root of your repository.
|
||||
|
||||
On any push to your repository, GitLab will look for the `.gitlab-ci.yml`
|
||||
file and start builds on _Runners_ according to the contents of the file,
|
||||
file and start jobs on _Runners_ according to the contents of the file,
|
||||
for that commit.
|
||||
|
||||
Because `.gitlab-ci.yml` is in the repository and is version controlled, old
|
||||
|
@ -63,11 +63,12 @@ have different pipelines and jobs, and you have a single source of truth for CI.
|
|||
You can read more about the reasons why we are using `.gitlab-ci.yml` [in our
|
||||
blog about it][blog-ci].
|
||||
|
||||
**Note:** `.gitlab-ci.yml` is a [YAML](https://en.wikipedia.org/wiki/YAML) file
|
||||
so you have to pay extra attention to indentation. Always use spaces, not tabs.
|
||||
|
||||
### Creating a simple `.gitlab-ci.yml` file
|
||||
|
||||
>**Note:**
|
||||
`.gitlab-ci.yml` is a [YAML](https://en.wikipedia.org/wiki/YAML) file
|
||||
so you have to pay extra attention to indentation. Always use spaces, not tabs.
|
||||
|
||||
You need to create a file named `.gitlab-ci.yml` in the root directory of your
|
||||
repository. Below is an example for a Ruby on Rails project.
|
||||
|
||||
|
@ -88,7 +89,7 @@ rubocop:
|
|||
- bundle exec rubocop
|
||||
```
|
||||
|
||||
This is the simplest possible build configuration that will work for most Ruby
|
||||
This is the simplest possible configuration that will work for most Ruby
|
||||
applications:
|
||||
|
||||
1. Define two jobs `rspec` and `rubocop` (the names are arbitrary) with
|
||||
|
@ -98,22 +99,22 @@ applications:
|
|||
The `.gitlab-ci.yml` file defines sets of jobs with constraints of how and when
|
||||
they should be run. The jobs are defined as top-level elements with a name (in
|
||||
our case `rspec` and `rubocop`) and always have to contain the `script` keyword.
|
||||
Jobs are used to create builds, which are then picked by
|
||||
Jobs are used to create jobs, which are then picked by
|
||||
[Runners](../runners/README.md) and executed within the environment of the Runner.
|
||||
|
||||
What is important is that each job is run independently from each other.
|
||||
|
||||
If you want to check whether your `.gitlab-ci.yml` file is valid, there is a
|
||||
Lint tool under the page `/ci/lint` of your GitLab instance. You can also find
|
||||
a "CI Lint" button to go to this page under **Pipelines > Pipelines** and
|
||||
**Pipelines > Builds** in your project.
|
||||
a "CI Lint" button to go to this page under **Pipelines ➔ Pipelines** and
|
||||
**Pipelines ➔ Jobs** in your project.
|
||||
|
||||
For more information and a complete `.gitlab-ci.yml` syntax, please read
|
||||
[the documentation on .gitlab-ci.yml](../yaml/README.md).
|
||||
[the reference documentation on .gitlab-ci.yml](../yaml/README.md).
|
||||
|
||||
### Push `.gitlab-ci.yml` to GitLab
|
||||
|
||||
Once you've created `.gitlab-ci.yml`, you should add it to your git repository
|
||||
Once you've created `.gitlab-ci.yml`, you should add it to your Git repository
|
||||
and push it to GitLab.
|
||||
|
||||
```bash
|
||||
|
@ -125,28 +126,27 @@ git push origin master
|
|||
Now if you go to the **Pipelines** page you will see that the pipeline is
|
||||
pending.
|
||||
|
||||
You can also go to the **Commits** page and notice the little clock icon next
|
||||
You can also go to the **Commits** page and notice the little pause icon next
|
||||
to the commit SHA.
|
||||
|
||||
![New commit pending](img/new_commit.png)
|
||||
|
||||
Clicking on the clock icon you will be directed to the builds page for that
|
||||
specific commit.
|
||||
Clicking on it you will be directed to the jobs page for that specific commit.
|
||||
|
||||
![Single commit builds page](img/single_commit_status_pending.png)
|
||||
![Single commit jobs page](img/single_commit_status_pending.png)
|
||||
|
||||
Notice that there are two jobs pending which are named after what we wrote in
|
||||
`.gitlab-ci.yml`. The red triangle indicates that there is no Runner configured
|
||||
yet for these builds.
|
||||
yet for these jobs.
|
||||
|
||||
The next step is to configure a Runner so that it picks the pending builds.
|
||||
The next step is to configure a Runner so that it picks the pending jobs.
|
||||
|
||||
## Configuring a Runner
|
||||
|
||||
In GitLab, Runners run the builds that you define in `.gitlab-ci.yml`. A Runner
|
||||
In GitLab, Runners run the jobs that you define in `.gitlab-ci.yml`. A Runner
|
||||
can be a virtual machine, a VPS, a bare-metal machine, a docker container or
|
||||
even a cluster of containers. GitLab and the Runners communicate through an API,
|
||||
so the only requirement is that the Runner's machine has Internet access.
|
||||
so the only requirement is that the Runner's machine has [Internet] access.
|
||||
|
||||
A Runner can be specific to a certain project or serve multiple projects in
|
||||
GitLab. If it serves all projects it's called a _Shared Runner_.
|
||||
|
@ -155,9 +155,9 @@ Find more information about different Runners in the
|
|||
[Runners](../runners/README.md) documentation.
|
||||
|
||||
You can find whether any Runners are assigned to your project by going to
|
||||
**Settings > Runners**. Setting up a Runner is easy and straightforward. The
|
||||
official Runner supported by GitLab is written in Go and can be found at
|
||||
<https://gitlab.com/gitlab-org/gitlab-ci-multi-runner>.
|
||||
**Settings ➔ Runners**. Setting up a Runner is easy and straightforward. The
|
||||
official Runner supported by GitLab is written in Go and its documentation
|
||||
can be found at <https://docs.gitlab.com/runner/>.
|
||||
|
||||
In order to have a functional Runner you need to follow two steps:
|
||||
|
||||
|
@ -167,28 +167,25 @@ In order to have a functional Runner you need to follow two steps:
|
|||
Follow the links above to set up your own Runner or use a Shared Runner as
|
||||
described in the next section.
|
||||
|
||||
For other types of unofficial Runners written in other languages, see the
|
||||
[instructions for the various GitLab Runners](https://about.gitlab.com/gitlab-ci/#gitlab-runner).
|
||||
|
||||
Once the Runner has been set up, you should see it on the Runners page of your
|
||||
project, following **Settings > Runners**.
|
||||
project, following **Settings ➔ Runners**.
|
||||
|
||||
![Activated runners](img/runners_activated.png)
|
||||
|
||||
### Shared Runners
|
||||
|
||||
If you use [GitLab.com](https://gitlab.com/) you can use **Shared Runners**
|
||||
If you use [GitLab.com](https://gitlab.com/) you can use the **Shared Runners**
|
||||
provided by GitLab Inc.
|
||||
|
||||
These are special virtual machines that run on GitLab's infrastructure and can
|
||||
build any project.
|
||||
|
||||
To enable **Shared Runners** you have to go to your project's
|
||||
**Settings > Runners** and click **Enable shared runners**.
|
||||
To enable the **Shared Runners** you have to go to your project's
|
||||
**Settings ➔ Runners** and click **Enable shared runners**.
|
||||
|
||||
[Read more on Shared Runners](../runners/README.md).
|
||||
|
||||
## Seeing the status of your pipeline and builds
|
||||
## Seeing the status of your pipeline and jobs
|
||||
|
||||
After configuring the Runner successfully, you should see the status of your
|
||||
last commit change from _pending_ to either _running_, _success_ or _failed_.
|
||||
|
@ -197,23 +194,23 @@ You can view all pipelines by going to the **Pipelines** page in your project.
|
|||
|
||||
![Commit status](img/pipelines_status.png)
|
||||
|
||||
Or you can view all builds, by going to the **Pipelines > Builds** page.
|
||||
Or you can view all jobs, by going to the **Pipelines ➔ Jobs** page.
|
||||
|
||||
![Commit status](img/builds_status.png)
|
||||
|
||||
By clicking on a Build ID, you will be able to see the log of that build.
|
||||
This is important to diagnose why a build failed or acted differently than
|
||||
By clicking on a job's status, you will be able to see the log of that job.
|
||||
This is important to diagnose why a job failed or acted differently than
|
||||
you expected.
|
||||
|
||||
![Build log](img/build_log.png)
|
||||
|
||||
You are also able to view the status of any commit in the various pages in
|
||||
GitLab, such as **Commits** and **Merge Requests**.
|
||||
GitLab, such as **Commits** and **Merge requests**.
|
||||
|
||||
## Enabling build emails
|
||||
|
||||
If you want to receive e-mail notifications about the result status of the
|
||||
builds, you should explicitly enable the **Builds Emails** service under your
|
||||
jobs, you should explicitly enable the **Builds Emails** service under your
|
||||
project's settings.
|
||||
|
||||
For more information read the
|
||||
|
@ -224,9 +221,7 @@ For more information read the
|
|||
Visit the [examples README][examples] to see a list of examples using GitLab
|
||||
CI with various languages.
|
||||
|
||||
Awesome! You started using CI in GitLab!
|
||||
|
||||
[runner-install]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/tree/master#install-gitlab-runner
|
||||
[runner-install]: https://docs.gitlab.com/runner/install/
|
||||
[blog-ci]: https://about.gitlab.com/2015/05/06/why-were-replacing-gitlab-ci-jobs-with-gitlab-ci-dot-yml/
|
||||
[examples]: ../examples/README.md
|
||||
[ci]: https://about.gitlab.com/gitlab-ci/
|
||||
|
@ -235,3 +230,4 @@ Awesome! You started using CI in GitLab!
|
|||
[enabled]: ../enable_or_disable_ci.md
|
||||
[stages]: ../yaml/README.md#stages
|
||||
[pipeline]: ../pipelines.md
|
||||
[internet]: https://about.gitlab.com/images/theinternet.png
|
||||
|
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 9.3 KiB |
|
@ -1,11 +1,11 @@
|
|||
# Runners
|
||||
|
||||
In GitLab CI, Runners run your [yaml](../yaml/README.md).
|
||||
A runner is an isolated (virtual) machine that picks up builds
|
||||
A Runner is an isolated (virtual) machine that picks up jobs
|
||||
through the coordinator API of GitLab CI.
|
||||
|
||||
A runner can be specific to a certain project or serve any project
|
||||
in GitLab CI. A runner that serves all projects is called a shared runner.
|
||||
A Runner can be specific to a certain project or serve any project
|
||||
in GitLab CI. A Runner that serves all projects is called a shared Runner.
|
||||
|
||||
Ideally, GitLab Runner should not be installed on the same machine as GitLab.
|
||||
Read the [requirements documentation](../../install/requirements.md#gitlab-runner)
|
||||
|
@ -13,150 +13,150 @@ for more information.
|
|||
|
||||
## Shared vs. Specific Runners
|
||||
|
||||
A runner that is specific only runs for the specified project. A shared runner
|
||||
can run jobs for every project that has enabled the option
|
||||
`Allow shared runners`.
|
||||
A Runner that is specific only runs for the specified project. A shared Runner
|
||||
can run jobs for every project that has enabled the option **Allow shared Runners**.
|
||||
|
||||
**Shared runners** are useful for jobs that have similar requirements,
|
||||
between multiple projects. Rather than having multiple runners idling for
|
||||
many projects, you can have a single or a small number of runners that handle
|
||||
multiple projects. This makes it easier to maintain and update runners.
|
||||
**Shared Runners** are useful for jobs that have similar requirements,
|
||||
between multiple projects. Rather than having multiple Runners idling for
|
||||
many projects, you can have a single or a small number of Runners that handle
|
||||
multiple projects. This makes it easier to maintain and update Runners.
|
||||
|
||||
**Specific runners** are useful for jobs that have special requirements or for
|
||||
**Specific Runners** are useful for jobs that have special requirements or for
|
||||
projects with a specific demand. If a job has certain requirements, you can set
|
||||
up the specific runner with this in mind, while not having to do this for all
|
||||
runners. For example, if you want to deploy a certain project, you can setup
|
||||
a specific runner to have the right credentials for this.
|
||||
up the specific Runner with this in mind, while not having to do this for all
|
||||
Runners. For example, if you want to deploy a certain project, you can setup
|
||||
a specific Runner to have the right credentials for this.
|
||||
|
||||
Projects with high demand of CI activity can also benefit from using specific runners.
|
||||
By having dedicated runners you are guaranteed that the runner is not being held
|
||||
Projects with high demand of CI activity can also benefit from using specific Runners.
|
||||
By having dedicated Runners you are guaranteed that the Runner is not being held
|
||||
up by another project's jobs.
|
||||
|
||||
You can set up a specific runner to be used by multiple projects. The difference
|
||||
with a shared runner is that you have to enable each project explicitly for
|
||||
the runner to be able to run its jobs.
|
||||
You can set up a specific Runner to be used by multiple projects. The difference
|
||||
with a shared Runner is that you have to enable each project explicitly for
|
||||
the Runner to be able to run its jobs.
|
||||
|
||||
Specific runners do not get shared with forked projects automatically.
|
||||
Specific Runners do not get shared with forked projects automatically.
|
||||
A fork does copy the CI settings (jobs, allow shared, etc) of the cloned repository.
|
||||
|
||||
# Creating and Registering a Runner
|
||||
|
||||
There are several ways to create a runner. Only after creation, upon
|
||||
There are several ways to create a Runner. Only after creation, upon
|
||||
registration its status as Shared or Specific is determined.
|
||||
|
||||
[See the documentation for](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/#installation)
|
||||
[See the documentation for](https://docs.gitlab.com/runner/install)
|
||||
the different methods of installing a Runner instance.
|
||||
|
||||
After installing the runner, you can either register it as `Shared` or as `Specific`.
|
||||
After installing the Runner, you can either register it as `Shared` or as `Specific`.
|
||||
You can only register a Shared Runner if you have admin access to the GitLab instance.
|
||||
|
||||
## Registering a Shared Runner
|
||||
|
||||
You can only register a shared runner if you are an admin on the linked
|
||||
You can only register a shared Runner if you are an admin on the linked
|
||||
GitLab instance.
|
||||
|
||||
Grab the shared-runner token on the `admin/runners` page of your GitLab CI
|
||||
Grab the shared-Runner token on the `admin/runners` page of your GitLab CI
|
||||
instance.
|
||||
|
||||
![shared token](shared_runner.png)
|
||||
|
||||
Now simply register the runner as any runner:
|
||||
Now simply register the Runner as any Runner:
|
||||
|
||||
```
|
||||
sudo gitlab-ci-multi-runner register
|
||||
```
|
||||
|
||||
Shared runners are enabled by default as of GitLab 8.2, but can be disabled with the
|
||||
`DISABLE SHARED RUNNERS` button. Previous versions of GitLab defaulted shared runners to
|
||||
Shared Runners are enabled by default as of GitLab 8.2, but can be disabled with the
|
||||
`DISABLE SHARED RUNNERS` button. Previous versions of GitLab defaulted shared Runners to
|
||||
disabled.
|
||||
|
||||
## Registering a Specific Runner
|
||||
|
||||
Registering a specific can be done in two ways:
|
||||
|
||||
1. Creating a runner with the project registration token
|
||||
1. Converting a shared runner into a specific runner (one-way, admin only)
|
||||
1. Creating a Runner with the project registration token
|
||||
1. Converting a shared Runner into a specific Runner (one-way, admin only)
|
||||
|
||||
There are several ways to create a runner instance. The steps below only
|
||||
concern registering the runner on GitLab CI.
|
||||
There are several ways to create a Runner instance. The steps below only
|
||||
concern registering the Runner on GitLab CI.
|
||||
|
||||
### Registering a Specific Runner with a Project Registration token
|
||||
|
||||
To create a specific runner without having admin rights to the GitLab instance,
|
||||
visit the project you want to make the runner work for in GitLab CI.
|
||||
To create a specific Runner without having admin rights to the GitLab instance,
|
||||
visit the project you want to make the Runner work for in GitLab CI.
|
||||
|
||||
Click on the runner tab and use the registration token you find there to
|
||||
setup a specific runner for this project.
|
||||
Click on the Runner tab and use the registration token you find there to
|
||||
setup a specific Runner for this project.
|
||||
|
||||
![project runners in GitLab CI](project_specific.png)
|
||||
![project Runners in GitLab CI](project_specific.png)
|
||||
|
||||
To register the runner, run the command below and follow instructions:
|
||||
To register the Runner, run the command below and follow instructions:
|
||||
|
||||
```
|
||||
sudo gitlab-ci-multi-runner register
|
||||
```
|
||||
|
||||
### Lock a specific runner from being enabled for other projects
|
||||
### Lock a specific Runner from being enabled for other projects
|
||||
|
||||
You can configure a runner to assign it exclusively to a project. When a
|
||||
runner is locked this way, it can no longer be enabled for other projects.
|
||||
This setting is available on each runner in *Project Settings* > *Runners*.
|
||||
You can configure a Runner to assign it exclusively to a project. When a
|
||||
Runner is locked this way, it can no longer be enabled for other projects.
|
||||
This setting is available on each Runner in *Project Settings* > *Runners*.
|
||||
|
||||
### Making an existing Shared Runner Specific
|
||||
|
||||
If you are an admin on your GitLab instance,
|
||||
you can make any shared runner a specific runner, _but you can not
|
||||
make a specific runner a shared runner_.
|
||||
you can make any shared Runner a specific Runner, _but you can not
|
||||
make a specific Runner a shared Runner_.
|
||||
|
||||
To make a shared runner specific, go to the runner page (`/admin/runners`)
|
||||
and find your runner. Add any projects on the left to make this runner
|
||||
run exclusively for these projects, therefore making it a specific runner.
|
||||
To make a shared Runner specific, go to the Runner page (`/admin/runners`)
|
||||
and find your Runner. Add any projects on the left to make this Runner
|
||||
run exclusively for these projects, therefore making it a specific Runner.
|
||||
|
||||
![making a shared runner specific](shared_to_specific_admin.png)
|
||||
![making a shared Runner specific](shared_to_specific_admin.png)
|
||||
|
||||
## Using Shared Runners Effectively
|
||||
|
||||
If you are planning to use shared runners, there are several things you
|
||||
If you are planning to use shared Runners, there are several things you
|
||||
should keep in mind.
|
||||
|
||||
### Use Tags
|
||||
|
||||
You must setup a runner to be able to run all the different types of jobs
|
||||
You must setup a Runner to be able to run all the different types of jobs
|
||||
that it may encounter on the projects it's shared over. This would be
|
||||
problematic for large amounts of projects, if it wasn't for tags.
|
||||
|
||||
By tagging a Runner for the types of jobs it can handle, you can make sure
|
||||
shared runners will only run the jobs they are equipped to run.
|
||||
shared Runners will only run the jobs they are equipped to run.
|
||||
|
||||
For instance, at GitLab we have runners tagged with "rails" if they contain
|
||||
For instance, at GitLab we have Runners tagged with "rails" if they contain
|
||||
the appropriate dependencies to run Rails test suites.
|
||||
|
||||
### Prevent runner with tags from picking jobs without tags
|
||||
### Prevent Runner with tags from picking jobs without tags
|
||||
|
||||
You can configure a runner to prevent it from picking jobs with tags when
|
||||
the runner does not have tags assigned. This setting is available on each
|
||||
runner in *Project Settings* > *Runners*.
|
||||
You can configure a Runner to prevent it from picking jobs with tags when
|
||||
the Runner does not have tags assigned. This setting is available on each
|
||||
Runner in *Project Settings* > *Runners*.
|
||||
|
||||
### Be careful with sensitive information
|
||||
|
||||
If you can run a build on a runner, you can get access to any code it runs
|
||||
and get the token of the runner. With shared runners, this means that anyone
|
||||
that runs jobs on the runner, can access anyone else's code that runs on the runner.
|
||||
If you can run a job on a Runner, you can get access to any code it runs
|
||||
and get the token of the Runner. With shared Runners, this means that anyone
|
||||
that runs jobs on the Runner, can access anyone else's code that runs on the Runner.
|
||||
|
||||
In addition, because you can get access to the runner token, it is possible
|
||||
to create a clone of a runner and submit false builds, for example.
|
||||
In addition, because you can get access to the Runner token, it is possible
|
||||
to create a clone of a Runner and submit false jobs, for example.
|
||||
|
||||
The above is easily avoided by restricting the usage of shared runners
|
||||
The above is easily avoided by restricting the usage of shared Runners
|
||||
on large public GitLab instances and controlling access to your GitLab instance.
|
||||
|
||||
### Forks
|
||||
|
||||
Whenever a project is forked, it copies the settings of the jobs that relate
|
||||
to it. This means that if you have shared runners setup for a project and
|
||||
someone forks that project, the shared runners will also serve jobs of this
|
||||
to it. This means that if you have shared Runners setup for a project and
|
||||
someone forks that project, the shared Runners will also serve jobs of this
|
||||
project.
|
||||
|
||||
## Attack vectors in Runners
|
||||
|
||||
Mentioned briefly earlier, but the following things of runners can be exploited.
|
||||
We're always looking for contributions that can mitigate these [Security Considerations](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/security/index.md).
|
||||
Mentioned briefly earlier, but the following things of Runners can be exploited.
|
||||
We're always looking for contributions that can mitigate these
|
||||
[Security Considerations](https://docs.gitlab.com/runner/security/).
|
||||
|
|
|
@ -31,7 +31,7 @@ Database: el_duderino
|
|||
```
|
||||
|
||||
If you are wondering why we used `mysql` for the `Host`, read more at
|
||||
[How is service linked to the build](../docker/using_docker_images.md#how-is-service-linked-to-the-build).
|
||||
[How is service linked to the job](../docker/using_docker_images.md#how-is-service-linked-to-the-job).
|
||||
|
||||
You can also use any other docker image available on [Docker Hub][hub-mysql].
|
||||
For example, to use MySQL 5.5 the service becomes `mysql:5.5`.
|
||||
|
@ -112,7 +112,7 @@ convenience that runs on [GitLab.com](https://gitlab.com) using our publicly
|
|||
available [shared runners](../runners/README.md).
|
||||
|
||||
Want to hack on it? Simply fork it, commit and push your changes. Within a few
|
||||
moments the changes will be picked by a public runner and the build will begin.
|
||||
moments the changes will be picked by a public runner and the job will begin.
|
||||
|
||||
[hub-mysql]: https://hub.docker.com/r/_/mysql/
|
||||
[mysql-example-repo]: https://gitlab.com/gitlab-examples/mysql
|
||||
|
|
|
@ -31,7 +31,7 @@ Database: nice_marmot
|
|||
```
|
||||
|
||||
If you are wondering why we used `postgres` for the `Host`, read more at
|
||||
[How is service linked to the build](../docker/using_docker_images.md#how-is-service-linked-to-the-build).
|
||||
[How is service linked to the job](../docker/using_docker_images.md#how-is-service-linked-to-the-job).
|
||||
|
||||
You can also use any other docker image available on [Docker Hub][hub-pg].
|
||||
For example, to use PostgreSQL 9.3 the service becomes `postgres:9.3`.
|
||||
|
@ -108,7 +108,7 @@ convenience that runs on [GitLab.com](https://gitlab.com) using our publicly
|
|||
available [shared runners](../runners/README.md).
|
||||
|
||||
Want to hack on it? Simply fork it, commit and push your changes. Within a few
|
||||
moments the changes will be picked by a public runner and the build will begin.
|
||||
moments the changes will be picked by a public runner and the job will begin.
|
||||
|
||||
[hub-pg]: https://hub.docker.com/r/_/postgres/
|
||||
[postgres-example-repo]: https://gitlab.com/gitlab-examples/postgres
|
||||
|
|
|
@ -63,7 +63,7 @@ that runs on [GitLab.com](https://gitlab.com) using our publicly available
|
|||
[shared runners](../runners/README.md).
|
||||
|
||||
Want to hack on it? Simply fork it, commit and push your changes. Within a few
|
||||
moments the changes will be picked by a public runner and the build will begin.
|
||||
moments the changes will be picked by a public runner and the job will begin.
|
||||
|
||||
[hub-redis]: https://hub.docker.com/r/_/redis/
|
||||
[redis-example-repo]: https://gitlab.com/gitlab-examples/redis
|
||||
|
|