Commit cc0c2d18 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'master' into 'zj-remove-deprecated-ci-service'

# Conflicts:
#   db/schema.rb
parents 178b6014 4ca6a719
...@@ -12,12 +12,18 @@ ...@@ -12,12 +12,18 @@
"localStorage": false "localStorage": false
}, },
"plugins": [ "plugins": [
"filenames" "filenames",
"import"
], ],
"settings": {
"import/resolver": {
"webpack": {
"config": "./config/webpack.config.js"
}
}
},
"rules": { "rules": {
"filenames/match-regex": [2, "^[a-z0-9_]+(.js)?$"], "filenames/match-regex": [2, "^[a-z0-9_]+(.js)?$"],
"no-multiple-empty-lines": ["error", { "max": 1 }], "no-multiple-empty-lines": ["error", { "max": 1 }]
"import/no-extraneous-dependencies": "off",
"import/no-unresolved": "off"
} }
} }
...@@ -107,7 +107,10 @@ setup-test-env: ...@@ -107,7 +107,10 @@ setup-test-env:
<<: *dedicated-runner <<: *dedicated-runner
stage: prepare stage: prepare
script: script:
- npm install - node --version
- yarn --version
- yarn install --pure-lockfile
- yarn check # ensure that yarn.lock matches package.json
- bundle exec rake gitlab:assets:compile - bundle exec rake gitlab:assets:compile
- bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init' - bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
artifacts: artifacts:
...@@ -246,13 +249,12 @@ karma: ...@@ -246,13 +249,12 @@ karma:
<<: *use-db <<: *use-db
<<: *dedicated-runner <<: *dedicated-runner
script: script:
- npm link istanbul
- bundle exec rake karma - bundle exec rake karma
artifacts: artifacts:
name: coverage-javascript name: coverage-javascript
expire_in: 31d expire_in: 31d
paths: paths:
- coverage-javascript/default/ - coverage-javascript/
lint-doc: lint-doc:
stage: test stage: test
...@@ -325,11 +327,9 @@ lint:javascript: ...@@ -325,11 +327,9 @@ lint:javascript:
paths: paths:
- node_modules/ - node_modules/
stage: test stage: test
image: "node:7.1" before_script: []
before_script:
- npm install
script: script:
- npm --silent run eslint - yarn run eslint
lint:javascript:report: lint:javascript:report:
<<: *dedicated-runner <<: *dedicated-runner
...@@ -337,12 +337,10 @@ lint:javascript:report: ...@@ -337,12 +337,10 @@ lint:javascript:report:
paths: paths:
- node_modules/ - node_modules/
stage: post-test stage: post-test
image: "node:7.1" before_script: []
before_script:
- npm install
script: script:
- find app/ spec/ -name '*.js' -or -name '*.js.es6' -exec sed --in-place 's|/\* eslint-disable .*\*/||' {} \; # run report over all files - find app/ spec/ -name '*.js' -or -name '*.js.es6' -exec sed --in-place 's|/\* eslint-disable .*\*/||' {} \; # run report over all files
- npm --silent run eslint-report || true # ignore exit code - yarn run eslint-report || true # ignore exit code
artifacts: artifacts:
name: eslint-report name: eslint-report
expire_in: 31d expire_in: 31d
...@@ -395,7 +393,7 @@ pages: ...@@ -395,7 +393,7 @@ pages:
- mv public/ .public/ - mv public/ .public/
- mkdir public/ - mkdir public/
- mv coverage/ public/coverage-ruby/ || true - mv coverage/ public/coverage-ruby/ || true
- mv coverage-javascript/default/ public/coverage-javascript/ || true - mv coverage-javascript/ public/coverage-javascript/ || true
- mv eslint-report.html public/ || true - mv eslint-report.html public/ || true
artifacts: artifacts:
paths: paths:
......
...@@ -2,6 +2,13 @@ ...@@ -2,6 +2,13 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
## 8.16.5 (2017-02-14)
- Patch Asciidocs rendering to block XSS.
- Fix XSS vulnerability in SVG attachments.
- Prevent the GitHub importer from assigning labels and comments to merge requests or issues belonging to other projects.
- Patch XSS vulnerability in RDOC support.
## 8.16.4 (2017-02-02) ## 8.16.4 (2017-02-02)
- Support non-ASCII characters in GFM autocomplete. !8729 - Support non-ASCII characters in GFM autocomplete. !8729
...@@ -174,6 +181,13 @@ entry. ...@@ -174,6 +181,13 @@ entry.
- Add margin to markdown math blocks. - Add margin to markdown math blocks.
- Add hover state to MR comment reply button. - Add hover state to MR comment reply button.
## 8.15.6 (2017-02-14)
- Patch Asciidocs rendering to block XSS.
- Fix XSS vulnerability in SVG attachments.
- Prevent the GitHub importer from assigning labels and comments to merge requests or issues belonging to other projects.
- Patch XSS vulnerability in RDOC support.
## 8.15.4 (2017-01-09) ## 8.15.4 (2017-01-09)
- Make successful pipeline emails off for watchers. !8176 - Make successful pipeline emails off for watchers. !8176
...@@ -437,6 +451,13 @@ entry. ...@@ -437,6 +451,13 @@ entry.
- Whitelist next project names: help, ci, admin, search. !8227 - Whitelist next project names: help, ci, admin, search. !8227
- Adds back CSS for progress-bars. !8237 - Adds back CSS for progress-bars. !8237
## 8.14.9 (2017-02-14)
- Patch Asciidocs rendering to block XSS.
- Fix XSS vulnerability in SVG attachments.
- Prevent the GitHub importer from assigning labels and comments to merge requests or issues belonging to other projects.
- Patch XSS vulnerability in RDOC support.
## 8.14.8 (2017-01-25) ## 8.14.8 (2017-01-25)
- Accept environment variables from the `pre-receive` script. !7967 - Accept environment variables from the `pre-receive` script. !7967
......
...@@ -29,6 +29,7 @@ gem 'omniauth-github', '~> 1.1.1' ...@@ -29,6 +29,7 @@ gem 'omniauth-github', '~> 1.1.1'
gem 'omniauth-gitlab', '~> 1.0.2' gem 'omniauth-gitlab', '~> 1.0.2'
gem 'omniauth-google-oauth2', '~> 0.4.1' gem 'omniauth-google-oauth2', '~> 0.4.1'
gem 'omniauth-kerberos', '~> 0.3.0', group: :kerberos gem 'omniauth-kerberos', '~> 0.3.0', group: :kerberos
gem 'omniauth-oauth2-generic', '~> 0.2.2'
gem 'omniauth-saml', '~> 1.7.0' gem 'omniauth-saml', '~> 1.7.0'
gem 'omniauth-shibboleth', '~> 1.2.0' gem 'omniauth-shibboleth', '~> 1.2.0'
gem 'omniauth-twitter', '~> 1.2.0' gem 'omniauth-twitter', '~> 1.2.0'
......
...@@ -483,6 +483,8 @@ GEM ...@@ -483,6 +483,8 @@ GEM
omniauth-oauth2 (1.3.1) omniauth-oauth2 (1.3.1)
oauth2 (~> 1.0) oauth2 (~> 1.0)
omniauth (~> 1.2) omniauth (~> 1.2)
omniauth-oauth2-generic (0.2.2)
omniauth-oauth2 (~> 1.0)
omniauth-saml (1.7.0) omniauth-saml (1.7.0)
omniauth (~> 1.3) omniauth (~> 1.3)
ruby-saml (~> 1.4) ruby-saml (~> 1.4)
...@@ -931,6 +933,7 @@ DEPENDENCIES ...@@ -931,6 +933,7 @@ DEPENDENCIES
omniauth-gitlab (~> 1.0.2) omniauth-gitlab (~> 1.0.2)
omniauth-google-oauth2 (~> 0.4.1) omniauth-google-oauth2 (~> 0.4.1)
omniauth-kerberos (~> 0.3.0) omniauth-kerberos (~> 0.3.0)
omniauth-oauth2-generic (~> 0.2.2)
omniauth-saml (~> 1.7.0) omniauth-saml (~> 1.7.0)
omniauth-shibboleth (~> 1.2.0) omniauth-shibboleth (~> 1.2.0)
omniauth-twitter (~> 1.2.0) omniauth-twitter (~> 1.2.0)
......
...@@ -56,8 +56,7 @@ requireAll(require.context('./u2f', false, /^\.\/.*\.(js|es6)$/)); ...@@ -56,8 +56,7 @@ requireAll(require.context('./u2f', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./droplab', false, /^\.\/.*\.(js|es6)$/)); requireAll(require.context('./droplab', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('.', false, /^\.\/(?!application\.js).*\.(js|es6)$/)); requireAll(require.context('.', false, /^\.\/(?!application\.js).*\.(js|es6)$/));
require('vendor/fuzzaldrin-plus'); require('vendor/fuzzaldrin-plus');
window.ES6Promise = require('vendor/es6-promise.auto'); require('es6-promise').polyfill();
window.ES6Promise.polyfill();
(function () { (function () {
document.addEventListener('beforeunload', function () { document.addEventListener('beforeunload', function () {
......
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
Vue.filter('due-date', (value) => { Vue.filter('due-date', (value) => {
const date = new Date(value); const date = new Date(value);
return dateFormat(date, 'mmm d, yyyy'); return dateFormat(date, 'mmm d, yyyy', true);
}); });
...@@ -20,7 +20,10 @@ $(() => { ...@@ -20,7 +20,10 @@ $(() => {
gl.commits.PipelinesTableBundle.$destroy(true); gl.commits.PipelinesTableBundle.$destroy(true);
} }
gl.commits.pipelines.PipelinesTableBundle = new gl.commits.pipelines.PipelinesTableView({ const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
el: 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);
}
}); });
...@@ -8,7 +8,22 @@ ...@@ -8,7 +8,22 @@
* Uses Vue.Resource * Uses Vue.Resource
*/ */
class PipelinesService { class PipelinesService {
constructor(endpoint) {
/**
* FIXME: The url provided to request the pipelines in the new merge request
* page already has `.json`.
* This should be fixed when the endpoint is improved.
*
* @param {String} root
*/
constructor(root) {
let endpoint;
if (root.indexOf('.json') === -1) {
endpoint = `${root}.json`;
} else {
endpoint = root;
}
this.pipelines = Vue.resource(endpoint); this.pipelines = Vue.resource(endpoint);
} }
......
...@@ -56,15 +56,14 @@ require('./pipelines_store'); ...@@ -56,15 +56,14 @@ require('./pipelines_store');
}, },
/** /**
* When the component is created the service to fetch the data will be * When the component is about to be mounted, tell the service to fetch the data
* initialized with the correct endpoint.
* *
* A request to fetch the pipelines will be made. * A request to fetch the pipelines will be made.
* In case of a successfull response we will store the data in the provided * 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. * store, in case of a failed response we need to warn the user.
* *
*/ */
created() { beforeMount() {
const pipelinesService = new gl.commits.pipelines.PipelinesService(this.endpoint); const pipelinesService = new gl.commits.pipelines.PipelinesService(this.endpoint);
this.isLoading = true; this.isLoading = true;
...@@ -82,8 +81,8 @@ require('./pipelines_store'); ...@@ -82,8 +81,8 @@ require('./pipelines_store');
}, },
template: ` template: `
<div> <div class="pipelines">
<div class="pipelines realtime-loading" v-if="isLoading"> <div class="realtime-loading" v-if="isLoading">
<i class="fa fa-spinner fa-spin"></i> <i class="fa fa-spinner fa-spin"></i>
</div> </div>
......
...@@ -47,9 +47,11 @@ ...@@ -47,9 +47,11 @@
} }
// Only filter asynchronously only if option remote is set // Only filter asynchronously only if option remote is set
if (this.options.remote) { if (this.options.remote) {
$inputContainer.parent().addClass('is-loading');
clearTimeout(timeout); clearTimeout(timeout);
return timeout = setTimeout(function() { return timeout = setTimeout(function() {
return this.options.query(this.input.val(), function(data) { return this.options.query(this.input.val(), function(data) {
$inputContainer.parent().removeClass('is-loading');
return this.options.callback(data); return this.options.callback(data);
}.bind(this)); }.bind(this));
}.bind(this), 250); }.bind(this), 250);
......
...@@ -61,6 +61,7 @@ require('./flash'); ...@@ -61,6 +61,7 @@ require('./flash');
constructor({ action, setUrl, stubLocation } = {}) { constructor({ action, setUrl, stubLocation } = {}) {
this.diffsLoaded = false; this.diffsLoaded = false;
this.pipelinesLoaded = false;
this.commitsLoaded = false; this.commitsLoaded = false;
this.fixedLayoutPref = null; this.fixedLayoutPref = null;
...@@ -128,6 +129,13 @@ require('./flash'); ...@@ -128,6 +129,13 @@ require('./flash');
$.scrollTo('.merge-request-details .merge-request-tabs', { $.scrollTo('.merge-request-details .merge-request-tabs', {
offset: 0, 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 { } else {
this.expandView(); this.expandView();
this.resetViewContainer(); this.resetViewContainer();
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
if (selected.id == null) { if (selected.id == null) {
return selected.text; return selected.text;
} else { } else {
return selected.kind + ": " + selected.path; return selected.kind + ": " + selected.full_path;
} }
}, },
data: function(term, dataCallback) { data: function(term, dataCallback) {
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
if (namespace.id == null) { if (namespace.id == null) {
return namespace.text; return namespace.text;
} else { } else {
return namespace.kind + ": " + namespace.path; return namespace.kind + ": " + namespace.full_path;
} }
}, },
renderRow: this.renderRow, renderRow: this.renderRow,
......
...@@ -193,7 +193,6 @@ ...@@ -193,7 +193,6 @@
top: $header-height; top: $header-height;
bottom: 0; bottom: 0;
right: 0; right: 0;
z-index: 8;
transition: width .3s; transition: width .3s;
background: $gray-light; background: $gray-light;
padding: 10px 20px; padding: 10px 20px;
......
...@@ -864,7 +864,7 @@ ...@@ -864,7 +864,7 @@
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
width: 90px; max-width: 70%;
color: $gl-text-color-secondary; color: $gl-text-color-secondary;
margin-left: 2px; margin-left: 2px;
display: inline-block; display: inline-block;
......
...@@ -35,13 +35,9 @@ ...@@ -35,13 +35,9 @@
margin-bottom: 10px; margin-bottom: 10px;
} }
.project-path { .project-path .form-control {
padding-right: 0;
.form-control {
border-radius: $border-radius-base; border-radius: $border-radius-base;
} }
}
.input-group > div { .input-group > div {
......
...@@ -171,6 +171,8 @@ ...@@ -171,6 +171,8 @@
.tree-controls { .tree-controls {
float: right; float: right;
margin-top: 11px; margin-top: 11px;
position: relative;
z-index: 2;
.project-action-button { .project-action-button {
margin-left: $btn-side-margin; margin-left: $btn-side-margin;
......
...@@ -84,7 +84,7 @@ class Projects::WikisController < Projects::ApplicationController ...@@ -84,7 +84,7 @@ class Projects::WikisController < Projects::ApplicationController
def destroy def destroy
@page = @project_wiki.find_page(params[:id]) @page = @project_wiki.find_page(params[:id])
@page&.delete WikiPages::DestroyService.new(@project, current_user).execute(@page)
redirect_to( redirect_to(
namespace_project_wiki_path(@project.namespace, @project, :home), namespace_project_wiki_path(@project.namespace, @project, :home),
......
...@@ -75,10 +75,10 @@ module MergeRequestsHelper ...@@ -75,10 +75,10 @@ module MergeRequestsHelper
new_namespace_project_merge_request_path( new_namespace_project_merge_request_path(
@project.namespace, @project, @project.namespace, @project,
merge_request: { merge_request: {
source_project_id: @merge_request.source_project_id, source_project_id: merge_request.source_project_id,
target_project_id: @merge_request.target_project_id, target_project_id: merge_request.target_project_id,
source_branch: @merge_request.source_branch, source_branch: merge_request.source_branch,
target_branch: @merge_request.target_branch, target_branch: merge_request.target_branch,
}, },
change_branches: true change_branches: true
) )
......
...@@ -10,7 +10,7 @@ module NamespacesHelper ...@@ -10,7 +10,7 @@ module NamespacesHelper
data_attr_users = { 'data-options-parent' => 'users' } data_attr_users = { 'data-options-parent' => 'users' }
group_opts = [ 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 = [ users_opts = [
......
...@@ -63,7 +63,7 @@ module SubmoduleHelper ...@@ -63,7 +63,7 @@ module SubmoduleHelper
namespace = components.pop.gsub(/^\.\.$/, '') namespace = components.pop.gsub(/^\.\.$/, '')
if namespace.empty? if namespace.empty?
namespace = @project.namespace.path namespace = @project.namespace.full_path
end end
[ [
......
...@@ -45,9 +45,10 @@ class Event < ActiveRecord::Base ...@@ -45,9 +45,10 @@ class Event < ActiveRecord::Base
class << self class << self
# Update Gitlab::ContributionsCalendar#activity_dates if this changes # Update Gitlab::ContributionsCalendar#activity_dates if this changes
def contributions def contributions
where("action = ? OR (target_type in (?) AND action in (?))", where("action = ? OR (target_type IN (?) AND action IN (?)) OR (target_type = ? AND action = ?)",
Event::PUSHED, ["MergeRequest", "Issue"], Event::PUSHED,
[Event::CREATED, Event::CLOSED, Event::MERGED]) ["MergeRequest", "Issue"], [Event::CREATED, Event::CLOSED, Event::MERGED],
"Note", Event::COMMENTED)
end end
def limit_recent(limit = 20, offset = nil) def limit_recent(limit = 20, offset = nil)
......
...@@ -81,7 +81,7 @@ class Group < Namespace ...@@ -81,7 +81,7 @@ class Group < Namespace
end end
def to_reference(_from_project = nil, full: nil) def to_reference(_from_project = nil, full: nil)
"#{self.class.reference_prefix}#{name}" "#{self.class.reference_prefix}#{full_path}"
end end
def web_url def web_url
......
...@@ -598,7 +598,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -598,7 +598,7 @@ class MergeRequest < ActiveRecord::Base
def source_project_namespace def source_project_namespace
if source_project && source_project.namespace if source_project && source_project.namespace
source_project.namespace.path source_project.namespace.full_path
else else
"(removed)" "(removed)"
end end
...@@ -606,7 +606,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -606,7 +606,7 @@ class MergeRequest < ActiveRecord::Base
def target_project_namespace def target_project_namespace
if target_project && target_project.namespace if target_project && target_project.namespace
target_project.namespace.path target_project.namespace.full_path
else else
"(removed)" "(removed)"
end end
......
...@@ -454,7 +454,7 @@ class Project < ActiveRecord::Base ...@@ -454,7 +454,7 @@ class Project < ActiveRecord::Base
if forked? if forked?
job_id = RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path, job_id = RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path,
forked_from_project.path_with_namespace, forked_from_project.path_with_namespace,
self.namespace.path) self.namespace.full_path)
else else
job_id = RepositoryImportWorker.perform_async(self.id) job_id = RepositoryImportWorker.perform_async(self.id)
end end
...@@ -942,8 +942,8 @@ class Project < ActiveRecord::Base ...@@ -942,8 +942,8 @@ class Project < ActiveRecord::Base
Gitlab::AppLogger.info "Project was renamed: #{old_path_with_namespace} -> #{new_path_with_namespace}" 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::UploadsTransfer.new.rename_project(path_was, path, namespace.full_path)
Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.path) Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.full_path)
end end
# Expires various caches before a project is renamed. # Expires various caches before a project is renamed.
...@@ -1150,19 +1150,25 @@ class Project < ActiveRecord::Base ...@@ -1150,19 +1150,25 @@ class Project < ActiveRecord::Base
end end
def pages_url def pages_url
subdomain, _, url_path = full_path.partition('/')
# The hostname always needs to be in downcased # The hostname always needs to be in downcased
# All web servers convert hostname to lowercase # 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 # The host in URL always needs to be downcased
url = Gitlab.config.pages.url.sub(/^https?:\/\//) do |prefix| url = Gitlab.config.pages.url.sub(/^https?:\/\//) do |prefix|
"#{prefix}#{namespace.path}." "#{prefix}#{subdomain}."
end.downcase end.downcase
# If the project path is the same as host, we serve it as group page # 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}/#{url_path}"
end
"#{url}/#{path}" def pages_subdomain
full_path.partition('/').first
end end
def pages_path def pages_path
...@@ -1179,8 +1185,8 @@ class Project < ActiveRecord::Base ...@@ -1179,8 +1185,8 @@ class Project < ActiveRecord::Base
# 3. We asynchronously remove pages with force # 3. We asynchronously remove pages with force
temp_path = "#{path}.#{SecureRandom.hex}.deleted" temp_path = "#{path}.#{SecureRandom.hex}.deleted"
if Gitlab::PagesTransfer.new.rename_project(path, temp_path, namespace.path) if Gitlab::PagesTransfer.new.rename_project(path, temp_path, namespace.full_path)
PagesWorker.perform_in(5.minutes, :remove, namespace.path, temp_path) PagesWorker.perform_in(5.minutes, :remove, namespace.full_path, temp_path)
end end
end end
...@@ -1230,7 +1236,7 @@ class Project < ActiveRecord::Base ...@@ -1230,7 +1236,7 @@ class Project < ActiveRecord::Base
end end
def ensure_dir_exist def ensure_dir_exist
gitlab_shell.add_namespace(repository_storage_path, namespace.path) gitlab_shell.add_namespace(repository_storage_path, namespace.full_path)
end end
def predefined_variables def predefined_variables
...@@ -1238,7 +1244,7 @@ class Project < ActiveRecord::Base ...@@ -1238,7 +1244,7 @@ class Project < ActiveRecord::Base
{ key: 'CI_PROJECT_ID', value: id.to_s, public: true }, { key: 'CI_PROJECT_ID', value: id.to_s, public: true },
{ key: 'CI_PROJECT_NAME', value: path, public: true }, { key: 'CI_PROJECT_NAME', value: path, public: true },
{ key: 'CI_PROJECT_PATH', value: path_with_namespace, 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 } { key: 'CI_PROJECT_URL', value: web_url, public: true }
] ]
end end
......
...@@ -12,7 +12,7 @@ class DroneCiService < CiService ...@@ -12,7 +12,7 @@ class DroneCiService < CiService
def compose_service_hook def compose_service_hook
hook = service_hook || build_service_hook hook = service_hook || build_service_hook
# If using a service template, project may not be available # 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.enable_ssl_verification = !!enable_ssl_verification
hook.save hook.save
end end
...@@ -38,7 +38,7 @@ class DroneCiService < CiService ...@@ -38,7 +38,7 @@ class DroneCiService < CiService
def commit_status_path(sha, ref) def commit_status_path(sha, ref)
url = [drone_url, 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}"] "?branch=#{URI::encode(ref.to_s)}&access_token=#{token}"]
URI.join(*url).to_s URI.join(*url).to_s
...@@ -73,7 +73,7 @@ class DroneCiService < CiService ...@@ -73,7 +73,7 @@ class DroneCiService < CiService
def build_page(sha, ref) def build_page(sha, ref)
url = [drone_url, 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)}"] "?branch=#{URI::encode(ref.to_s)}"]
URI.join(*url).to_s URI.join(*url).to_s
......
...@@ -335,7 +335,7 @@ class User < ActiveRecord::Base ...@@ -335,7 +335,7 @@ class User < ActiveRecord::Base
def reference_pattern def reference_pattern
%r{ %r{
#{Regexp.escape(reference_prefix)} #{Regexp.escape(reference_prefix)}
(?<user>#{Gitlab::Regex::NAMESPACE_REGEX_STR}) (?<user>#{Gitlab::Regex::NAMESPACE_REF_REGEX_STR})
}x }x
end end
end end
......
...@@ -207,6 +207,10 @@ class WikiPage ...@@ -207,6 +207,10 @@ class WikiPage
'projects/wikis/wiki_page' 'projects/wikis/wiki_page'
end end
def id
page.version.to_s
end
private private
def set_attributes def set_attributes
......
...@@ -36,7 +36,7 @@ module Projects ...@@ -36,7 +36,7 @@ module Projects
def groups def groups
current_user.authorized_groups.sort_by(&:path).map do |group| current_user.authorized_groups.sort_by(&:path).map do |group|
count = group.users.count count = group.users.count
{ username: group.path, name: group.name, count: count, avatar_url: group.avatar_url } { username: group.full_path, name: group.full_name, count: count, avatar_url: group.avatar_url }
end end
end end
......
...@@ -30,7 +30,7 @@ module Projects ...@@ -30,7 +30,7 @@ module Projects
Project.transaction do Project.transaction do
old_path = project.path_with_namespace old_path = project.path_with_namespace
old_group = project.group 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? 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") raise TransferError.new("Project with same path in target namespace already exists")
...@@ -63,10 +63,10 @@ module Projects ...@@ -63,10 +63,10 @@ module Projects
Labels::TransferService.new(current_user, old_group, project).execute Labels::TransferService.new(current_user, old_group, project).execute
# Move uploads # 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 # 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 project.old_path_with_namespace = old_path
......
module WikiPages
class DestroyService < WikiPages::BaseService
def execute(page)
if page&.delete
execute_hooks(page, 'delete')
end
page
end
end
end
...@@ -163,6 +163,6 @@ ...@@ -163,6 +163,6 @@
- @groups.each do |group| - @groups.each do |group|
%p %p
= link_to [:admin, group], class: 'str-truncated-60' do = link_to [:admin, group], class: 'str-truncated-60' do
= group.name = group.full_name
%span.light.pull-right %span.light.pull-right
#{time_ago_with_tooltip(group.created_at)} #{time_ago_with_tooltip(group.created_at)}
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
- toggle_text = 'Namespace' - toggle_text = 'Namespace'
- if params[:namespace_id].present? - if params[:namespace_id].present?
- namespace = Namespace.find(params[:namespace_id]) - 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_toggle(toggle_text, { toggle: 'dropdown' }, { toggle_class: 'js-namespace-select large' })
.dropdown-menu.dropdown-select.dropdown-menu-align-right .dropdown-menu.dropdown-select.dropdown-menu-align-right
= dropdown_title('Namespaces') = dropdown_title('Namespaces')
......
%ul.nav-links .top-area
%ul.nav-links
%li{ class: ("active" unless params[:filter]) }> %li{ class: ("active" unless params[:filter]) }>
= link_to activity_dashboard_path, class: 'shortcuts-activity', data: {placement: 'right'} do = link_to activity_dashboard_path, class: 'shortcuts-activity', data: {placement: 'right'} do
Your Projects Your Projects
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import_button = tr.find(".btn-import") import_button = tr.find(".btn-import")
origin_target = target_field.text() origin_target = target_field.text()
project_name = "#{@project_name}" project_name = "#{@project_name}"
origin_namespace = "#{@target_namespace.path}" origin_namespace = "#{@target_namespace.full_path}"
target_field.empty() 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("<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' />") target_field.append("<input type='text' name='target_namespace' />")
......
#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"), .pipeline-svgs{ data: { "commit_icon_svg" => custom_icon("icon_commit"),
"icon_status_canceled" => custom_icon("icon_status_canceled"), "icon_status_canceled" => custom_icon("icon_status_canceled"),
"icon_status_running" => custom_icon("icon_status_running"), "icon_status_running" => custom_icon("icon_status_running"),
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
.col-lg-9 .col-lg-9
.project-edit-errors .project-edit-errors
= form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit-project" }, authenticity_token: true do |f| = 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 .row
.form-group.col-md-9 .form-group.col-md-9
= f.label :name, class: 'label-light', for: 'project_name_edit' do = f.label :name, class: 'label-light', for: 'project_name_edit' do
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
= f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control" = f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control"
%p.help-block Separate tags with commas. %p.help-block Separate tags with commas.
%hr %hr
%fieldset.append-bottom-0 %fieldset
%h5.prepend-top-0 %h5.prepend-top-0
Sharing &amp; Permissions Sharing &amp; Permissions
.form_group.prepend-top-20.sharing-and-permissions .form_group.prepend-top-20.sharing-and-permissions
...@@ -232,7 +232,7 @@ ...@@ -232,7 +232,7 @@
.form-group .form-group
.input-group .input-group
.input-group-addon .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' = f.text_field :path, class: 'form-control'
%ul %ul
%li Be careful. Renaming a project's repository can have unintended side effects. %li Be careful. Renaming a project's repository can have unintended side effects.
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
= icon("folder-open-o", class: "settings-list-icon") = icon("folder-open-o", class: "settings-list-icon")
.pull-left .pull-left
= link_to group do = link_to group do
= group.name = group.full_name
%br %br
up to #{group_link.human_access} up to #{group_link.human_access}
- if group_link.expires? - if group_link.expires?
......
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
-# This tab is always loaded via AJAX -# This tab is always loaded via AJAX
#pipelines.pipelines.tab-pane #pipelines.pipelines.tab-pane
- if @pipelines.any? - 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 #diffs.diffs.tab-pane
-# This tab is always loaded via AJAX -# This tab is always loaded via AJAX
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
Create or Import your project from popular Git services Create or Import your project from popular Git services
.col-lg-9 .col-lg-9
= form_for @project, html: { class: 'new_project' } do |f| = form_for @project, html: { class: 'new_project' } do |f|
%fieldset.append-bottom-0 .row
.form-group.col-xs-12.col-sm-6 .form-group.col-xs-12.col-sm-6
= f.label :namespace_id, class: 'label-light' do = f.label :namespace_id, class: 'label-light' do
%span %span
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
%p %p
To access the domain create a new DNS record: To access the domain create a new DNS record:
%pre %pre
#{@domain.domain} CNAME #{@domain.project.namespace.path}.#{Settings.pages.host}. #{@domain.domain} CNAME #{@domain.project.pages_subdomain}.#{Settings.pages.host}.
%tr %tr
%td %td
Certificate Certificate
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
%span.list-item-name %span.list-item-name
= image_tag group_icon(group), class: "avatar s40", alt: '' = image_tag group_icon(group), class: "avatar s40", alt: ''
%strong %strong
= link_to group.name, group_path(group) = link_to group.full_name, group_path(group)
.cgray .cgray
Joined #{time_ago_with_tooltip(group.created_at)} Joined #{time_ago_with_tooltip(group.created_at)}
- if group_link.expires? - if group_link.expires?
......
.clearfix.calendar .clearfix.calendar
.js-contrib-calendar .js-contrib-calendar
.calendar-hint .calendar-hint
Summary of issues, merge requests, and push events Summary of issues, merge requests, push events, and comments
:javascript :javascript
new Calendar( new Calendar(
#{@activity_dates.to_json}, #{@activity_dates.to_json},
......
...@@ -10,11 +10,17 @@ ...@@ -10,11 +10,17 @@
%i.fa.fa-clock-o %i.fa.fa-clock-o
= event.created_at.to_s(:time) = event.created_at.to_s(:time)
- if event.push? - if event.push?
#{event.action_name} #{event.ref_type} #{event.ref_name} #{event.action_name} #{event.ref_type}
%strong
- commits_path = namespace_project_commits_path(event.project.namespace, event.project, event.ref_name)
= link_to_if event.project.repository.branch_exists?(event.ref_name), event.ref_name, commits_path
- else - else
= event_action_name(event) = event_action_name(event)
- if event.target %strong
%strong= link_to "#{event.target.to_reference}", [event.project.namespace.becomes(Namespace), event.project, event.target] - if event.note?
= link_to event.note_target.to_reference, event_note_target_path(event)
- elsif event.target
= link_to event.target.to_reference, [event.project.namespace.becomes(Namespace), event.project, event.target]
at at
%strong %strong
......
...@@ -106,6 +106,8 @@ ...@@ -106,6 +106,8 @@
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
.user-calendar-activities .user-calendar-activities
%h4.prepend-top-20
Most Recent Activity
.content_list{ data: { href: user_path } } .content_list{ data: { href: user_path } }
= spinner = spinner
......
---
title: Move /projects/fork/:id to /projects/:id/fork
merge_request: 8940
author:
---
title: Execute web hooks for WikiPage delete operation
merge_request: 8198
author:
---
title: Add discussion events to contributions calendar
merge_request: 8821
author:
---
title: 'API: Consolidate /projects endpoint'
merge_request: 8962
author:
---
title: Added 'Most Recent Activity' header to the User Profile page
merge_request: 9189
author: Jan Christophersen
---
title: Add Links to Branches in Calendar Activity
merge_request: 9224
author: Jan Christophersen
title: Add the oauth2_generic OmniAuth strategy
merge_request: 9048
author: Joe Marty
\ No newline at end of file
---
title: "Fix small height of activity header page"
merge_request: 8952
author: Pavel Sorokin
---
title: Update doc for enabling or disabling GitLab CI
merge_request: 8965
author: Takuya Noguchi
---
title: Set maximum width for mini pipeline graph text so it is not truncated to early
merge_request: 9188
author:
---
title: Fix stray pipelines API request when showing MR
merge_request:
author:
---
title: Fix Merge request pipelines displays JSON
merge_request:
author:
---
title: Display loading indicator when filtering ref switcher dropdown
merge_request:
author:
---
title: Fix z index issues with sidebar
merge_request:
author:
---
title: Centers loading icon vertically and horizontally in pipelines table in commit
view
merge_request:
author:
---
title: Reintroduce coverage report for JavaScript
merge_request: 9133
author: winniehell
---
title: Replace static fixture for right_sidebar_spec.js
merge_request: 9211
author: winniehell
---
title: Don't connect in Gitlab::Database.adapter_name
merge_request:
author:
---
title: Fix timezone on issue boards due date
merge_request:
author:
---
title: Disable invalid service templates
merge_request:
author:
---
title: Make it possible to pass coverage value to commit status API
merge_request: 9214
author: wendy0402
---
title: Remove inactive default email services
merge_request: 8987
author:
---
title: replace npm with yarn and add yarn.lock
merge_request: 9055
author:
---
title: Replace static fixture for behaviors/requires_input_spec.js
merge_request: 9162
author: winniehell
...@@ -15,6 +15,13 @@ module.exports = function(config) { ...@@ -15,6 +15,13 @@ module.exports = function(config) {
preprocessors: { preprocessors: {
'spec/javascripts/**/*.js?(.es6)': ['webpack', 'sourcemap'], 'spec/javascripts/**/*.js?(.es6)': ['webpack', 'sourcemap'],
}, },
reporters: ['progress', 'coverage-istanbul'],
coverageIstanbulReporter: {
reports: ['html', 'text-summary'],
dir: 'coverage-javascript/',
subdir: '.',
fixWebpackSourcePaths: true
},
webpack: webpackConfig, webpack: webpackConfig,
webpackMiddleware: { stats: 'errors-only' }, webpackMiddleware: { stats: 'errors-only' },
}); });
......
...@@ -54,6 +54,7 @@ var config = { ...@@ -54,6 +54,7 @@ var config = {
exclude: /(node_modules|vendor\/assets)/, exclude: /(node_modules|vendor\/assets)/,
loader: 'babel-loader', loader: 'babel-loader',
options: { options: {
plugins: ['istanbul'],
presets: [ presets: [
["es2015", {"modules": false}], ["es2015", {"modules": false}],
'stage-2' 'stage-2'
......
class RemoveInactiveDefaultEmailServices < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
Gitlab::Database.with_connection_pool(2) do |pool|
threads = []
threads << Thread.new do
pool.with_connection do |connection|
connection.execute <<-SQL.strip_heredoc
DELETE FROM services
WHERE type = 'BuildsEmailService'
AND active IS FALSE
AND properties = '{"notify_only_broken_builds":true}';
SQL
end
end
threads << Thread.new do
pool.with_connection do |connection|
connection.execute <<-SQL.strip_heredoc
DELETE FROM services
WHERE type = 'PipelinesEmailService'
AND active IS FALSE
AND properties = '{"notify_only_broken_pipelines":true}';
SQL
end
end
threads.each(&:join)
end
end
def down
# Nothing can be done to restore the records
end
end
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
# Build artifacts administration This document was moved to [jobs_artifacts](jobs_artifacts.md).
>**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).
# 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"
...@@ -444,6 +444,7 @@ POST /projects/:id/statuses/:sha ...@@ -444,6 +444,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` | `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 | `target_url` | string | no | The target URL to associate with this status
| `description` | string | no | The short description of the status | `description` | string | no | The short description of the status
| `coverage` | float | no | The total code coverage
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/17/statuses/18f3e63d05582537db6d183d9d557be09e1f90c8?state=success" curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/17/statuses/18f3e63d05582537db6d183d9d557be09e1f90c8?state=success"
...@@ -464,6 +465,7 @@ Example response: ...@@ -464,6 +465,7 @@ Example response:
"name" : "default", "name" : "default",
"sha" : "18f3e63d05582537db6d183d9d557be09e1f90c8", "sha" : "18f3e63d05582537db6d183d9d557be09e1f90c8",
"status" : "success", "status" : "success",
"coverage": 100.0,
"description" : null, "description" : null,
"id" : 93, "id" : 93,
"target_url" : null, "target_url" : null,
......
...@@ -73,6 +73,8 @@ Parameters: ...@@ -73,6 +73,8 @@ Parameters:
| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` | | `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Return list of authorized projects matching the search criteria | | `search` | string | no | Return list of authorized projects matching the search criteria |
| `simple` | boolean | no | Return only the ID, URL, name, and path of each project | | `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
| `owned` | boolean | no | Limit by projects owned by the current user |
| `starred` | boolean | no | Limit by projects starred by the current user |
Example response: Example response:
......
...@@ -35,6 +35,12 @@ Example response: ...@@ -35,6 +35,12 @@ Example response:
"id": 2, "id": 2,
"path": "group1", "path": "group1",
"kind": "group" "kind": "group"
},
{
"id": 3,
"path": "bar",
"kind": "group",
"full_path": "foo/bar",
} }
] ]
``` ```
...@@ -64,7 +70,8 @@ Example response: ...@@ -64,7 +70,8 @@ Example response:
{ {
"id": 4, "id": 4,
"path": "twitter", "path": "twitter",
"kind": "group" "kind": "group",
"full_path": "twitter",
} }
] ]
``` ```
...@@ -36,6 +36,8 @@ Parameters: ...@@ -36,6 +36,8 @@ Parameters:
| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` | | `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Return list of authorized projects matching the search criteria | | `search` | string | no | Return list of authorized projects matching the search criteria |
| `simple` | boolean | no | Return only the ID, URL, name, and path of each project | | `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
| `owned` | boolean | no | Limit by projects owned by the current user |
| `starred` | boolean | no | Limit by projects starred by the current user |
```json ```json
[ [
...@@ -75,7 +77,8 @@ Parameters: ...@@ -75,7 +77,8 @@ Parameters:
"id": 3, "id": 3,
"name": "Diaspora", "name": "Diaspora",
"path": "diaspora", "path": "diaspora",
"kind": "group" "kind": "group",
"full_path": "diaspora"
}, },
"archived": false, "archived": false,
"avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png", "avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",
...@@ -125,7 +128,8 @@ Parameters: ...@@ -125,7 +128,8 @@ Parameters:
"id": 4, "id": 4,
"name": "Brightbox", "name": "Brightbox",
"path": "brightbox", "path": "brightbox",
"kind": "group" "kind": "group",
"full_path": "brightbox"
}, },
"permissions": { "permissions": {
"project_access": { "project_access": {
...@@ -152,190 +156,6 @@ Parameters: ...@@ -152,190 +156,6 @@ Parameters:
] ]
``` ```
Get a list of projects which the authenticated user can see.
```
GET /projects/visible
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `archived` | boolean | no | Limit by archived status |
| `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
| `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Return list of authorized projects matching the search criteria |
| `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
```json
[
{
"id": 4,
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"tag_list": [
"example",
"disapora client"
],
"owner": {
"id": 3,
"name": "Diaspora",
"created_at": "2013-09-30T13:46:02Z"
},
"name": "Diaspora Client",
"name_with_namespace": "Diaspora / Diaspora Client",
"path": "diaspora-client",
"path_with_namespace": "diaspora/diaspora-client",
"issues_enabled": true,
"open_issues_count": 1,
"merge_requests_enabled": true,
"builds_enabled": true,
"wiki_enabled": true,
"snippets_enabled": false,
"container_registry_enabled": false,
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
"id": 3,
"name": "Diaspora",
"path": "diaspora",
"kind": "group"
},
"archived": false,
"avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",
"shared_runners_enabled": true,
"forks_count": 0,
"star_count": 0,
"runners_token": "b8547b1dc37721d05889db52fa2f02",
"public_builds": true,
"shared_with_groups": []
},
{
"id": 6,
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:brightbox/puppet.git",
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"tag_list": [
"example",
"puppet"
],
"owner": {
"id": 4,
"name": "Brightbox",
"created_at": "2013-09-30T13:46:02Z"
},
"name": "Puppet",
"name_with_namespace": "Brightbox / Puppet",
"path": "puppet",
"path_with_namespace": "brightbox/puppet",
"issues_enabled": true,
"open_issues_count": 1,
"merge_requests_enabled": true,
"builds_enabled": true,
"wiki_enabled": true,
"snippets_enabled": false,
"container_registry_enabled": false,
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
"id": 4,
"name": "Brightbox",
"path": "brightbox",
"kind": "group"
},
"permissions": {
"project_access": {
"access_level": 10,
"notification_level": 3
},
"group_access": {
"access_level": 50,
"notification_level": 3
}
},
"archived": false,
"avatar_url": null,
"shared_runners_enabled": true,
"forks_count": 0,
"star_count": 0,
"runners_token": "b8547b1dc37721d05889db52fa2f02",
"public_builds": true,
"shared_with_groups": []
}
]
```
### List owned projects
Get a list of projects which are owned by the authenticated user.
```
GET /projects/owned
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `archived` | boolean | no | Limit by archived status |
| `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
| `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Return list of authorized projects matching the search criteria |
| `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
| `statistics` | boolean | no | Include project statistics |
### List starred projects
Get a list of projects which are starred by the authenticated user.
```
GET /projects/starred
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `archived` | boolean | no | Limit by archived status |
| `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
| `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Return list of authorized projects matching the search criteria |
| `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
### List ALL projects
Get a list of all GitLab projects (admin only).
```
GET /projects/all
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `archived` | boolean | no | Limit by archived status |
| `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
| `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Return list of authorized projects matching the search criteria |
| `statistics` | boolean | no | Include project statistics |
### Get single project ### Get single project
Get a specific project, identified by project ID or NAMESPACE/PROJECT_NAME, which is owned by the authenticated user. Get a specific project, identified by project ID or NAMESPACE/PROJECT_NAME, which is owned by the authenticated user.
...@@ -389,7 +209,8 @@ Parameters: ...@@ -389,7 +209,8 @@ Parameters:
"id": 3, "id": 3,
"name": "Diaspora", "name": "Diaspora",
"path": "diaspora", "path": "diaspora",
"kind": "group" "kind": "group",
"full_path": "diaspora"
}, },
"permissions": { "permissions": {
"project_access": { "project_access": {
...@@ -705,7 +526,7 @@ Parameters: ...@@ -705,7 +526,7 @@ Parameters:
Forks a project into the user namespace of the authenticated user or the one provided. Forks a project into the user namespace of the authenticated user or the one provided.
``` ```
POST /projects/fork/:id POST /projects/:id/fork
``` ```
Parameters: Parameters:
...@@ -767,7 +588,8 @@ Example response: ...@@ -767,7 +588,8 @@ Example response:
"id": 3, "id": 3,
"name": "Diaspora", "name": "Diaspora",
"path": "diaspora", "path": "diaspora",
"kind": "group" "kind": "group",
"full_path": "diaspora"
}, },
"archived": true, "archived": true,
"avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png", "avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png",
...@@ -832,7 +654,8 @@ Example response: ...@@ -832,7 +654,8 @@ Example response:
"id": 3, "id": 3,
"name": "Diaspora", "name": "Diaspora",
"path": "diaspora", "path": "diaspora",
"kind": "group" "kind": "group",
"full_path": "diaspora"
}, },
"archived": true, "archived": true,
"avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png", "avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png",
...@@ -903,7 +726,8 @@ Example response: ...@@ -903,7 +726,8 @@ Example response:
"id": 3, "id": 3,
"name": "Diaspora", "name": "Diaspora",
"path": "diaspora", "path": "diaspora",
"kind": "group" "kind": "group",
"full_path": "diaspora"
}, },
"permissions": { "permissions": {
"project_access": { "project_access": {
...@@ -985,7 +809,8 @@ Example response: ...@@ -985,7 +809,8 @@ Example response:
"id": 3, "id": 3,
"name": "Diaspora", "name": "Diaspora",
"path": "diaspora", "path": "diaspora",
"kind": "group" "kind": "group",
"full_path": "diaspora"
}, },
"permissions": { "permissions": {
"project_access": { "project_access": {
......
...@@ -22,4 +22,5 @@ changes are in V4: ...@@ -22,4 +22,5 @@ changes are in V4:
- `/gitignores/:key` - `/gitignores/:key`
- `/gitlab_ci_ymls/:key` - `/gitlab_ci_ymls/:key`
- `/dockerfiles/:key` - `/dockerfiles/:key`
- Moved `/projects/fork/:id` to `/projects/:id/fork`
- Endpoints `/projects/owned`, `/projects/visible`, `/projects/starred` & `/projects/all` are consolidated into `/projects` using query parameters
...@@ -2,22 +2,22 @@ ...@@ -2,22 +2,22 @@
## CI User documentation ## 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) - [CI examples for various languages](examples/README.md)
- [Learn how to enable or disable GitLab CI](enable_or_disable_ci.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) - [Environments and deployments](environments.md)
- [Learn how `.gitlab-ci.yml` works](yaml/README.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 Docker images with GitLab Runner](docker/using_docker_images.md)
- [Use CI to build Docker images](docker/using_docker_build.md) - [Use CI to build Docker images](docker/using_docker_build.md)
- [CI Variables](variables/README.md) - Learn how to use variables defined in - [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 your `.gitlab-ci.yml` or secured ones defined in your project's settings
- [Use SSH keys in your build environment](ssh_keys/README.md) - [Use SSH keys in your build environment](ssh_keys/README.md)
- [Trigger builds through the API](triggers/README.md) - [Trigger jobs through the API](triggers/README.md)
- [Build artifacts](../user/project/builds/artifacts.md) - [Job artifacts](../user/project/pipelines/job_artifacts.md)
- [User permissions](../user/permissions.md#gitlab-ci) - [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) - [API](../api/ci/README.md)
- [CI services (linked docker containers)](services/README.md) - [CI services (linked docker containers)](services/README.md)
- [CI/CD pipelines settings](../user/project/pipelines/settings.md) - [CI/CD pipelines settings](../user/project/pipelines/settings.md)
...@@ -27,6 +27,6 @@ ...@@ -27,6 +27,6 @@
## Breaking changes ## Breaking changes
- [New CI build permissions model](../user/project/new_ci_build_permissions_model.md) - [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 builds. 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 builds. There's a new way to access your Git submodules and LFS objects in jobs.
This document was moved to: This document was moved to [user/project/job_artifacts.md](../../user/project/job_artifacts.md).
- [user/project/builds/artifacts.md](../../user/project/builds/artifacts.md) - user guide
- [administration/build_artifacts.md](../../administration/build_artifacts.md) - administrator guide
# Docker integration # Docker integration
+ [Using Docker Images](using_docker_images.md) - [Using Docker Images](using_docker_images.md)
+ [Using Docker Build](using_docker_build.md) - [Using Docker Build](using_docker_build.md)
\ No newline at end of file
...@@ -12,6 +12,7 @@ One of the new trends in Continuous Integration/Deployment is to: ...@@ -12,6 +12,7 @@ One of the new trends in Continuous Integration/Deployment is to:
1. deploy to a server from the pushed image. 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: It's also useful when your application already has the `Dockerfile` that can be used to create and test an image:
```bash ```bash
$ docker build -t my-image dockerfiles/ $ docker build -t my-image dockerfiles/
$ docker run my-docker-image /script/to/run/tests $ docker run my-docker-image /script/to/run/tests
...@@ -19,23 +20,23 @@ $ docker tag my-image my-registry:5000/my-image ...@@ -19,23 +20,23 @@ $ docker tag my-image my-registry:5000/my-image
$ docker push 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 ## 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 ### Use shell executor
The simplest approach is to install GitLab Runner in `shell` execution mode. 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. 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 ```bash
$ sudo gitlab-ci-multi-runner register -n \ sudo gitlab-ci-multi-runner register -n \
--url https://gitlab.com/ci \ --url https://gitlab.com/ci \
--registration-token REGISTRATION_TOKEN \ --registration-token REGISTRATION_TOKEN \
--executor shell \ --executor shell \
...@@ -50,16 +51,17 @@ GitLab Runner then executes build scripts as the `gitlab-runner` user. ...@@ -50,16 +51,17 @@ GitLab Runner then executes build scripts as the `gitlab-runner` user.
3. Add `gitlab-runner` user to `docker` group: 3. Add `gitlab-runner` user to `docker` group:
```bash ```bash
$ sudo usermod -aG docker gitlab-runner sudo usermod -aG docker gitlab-runner
``` ```
4. Verify that `gitlab-runner` has access to Docker: 4. Verify that `gitlab-runner` has access to Docker:
```bash ```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`: You can now verify that everything works by adding `docker info` to `.gitlab-ci.yml`:
```yaml ```yaml
before_script: before_script:
- docker info - docker info
...@@ -80,12 +82,12 @@ For more information please read [On Docker security: `docker` group considered ...@@ -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) The second approach is to use the special docker-in-docker (dind)
[Docker image](https://hub.docker.com/_/docker/) with all tools installed [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. image in privileged mode.
In order to do that, follow the steps: 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` 1. Register GitLab Runner from the command line to use `docker` and `privileged`
mode: mode:
...@@ -155,10 +157,10 @@ not without its own challenges: ...@@ -155,10 +157,10 @@ not without its own challenges:
escalation which can lead to container breakout. For more information, check escalation which can lead to container breakout. For more information, check
out the official Docker documentation on out the official Docker documentation on
[Runtime privilege and Linux capabilities][docker-cap]. [Runtime privilege and Linux capabilities][docker-cap].
- Using docker-in-docker, each build is in a clean environment without the past - When using docker-in-docker, each job is in a clean environment without the past
history. Concurrent builds work fine because every build gets it's own 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 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 - By default, `docker:dind` uses `--storage-driver vfs` which is the slowest
form offered. To use a different driver, see form offered. To use a different driver, see
[Using the overlayfs driver](#using-the-overlayfs-driver). [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 ...@@ -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: 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`: 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: ...@@ -187,7 +189,9 @@ In order to do that, follow the steps:
The above command will register a new Runner to use the special 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 `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: The above command will create a `config.toml` entry similar to this:
...@@ -206,7 +210,8 @@ In order to do that, follow the steps: ...@@ -206,7 +210,8 @@ In order to do that, follow the steps:
Insecure = false 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 ```yaml
image: docker:latest image: docker:latest
...@@ -221,18 +226,23 @@ In order to do that, follow the steps: ...@@ -221,18 +226,23 @@ In order to do that, follow the steps:
- docker run my-docker-image /script/to/run/tests - 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: While the above method avoids using Docker in privileged mode, you should be
* By sharing the docker daemon, you are effectively disabling all aware of the following implications:
the security mechanisms of containers and exposing your host to privilege
escalation which can lead to container breakout. For example, if a project - By sharing the docker daemon, you are effectively disabling all
ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner the security mechanisms of containers and exposing your host to privilege
containers. escalation which can lead to container breakout. For example, if a project
* Concurrent builds may not work; if your tests ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner
create containers with specific names, they may conflict with each other. containers.
* Sharing files and directories from the source repo into containers may not - Concurrent jobs may not work; if your tests
work as expected since volume mounting is done in the context of the host create containers with specific names, they may conflict with each other.
machine, not the build container. - Sharing files and directories from the source repo into containers may not
e.g. `docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests` 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 ## Using the OverlayFS driver
...@@ -299,7 +309,7 @@ push to the Registry connected to your project. Its password is provided in the ...@@ -299,7 +309,7 @@ push to the Registry connected to your project. Its password is provided in the
of your Docker images. of your Docker images.
Here's a more elaborate example that splits up the tasks into 4 pipeline stages, 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 registry and used by subsequent stages, downloading the image
when needed. Changes to `master` also get tagged as `latest` and deployed using when needed. Changes to `master` also get tagged as `latest` and deployed using
an application-specific deploy script: an application-specific deploy script:
...@@ -360,17 +370,17 @@ deploy: ...@@ -360,17 +370,17 @@ deploy:
Some things you should be aware of when using the Container Registry: Some things you should be aware of when using the Container Registry:
- You must log in to the container registry before running commands. Putting - 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 - 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 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. 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 - 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 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 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 shouldn't ever have a stale image, but it's still possible if you re-build a
given commit after a dependency has changed. 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. happening simultaneously.
[docker-in-docker]: https://blog.docker.com/2013/09/docker-can-now-run-within-docker/ [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 ...@@ -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 instance. [Docker Hub][hub] has a rich database of pre-built images that can be
used to test and build your applications. 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 container using the predefined image that is set up in
[`.gitlab-ci.yml`](../yaml/README.md). [`.gitlab-ci.yml`](../yaml/README.md).
...@@ -45,12 +45,12 @@ can be found at [Docker Hub][hub]. For more information about images and Docker ...@@ -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. Hub please read the [Docker Fundamentals][] documentation.
In short, with `image` we refer to the docker image, which will be used to 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 ## What is a service
The `services` keyword defines just another docker image that is run during 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. 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 The service image can run any application, but the most common use case is to
...@@ -61,13 +61,13 @@ time the project is built. ...@@ -61,13 +61,13 @@ time the project is built.
You can see some widely used services examples in the relevant documentation of You can see some widely used services examples in the relevant documentation of
[CI services examples](../services/README.md). [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 To better understand how the container linking works, read
[Linking containers together][linking-containers]. [Linking containers together][linking-containers].
To summarize, if you add `mysql` as service to your application, the image will 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`. 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 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: ...@@ -133,7 +133,7 @@ Look for the `[runners.docker]` section:
services = ["mysql:latest", "postgres:latest"] 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. that runner.
## Define an image from a private Docker registry ## Define an image from a private Docker registry
...@@ -167,7 +167,7 @@ services: ...@@ -167,7 +167,7 @@ services:
- tutum/wordpress:latest - 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`. 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 The alias hostname for the service is made from the image name following these
...@@ -202,21 +202,21 @@ See the specific documentation for ...@@ -202,21 +202,21 @@ See the specific documentation for
## How Docker integration works ## 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. time.
1. Create any service container: `mysql`, `postgresql`, `mongodb`, `redis`. 1. Create any service container: `mysql`, `postgresql`, `mongodb`, `redis`.
1. Create cache container to store all volumes as defined in `config.toml` and 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). `Dockerfile` of build image (`ruby:2.1` as in above example).
1. Create build container and link any service container to build container. 1. Create build container and link any service container to build container.
1. Start build container and send build script to the container. 1. Start build container and send job script to the container.
1. Run build script. 1. Run job script.
1. Checkout code in: `/builds/group-name/project-name/`. 1. Checkout code in: `/builds/group-name/project-name/`.
1. Run any step defined in `.gitlab-ci.yml`. 1. Run any step defined in `.gitlab-ci.yml`.
1. Check exit status of build script. 1. Check exit status of build script.
1. Remove build container and all created service containers. 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 *Note: The following commands are run without root privileges. You should be
able to run docker with your regular user account.* able to run docker with your regular user account.*
......
...@@ -11,10 +11,10 @@ API. ...@@ -11,10 +11,10 @@ API.
--- ---
As of GitLab 8.2, GitLab CI is mainly exposed via the `/builds` page of a GitLab CI is exposed via the `/pipelines` and `/builds` pages of a project.
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 `/builds` page can still be accessed, although it's hidden from In fact, the `/pipelines` and `/builds` pages can still be accessed, although
the left sidebar menu. it's hidden from the left sidebar menu.
GitLab CI is enabled by default on new installations and can be disabled either GitLab CI is enabled by default on new installations and can be disabled either
individually under each project's settings, or site-wide by modifying the individually under each project's settings, or site-wide by modifying the
...@@ -23,12 +23,12 @@ respectively. ...@@ -23,12 +23,12 @@ respectively.
### Per-project user setting ### Per-project user setting
The setting to enable or disable GitLab CI can be found with the name **Builds** The setting to enable or disable GitLab CI can be found with the name **Pipelines**
under the **Features** area of a project's settings along with **Issues**, under the **Sharing & Permissions** area of a project's settings along with
**Merge Requests**, **Wiki** and **Snippets**. Select or deselect the checkbox **Merge Requests**. Choose one of **Disabled**, **Only team members** and
and hit **Save** for the settings to take effect. **Everyone with access** and hit **Save changes** for the settings to take effect.
![Features settings](img/features_settings.png) ![Sharing & Permissions settings](img/permissions_settings.png)
--- ---
......
...@@ -75,7 +75,7 @@ We have defined 3 [stages](yaml/README.md#stages): ...@@ -75,7 +75,7 @@ We have defined 3 [stages](yaml/README.md#stages):
- deploy - deploy
The jobs assigned to these stages will run in this order. If a job fails, then 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 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, 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 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: ...@@ -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 environment's name with a link to its deployments
- The last deployment ID number and who performed it - 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 - The commit information of the last deployment such as who committed, to what
branch and the Git SHA of the commit branch and the Git SHA of the commit
- The exact time the last deployment was performed - The exact time the last deployment was performed
...@@ -219,9 +219,9 @@ deploy_prod: ...@@ -219,9 +219,9 @@ deploy_prod:
The `when: manual` action exposes a play button in GitLab's UI and the 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. `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) | | ![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: ...@@ -419,7 +419,7 @@ Behind the scenes:
- GitLab Runner picks up the changes and starts running the jobs - GitLab Runner picks up the changes and starts running the jobs
- The jobs run sequentially as defined in `stages` - The jobs run sequentially as defined in `stages`
- First, the tests pass - 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 - Lastly, the app is deployed to an environment with a name specific to the
branch branch
......
...@@ -91,7 +91,7 @@ Secure Variables can added by going to `Project > Variables > Add Variable`. ...@@ -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.** **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 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. 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): 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 1. `$SECRET_VARIABLE` - use it for non-Windows runners
......
...@@ -65,7 +65,7 @@ In order, this means that: ...@@ -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; 1. We check if the `ssh-agent` is available and we install it if it's not;
2. We create the `~/.ssh` folder; 2. We create the `~/.ssh` folder;
3. We make sure we're running bash; 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. And this is basically all you need in the `before_script` section.
......
...@@ -15,10 +15,10 @@ This will allow us to test PHP projects against different versions of PHP. ...@@ -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 However, not everything is plug 'n' play, you still need to configure some
things manually. 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. 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 (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)). about [Using Docker images](../docker/using_docker_images.md#what-is-image)).
...@@ -58,8 +58,8 @@ docker-php-ext-install pdo_mysql ...@@ -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 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 provided by the official php docker image that you can use to easily install
extensions. For more information read the the documentation at extensions. For more information read the documentation at
<https://hub.docker.com/r/_/php/>. <https://hub.docker.com/r/_/php/>.
Now that we created the script that contains all prerequisites for our build 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 ...@@ -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 ## 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 Thus, in order to test your projects you first need to make sure that all
dependencies are installed. dependencies are installed.
...@@ -280,7 +280,7 @@ that runs on [GitLab.com](https://gitlab.com) using our publicly available ...@@ -280,7 +280,7 @@ that runs on [GitLab.com](https://gitlab.com) using our publicly available
[shared runners](../runners/README.md). [shared runners](../runners/README.md).
Want to hack on it? Simply fork it, commit and push your changes. Within a few 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/ [php-hub]: https://hub.docker.com/r/_/php/
[phpenv]: https://github.com/phpenv/phpenv [phpenv]: https://github.com/phpenv/phpenv
......
...@@ -51,14 +51,14 @@ The `deploy` stage automatically deploys the project to Heroku using dpl. ...@@ -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 You can use other versions of Scala and SBT by defining them in
`build.sbt`. `build.sbt`.
## Display test coverage in build ## Display test coverage in job
Add the `Coverage was \[\d+.\d+\%\]` regular expression in the 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 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 ## Heroku application
......
# Using Git submodules with GitLab CI # Using Git submodules with GitLab CI
> **Notes:** > **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. 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 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` 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 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 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. - The HTTP(S) Git protocol [must be enabled][gitpro] in your GitLab instance.
## Configuring the `.gitmodules` file ## Configuring the `.gitmodules` file
...@@ -27,7 +27,7 @@ Let's consider the following example: ...@@ -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, 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**. you must update your `.gitmodules` file to use **relative URLs**.
Since Git allows the usage of relative URLs for your `.gitmodules` configuration, 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: for all your local checkouts. The `.gitmodules` would look like:
```ini ```ini
...@@ -38,7 +38,7 @@ for all your local checkouts. The `.gitmodules` would look like: ...@@ -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 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 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 (because GitLab CI only uses HTTP(S) for cloning your sources), and all your local
clones will continue using SSH. clones will continue using SSH.
...@@ -57,13 +57,13 @@ Once `.gitmodules` is correctly configured, you can move on to ...@@ -57,13 +57,13 @@ Once `.gitmodules` is correctly configured, you can move on to
## Using Git submodules in your CI jobs ## Using Git submodules in your CI jobs
There are a few steps you need to take in order to make submodules work 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) 1. First, make sure you have used [relative URLs](#configuring-the-gitmodules-file)
for the submodules located in the same GitLab server. 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 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 `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 ```yaml
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
...@@ -87,9 +87,9 @@ The rationale to set the `sync` and `update` in `before_script` is because of ...@@ -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 the way Git submodules work. On a fresh Runner workspace, Git will set the
submodule URL including the token in `.git/config` submodule URL including the token in `.git/config`
(or `.git/modules/<submodule>/config`) based on `.gitmodules` and the current (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 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. the full URL.
[gitpro]: ../user/admin_area/settings/visibility_and_access_controls.md#enabled-git-access-protocols [gitpro]: ../user/admin_area/settings/visibility_and_access_controls.md#enabled-git-access-protocols
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
# Introduction to pipelines and builds # Introduction to pipelines and jobs
>**Note:** >**Note:**
Introduced in GitLab 8.8. Introduced in GitLab 8.8.
## Pipelines ## Pipelines
A pipeline is a group of [builds][] that get executed in [stages][](batches). A pipeline is a group of [jobs][] that get executed in [stages][](batches).
All of the builds in a stage are executed in parallel (if there are enough 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 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. executed.
![Pipelines example](img/pipelines.png) ![Pipelines example](img/pipelines.png)
## Builds ## Types of Pipelines
Builds are individual runs of [jobs]. Not to be confused with a `build` job or There are three types of pipelines that often use the single shorthand of "pipeline". People often talk about them as if each one is "the" pipeline, but really, they're just pieces of a single, comprehensive pipeline.
`build` stage.
![Types of Pipelines](img/types-of-pipelines.svg)
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.
## Development Workflows
Pipelines accommodate several development workflows:
1. **Branch Flow** (e.g. different branch for dev, qa, staging, production)
2. **Trunk-based Flow** (e.g. feature branches and single master branch, possibly with tags for releases)
3. **Fork-based Flow** (e.g. merge requests come from forks)
Example continuous delivery flow:
![CD Flow](img/pipelines-goal.svg)
## Jobs
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 ## Defining pipelines
...@@ -30,11 +52,11 @@ See full [documentation](yaml/README.md#jobs). ...@@ -30,11 +52,11 @@ See full [documentation](yaml/README.md#jobs).
You can find the current and historical pipeline runs under **Pipelines** for You can find the current and historical pipeline runs under **Pipelines** for
your project. your project.
## Seeing build status ## Seeing job status
Clicking on a pipeline will show the builds that were run for that pipeline. Clicking on a pipeline will show the jobs that were run for that pipeline.
Clicking on an individual build will show you its build trace, and allow you to Clicking on an individual job will show you its job trace, and allow you to
cancel the build, retry it, or erase the build trace. cancel the job, retry it, or erase the job trace.
## How the pipeline duration is calculated ## How the pipeline duration is calculated
...@@ -69,11 +91,11 @@ total running time should be: ...@@ -69,11 +91,11 @@ total running time should be:
## Badges ## 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. respective link in the [Pipelines settings] page.
[builds]: #builds [jobs]: #jobs
[jobs]: yaml/README.md#jobs [jobs-yaml]: yaml/README.md#jobs
[stages]: yaml/README.md#stages [stages]: yaml/README.md#stages
[runners]: runners/README.html [runners]: runners/README.html
[pipelines settings]: ../user/project/pipelines/settings.md [pipelines settings]: ../user/project/pipelines/settings.md
# Quick Start # Getting started with GitLab CI
>**Note:** Starting from version 8.0, GitLab [Continuous Integration][ci] (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 is fully integrated into GitLab itself and is [enabled] by default on all
...@@ -7,7 +7,7 @@ projects. ...@@ -7,7 +7,7 @@ projects.
GitLab offers a [continuous integration][ci] service. If you GitLab offers a [continuous integration][ci] service. If you
[add a `.gitlab-ci.yml` file][yaml] to the root directory of your repository, [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 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 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 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: ...@@ -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 From there on, on every push to your Git repository, the Runner will
automagically start the pipeline and the pipeline will appear under the automagically start the pipeline and the pipeline will appear under the
project's `/pipelines` page. project's **Pipelines** page.
--- ---
This guide assumes that you: 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) [GitLab.com](https://gitlab.com)
- have a project in GitLab that you would like to use CI for - 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. ...@@ -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. It lives in the root of your repository.
On any push to your repository, GitLab will look for the `.gitlab-ci.yml` 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. for that commit.
Because `.gitlab-ci.yml` is in the repository and is version controlled, old 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. ...@@ -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 You can read more about the reasons why we are using `.gitlab-ci.yml` [in our
blog about it][blog-ci]. 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 ### 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 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. repository. Below is an example for a Ruby on Rails project.
...@@ -88,7 +89,7 @@ rubocop: ...@@ -88,7 +89,7 @@ rubocop:
- bundle exec 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: applications:
1. Define two jobs `rspec` and `rubocop` (the names are arbitrary) with 1. Define two jobs `rspec` and `rubocop` (the names are arbitrary) with
...@@ -98,22 +99,22 @@ applications: ...@@ -98,22 +99,22 @@ applications:
The `.gitlab-ci.yml` file defines sets of jobs with constraints of how and when 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 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. 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. [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. 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 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 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 a "CI Lint" button to go to this page under **Pipelines Pipelines** and
**Pipelines > Builds** in your project. **Pipelines ➔ Jobs** in your project.
For more information and a complete `.gitlab-ci.yml` syntax, please read 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 ### 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. and push it to GitLab.
```bash ```bash
...@@ -125,28 +126,27 @@ git push origin master ...@@ -125,28 +126,27 @@ git push origin master
Now if you go to the **Pipelines** page you will see that the pipeline is Now if you go to the **Pipelines** page you will see that the pipeline is
pending. 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. to the commit SHA.
![New commit pending](img/new_commit.png) ![New commit pending](img/new_commit.png)
Clicking on the clock icon you will be directed to the builds page for that Clicking on it you will be directed to the jobs page for that specific commit.
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 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 `.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 ## 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 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, 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 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_. GitLab. If it serves all projects it's called a _Shared Runner_.
...@@ -155,9 +155,9 @@ Find more information about different Runners in the ...@@ -155,9 +155,9 @@ Find more information about different Runners in the
[Runners](../runners/README.md) documentation. [Runners](../runners/README.md) documentation.
You can find whether any Runners are assigned to your project by going to 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 **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 official Runner supported by GitLab is written in Go and its documentation
<https://gitlab.com/gitlab-org/gitlab-ci-multi-runner>. can be found at <https://docs.gitlab.com/runner/>.
In order to have a functional Runner you need to follow two steps: 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: ...@@ -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 Follow the links above to set up your own Runner or use a Shared Runner as
described in the next section. 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 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) ![Activated runners](img/runners_activated.png)
### Shared Runners ### 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. provided by GitLab Inc.
These are special virtual machines that run on GitLab's infrastructure and can These are special virtual machines that run on GitLab's infrastructure and can
build any project. build any project.
To enable **Shared Runners** you have to go to your project's To enable the **Shared Runners** you have to go to your project's
**Settings > Runners** and click **Enable shared runners**. **Settings Runners** and click **Enable shared runners**.
[Read more on Shared Runners](../runners/README.md). [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 After configuring the Runner successfully, you should see the status of your
last commit change from _pending_ to either _running_, _success_ or _failed_. 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. ...@@ -197,23 +194,23 @@ You can view all pipelines by going to the **Pipelines** page in your project.
![Commit status](img/pipelines_status.png) ![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) ![Commit status](img/builds_status.png)
By clicking on a Build ID, you will be able to see the log of that build. 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 build failed or acted differently than This is important to diagnose why a job failed or acted differently than
you expected. you expected.
![Build log](img/build_log.png) ![Build log](img/build_log.png)
You are also able to view the status of any commit in the various pages in 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 ## Enabling build emails
If you want to receive e-mail notifications about the result status of the 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. project's settings.
For more information read the For more information read the
...@@ -224,9 +221,7 @@ 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 Visit the [examples README][examples] to see a list of examples using GitLab
CI with various languages. CI with various languages.
Awesome! You started using CI in GitLab! [runner-install]: https://docs.gitlab.com/runner/install/
[runner-install]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/tree/master#install-gitlab-runner
[blog-ci]: https://about.gitlab.com/2015/05/06/why-were-replacing-gitlab-ci-jobs-with-gitlab-ci-dot-yml/ [blog-ci]: https://about.gitlab.com/2015/05/06/why-were-replacing-gitlab-ci-jobs-with-gitlab-ci-dot-yml/
[examples]: ../examples/README.md [examples]: ../examples/README.md
[ci]: https://about.gitlab.com/gitlab-ci/ [ci]: https://about.gitlab.com/gitlab-ci/
...@@ -235,3 +230,4 @@ Awesome! You started using CI in GitLab! ...@@ -235,3 +230,4 @@ Awesome! You started using CI in GitLab!
[enabled]: ../enable_or_disable_ci.md [enabled]: ../enable_or_disable_ci.md
[stages]: ../yaml/README.md#stages [stages]: ../yaml/README.md#stages
[pipeline]: ../pipelines.md [pipeline]: ../pipelines.md
[internet]: https://about.gitlab.com/images/theinternet.png
doc/ci/quick_start/img/build_log.png

23.9 KB | W: | H:

doc/ci/quick_start/img/build_log.png

34.4 KB | W: | H:

doc/ci/quick_start/img/build_log.png
doc/ci/quick_start/img/build_log.png
doc/ci/quick_start/img/build_log.png
doc/ci/quick_start/img/build_log.png
  • 2-up
  • Swipe
  • Onion skin
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment