New upstream version 10.6.2+dfsg
This commit is contained in:
parent
514980f938
commit
b4bdfb5f9f
37 changed files with 3235 additions and 97 deletions
34
CHANGELOG.md
34
CHANGELOG.md
|
@ -2,6 +2,34 @@
|
|||
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||
entry.
|
||||
|
||||
## 10.6.2 (2018-03-29)
|
||||
|
||||
### Fixed (2 changes, 1 of them is from the community)
|
||||
|
||||
- Don't capture trailing punctuation when autolinking. !17965
|
||||
- Cloning a repository over HTTPS with LDAP credentials causes a HTTP 401 Access denied. (Horatiu Eugen Vlad)
|
||||
|
||||
|
||||
## 10.6.1 (2018-03-27)
|
||||
|
||||
### Security (1 change)
|
||||
|
||||
- Bump rails-html-sanitizer to 1.0.4.
|
||||
|
||||
### Fixed (2 changes)
|
||||
|
||||
- Prevent auto-retry AccessDenied error from stopping transition to failed. !17862
|
||||
- Fix 500 error when trying to resolve non-ASCII conflicts in the editor. !17962
|
||||
|
||||
### Performance (1 change)
|
||||
|
||||
- Add indexes for user activity queries. !17890
|
||||
|
||||
### Other (1 change)
|
||||
|
||||
- Add documentation for runner IP address (#44232). !17837
|
||||
|
||||
|
||||
## 10.6.0 (2018-03-22)
|
||||
|
||||
### Security (4 changes)
|
||||
|
@ -168,13 +196,17 @@ entry.
|
|||
- Add one group board to Libre.
|
||||
- Add support for filtering by source and target branch to merge requests API.
|
||||
|
||||
### Other (14 changes, 3 of them are from the community)
|
||||
### Other (18 changes, 7 of them are from the community)
|
||||
|
||||
- Group MRs on issue page by project and namespace. !8494 (Jeff Stubler)
|
||||
- Make oauth provider login generic. !8809 (Horatiu Eugen Vlad)
|
||||
- Add email button to new issue by email. !10942 (Islam Wazery)
|
||||
- Update vue component naming guidelines. !17018 (George Tsiolis)
|
||||
- Added new design for promotion modals. !17197
|
||||
- Update to github-linguist 5.3.x. !17241 (Ken Ding)
|
||||
- update toml-rb to 1.0.0. !17259 (Ken Ding)
|
||||
- Keep track of projects a user interacted with. !17327
|
||||
- Moved o_auth/saml/ldap modules under gitlab/auth. !17359 (Horatiu Eugen Vlad)
|
||||
- Enables eslint in codeclimate job. !17392
|
||||
- Port Labels Select dropdown to Vue. !17411
|
||||
- Add NOT NULL constraint to projects.namespace_id. !17448
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -218,7 +218,7 @@ gem 'sanitize', '~> 2.0'
|
|||
gem 'babosa', '~> 1.0.2'
|
||||
|
||||
# Sanitizes SVG input
|
||||
gem 'loofah', '~> 2.0.3'
|
||||
gem 'loofah', '~> 2.2'
|
||||
|
||||
# Working with license
|
||||
gem 'licensee', '~> 8.7.0'
|
||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -142,6 +142,7 @@ GEM
|
|||
connection_pool (2.2.1)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
crass (1.0.3)
|
||||
creole (0.5.0)
|
||||
css_parser (1.5.0)
|
||||
addressable
|
||||
|
@ -488,7 +489,8 @@ GEM
|
|||
actionpack (>= 4, < 5.2)
|
||||
activesupport (>= 4, < 5.2)
|
||||
railties (>= 4, < 5.2)
|
||||
loofah (2.0.3)
|
||||
loofah (2.2.2)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.0)
|
||||
mini_mime (>= 0.1.1)
|
||||
|
@ -685,8 +687,8 @@ GEM
|
|||
activesupport (>= 4.2.0.beta, < 5.0)
|
||||
nokogiri (~> 1.6)
|
||||
rails-deprecated_sanitizer (>= 1.0.1)
|
||||
rails-html-sanitizer (1.0.3)
|
||||
loofah (~> 2.0)
|
||||
rails-html-sanitizer (1.0.4)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
rails-i18n (4.0.9)
|
||||
i18n (~> 0.7)
|
||||
railties (~> 4.0)
|
||||
|
@ -1100,7 +1102,7 @@ DEPENDENCIES
|
|||
license_finder (~> 3.1)
|
||||
licensee (~> 8.7.0)
|
||||
lograge (~> 0.5)
|
||||
loofah (~> 2.0.3)
|
||||
loofah (~> 2.2)
|
||||
mail_room (~> 0.9.1)
|
||||
method_source (~> 0.8)
|
||||
minitest (~> 5.7.0)
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
10.6.0
|
||||
10.6.2
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// ECMAScript polyfills
|
||||
import 'core-js/fn/array/fill';
|
||||
import 'core-js/fn/array/find';
|
||||
import 'core-js/fn/array/find-index';
|
||||
import 'core-js/fn/array/from';
|
||||
|
|
|
@ -140,7 +140,11 @@ module Ci
|
|||
next if build.retries_max.zero?
|
||||
|
||||
if build.retries_count < build.retries_max
|
||||
Ci::Build.retry(build, build.user)
|
||||
begin
|
||||
Ci::Build.retry(build, build.user)
|
||||
rescue Gitlab::Access::AccessDeniedError => ex
|
||||
Rails.logger.error "Unable to auto-retry job #{build.id}: #{ex}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -328,8 +332,7 @@ module Ci
|
|||
end
|
||||
|
||||
def erase_old_trace!
|
||||
write_attribute(:trace, nil)
|
||||
save
|
||||
update_column(:trace, nil)
|
||||
end
|
||||
|
||||
def needs_touch?
|
||||
|
|
|
@ -230,13 +230,13 @@ class Group < Namespace
|
|||
end
|
||||
|
||||
GroupMember
|
||||
.active_without_invites
|
||||
.active_without_invites_and_requests
|
||||
.where(source_id: source_ids)
|
||||
end
|
||||
|
||||
def members_with_descendants
|
||||
GroupMember
|
||||
.active_without_invites
|
||||
.active_without_invites_and_requests
|
||||
.where(source_id: self_and_descendants.reorder(nil).select(:id))
|
||||
end
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class Member < ActiveRecord::Base
|
|||
end
|
||||
|
||||
# Like active, but without invites. For when a User is required.
|
||||
scope :active_without_invites, -> do
|
||||
scope :active_without_invites_and_requests, -> do
|
||||
left_join_users
|
||||
.where(users: { state: 'active' })
|
||||
.non_request
|
||||
|
|
|
@ -208,9 +208,9 @@ class NotificationService
|
|||
def new_access_request(member)
|
||||
return true unless member.notifiable?(:subscription)
|
||||
|
||||
recipients = member.source.members.active_without_invites.owners_and_masters
|
||||
recipients = member.source.members.active_without_invites_and_requests.owners_and_masters
|
||||
if fallback_to_group_owners_masters?(recipients, member)
|
||||
recipients = member.source.group.members.active_without_invites.owners_and_masters
|
||||
recipients = member.source.group.members.active_without_invites_and_requests.owners_and_masters
|
||||
end
|
||||
|
||||
recipients.each { |recipient| deliver_access_request_email(recipient, member) }
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
class AddIndexesForUserActivityQueries < ActiveRecord::Migration
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_index :events, [:author_id, :project_id] unless index_exists?(:events, [:author_id, :project_id])
|
||||
add_concurrent_index :user_interacted_projects, :user_id unless index_exists?(:user_interacted_projects, :user_id)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index :events, [:author_id, :project_id] if index_exists?(:events, [:author_id, :project_id])
|
||||
|
||||
patch_foreign_keys do
|
||||
remove_concurrent_index :user_interacted_projects, :user_id if index_exists?(:user_interacted_projects, :user_id)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def patch_foreign_keys
|
||||
return yield if Gitlab::Database.postgresql?
|
||||
|
||||
# MySQL doesn't like to remove the index with a foreign key using it.
|
||||
remove_foreign_key :user_interacted_projects, :users if fk_exists?(:user_interacted_projects, :user_id)
|
||||
|
||||
yield
|
||||
|
||||
# Let's re-add the foreign key using the existing index on (user_id, project_id)
|
||||
add_concurrent_foreign_key :user_interacted_projects, :users, column: :user_id unless fk_exists?(:user_interacted_projects, :user_id)
|
||||
end
|
||||
|
||||
def fk_exists?(table, column)
|
||||
foreign_keys(table).any? do |key|
|
||||
key.options[:column] == column.to_s
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20180309160427) do
|
||||
ActiveRecord::Schema.define(version: 20180320182229) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -728,6 +728,7 @@ ActiveRecord::Schema.define(version: 20180309160427) do
|
|||
end
|
||||
|
||||
add_index "events", ["action"], name: "index_events_on_action", using: :btree
|
||||
add_index "events", ["author_id", "project_id"], name: "index_events_on_author_id_and_project_id", using: :btree
|
||||
add_index "events", ["author_id"], name: "index_events_on_author_id", using: :btree
|
||||
add_index "events", ["project_id", "id"], name: "index_events_on_project_id_and_id", using: :btree
|
||||
add_index "events", ["target_type", "target_id"], name: "index_events_on_target_type_and_target_id", using: :btree
|
||||
|
@ -1856,6 +1857,7 @@ ActiveRecord::Schema.define(version: 20180309160427) do
|
|||
end
|
||||
|
||||
add_index "user_interacted_projects", ["project_id", "user_id"], name: "index_user_interacted_projects_on_project_id_and_user_id", unique: true, using: :btree
|
||||
add_index "user_interacted_projects", ["user_id"], name: "index_user_interacted_projects_on_user_id", using: :btree
|
||||
|
||||
create_table "user_synced_attributes_metadata", force: :cascade do |t|
|
||||
t.boolean "name_synced", default: false
|
||||
|
|
|
@ -65,7 +65,8 @@ learn how to leverage its potential even more.
|
|||
environments and use them for different purposes like testing, building and
|
||||
deploying
|
||||
- [Job artifacts](../user/project/pipelines/job_artifacts.md)
|
||||
- [Git submodules](git_submodules.md): How to run your CI jobs when Git
|
||||
- [Caching dependencies](caching/index.md)
|
||||
- [Git submodules](git_submodules.md) - How to run your CI jobs when Git
|
||||
submodules are involved
|
||||
- [Use SSH keys in your build environment](ssh_keys/README.md)
|
||||
- [Trigger pipelines through the GitLab API](triggers/README.md)
|
||||
|
|
516
doc/ci/caching/index.md
Normal file
516
doc/ci/caching/index.md
Normal file
|
@ -0,0 +1,516 @@
|
|||
# Cache dependencies in GitLab CI/CD
|
||||
|
||||
GitLab CI/CD provides a caching mechanism that can be used to save time
|
||||
when your jobs are running.
|
||||
|
||||
Caching is about speeding the time a job is executed by reusing the same
|
||||
content of a previous job. It can be particularly useful when your are
|
||||
developing software that depends on other libraries which are fetched via the
|
||||
internet during build time.
|
||||
|
||||
If caching is enabled, it's shared between pipelines and jobs by default,
|
||||
starting from GitLab 9.0.
|
||||
|
||||
Make sure you read the [`cache` reference](../yaml/README.md#cache) to learn
|
||||
how it is defined in `.gitlab-ci.yml`.
|
||||
|
||||
## Good caching practices
|
||||
|
||||
We have the cache from the perspective of the developers (who consume a cache
|
||||
within the job) and the cache from the perspective of the Runner. Depending on
|
||||
which type of Runner you are using, cache can act differently.
|
||||
|
||||
From the perspective of the developer, to ensure maximum availability of the
|
||||
cache, when declaring `cache` in your jobs, use one or a mix of the following:
|
||||
|
||||
- [Tag your Runners](../runners/README.md#using-tags) and use the tag on jobs
|
||||
that share their cache.
|
||||
- [Use sticky Runners](../runners/README.md#locking-a-specific-runner-from-being-enabled-for-other-projects)
|
||||
that will be only available to a particular project.
|
||||
- [Use a `key`](../yaml/README.md#cache-key) that fits your workflow (e.g.,
|
||||
different caches on each branch). For that, you can take advantage of the
|
||||
[CI/CD predefined variables](../variables/README.md#predefined-variables-environment-variables).
|
||||
|
||||
TIP: **Tip:**
|
||||
Using the same Runner for your pipeline, is the most simple and efficient way to
|
||||
cache files in one stage or pipeline, and pass this cache to subsequent stages
|
||||
or pipelines in a guaranteed manner.
|
||||
|
||||
From the perspective of the Runner, in order for cache to work effectively, one
|
||||
of the following must be true:
|
||||
|
||||
- Use a single Runner for all your jobs
|
||||
- Use multiple Runners (in autoscale mode or not) that use
|
||||
[distributed caching](https://docs.gitlab.com/runner/configuration/autoscale.html#distributed-runners-caching),
|
||||
where the cache is stored in S3 buckets (like shared Runners on GitLab.com)
|
||||
- Use multiple Runners (not in autoscale mode) of the same architecture that
|
||||
share a common network-mounted directory (using NFS or something similar)
|
||||
where the cache will be stored
|
||||
|
||||
TIP: **Tip:**
|
||||
Read about the [availability of the cache](#availability-of-the-cache)
|
||||
to learn more about the internals and get a better idea how cache works.
|
||||
|
||||
### Sharing caches across the same branch
|
||||
|
||||
Define a cache with the `key: ${CI_COMMIT_REF_SLUG}` so that jobs of each
|
||||
branch always use the same cache:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
```
|
||||
|
||||
While this feels like it might be safe from accidentally overwriting the cache,
|
||||
it means merge requests get slow first pipelines, which might be a bad
|
||||
developer experience. The next time a new commit is pushed to the branch, the
|
||||
cache will be re-used.
|
||||
|
||||
To enable per-job and per-branch caching:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
```
|
||||
|
||||
To enable per-branch and per-stage caching:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
|
||||
```
|
||||
|
||||
### Sharing caches across different branches
|
||||
|
||||
If the files you are caching need to be shared across all branches and all jobs,
|
||||
you can use the same key for all of them:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key: one-key-to-rull-them-all
|
||||
```
|
||||
|
||||
To share the same cache between branches, but separate them by job:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key: ${CI_JOB_NAME}
|
||||
```
|
||||
|
||||
### Disabling cache on specific jobs
|
||||
|
||||
If you have defined the cache globally, it means that each job will use the
|
||||
same definition. You can override this behavior per-job, and if you want to
|
||||
disable it completely, use an empty hash:
|
||||
|
||||
```yaml
|
||||
job:
|
||||
cache: {}
|
||||
```
|
||||
|
||||
For more fine tuning, read also about the
|
||||
[`cache: policy`](../yaml/README.md#cache-policy).
|
||||
|
||||
## Common use cases
|
||||
|
||||
The most common use case of cache is to preserve contents between subsequent
|
||||
runs of jobs for things like dependencies and commonly used libraries
|
||||
(Nodejs packages, PHP packages, rubygems, python libraries, etc.),
|
||||
so they don't have to be re-fetched from the public internet.
|
||||
|
||||
NOTE: **Note:**
|
||||
For more examples, check the [GitLab CI Yml](https://gitlab.com/gitlab-org/gitlab-ci-yml)
|
||||
project.
|
||||
|
||||
### Caching Nodejs dependencies
|
||||
|
||||
Assuming your project is using [npm](https://www.npmjs.com/) or
|
||||
[Yarn](https://yarnpkg.com/en/) to install the Nodejs dependencies, the
|
||||
following example defines `cache` globally so that all jobs inherit it.
|
||||
Nodejs modules are installed in `node_modules/` and are cached per-branch:
|
||||
|
||||
```yaml
|
||||
#
|
||||
# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Nodejs.gitlab-ci.yml
|
||||
#
|
||||
image: node:latest
|
||||
|
||||
# Cache modules in between jobs
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- node_modules/
|
||||
|
||||
before_script:
|
||||
- npm install
|
||||
|
||||
test_async:
|
||||
script:
|
||||
- node ./specs/start.js ./specs/async.spec.js
|
||||
```
|
||||
|
||||
### Caching PHP dependencies
|
||||
|
||||
Assuming your project is using [Composer](https://getcomposer.org/) to install
|
||||
the PHP dependencies, the following example defines `cache` globally so that
|
||||
all jobs inherit it. PHP libraries modules are installed in `vendor/` and
|
||||
are cached per-branch:
|
||||
|
||||
```yaml
|
||||
#
|
||||
# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/PHP.gitlab-ci.yml
|
||||
#
|
||||
image: php:7.2
|
||||
|
||||
# Cache libraries in between jobs
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- vendor/
|
||||
|
||||
before_script:
|
||||
# Install and run Composer
|
||||
- curl --show-error --silent https://getcomposer.org/installer | php
|
||||
- php composer.phar install
|
||||
|
||||
test:
|
||||
script:
|
||||
- vendor/bin/phpunit --configuration phpunit.xml --coverage-text --colors=never
|
||||
```
|
||||
|
||||
### Caching Python dependencies
|
||||
|
||||
Assuming your project is using [pip](https://pip.pypa.io/en/stable/) to install
|
||||
the python dependencies, the following example defines `cache` globally so that
|
||||
all jobs inherit it. Python libraries are installed in a virtualenv under `venv/`,
|
||||
pip's cache is defined under `.cache/pip/` and both are cached per-branch:
|
||||
|
||||
```yaml
|
||||
#
|
||||
# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Python.gitlab-ci.yml
|
||||
#
|
||||
image: python:latest
|
||||
|
||||
# Change pip's cache directory to be inside the project directory since we can
|
||||
# only cache local items.
|
||||
variables:
|
||||
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache"
|
||||
|
||||
# Pip's cache doesn't store the python packages
|
||||
# https://pip.pypa.io/en/stable/reference/pip_install/#caching
|
||||
#
|
||||
# If you want to also cache the installed packages, you have to install
|
||||
# them in a virtualenv and cache it as well.
|
||||
cache:
|
||||
paths:
|
||||
- .cache/
|
||||
- venv/
|
||||
|
||||
before_script:
|
||||
- python -V # Print out python version for debugging
|
||||
- pip install virtualenv
|
||||
- virtualenv venv
|
||||
- source venv/bin/activate
|
||||
|
||||
test:
|
||||
script:
|
||||
- python setup.py test
|
||||
- pip install flake8
|
||||
- flake8 .
|
||||
```
|
||||
|
||||
### Caching Ruby dependencies
|
||||
|
||||
Assuming your project is using [Bundler](https://bundler.io) to install the
|
||||
gem dependencies, the following example defines `cache` globally so that all
|
||||
jobs inherit it. Gems are installed in `vendor/ruby/` and are cached per-branch:
|
||||
|
||||
```yaml
|
||||
#
|
||||
# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Ruby.gitlab-ci.yml
|
||||
#
|
||||
image: ruby:2.5
|
||||
|
||||
# Cache gems in between builds
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- vendor/ruby
|
||||
|
||||
before_script:
|
||||
- ruby -v # Print out ruby version for debugging
|
||||
- gem install bundler --no-ri --no-rdoc # Bundler is not installed with the image
|
||||
- bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby
|
||||
|
||||
rspec:
|
||||
script:
|
||||
- rspec spec
|
||||
```
|
||||
|
||||
## Availability of the cache
|
||||
|
||||
Caching is an optimization, but isn't guaranteed to always work, so you need to
|
||||
be prepared to regenerate any cached files in each job that needs them.
|
||||
|
||||
Assuming you have properly [defined `cache` in `.gitlab-ci.yml`](../yaml/README.md#cache)
|
||||
according to your workflow, the availability of the cache ultimately depends on
|
||||
how the Runner has been configured (the executor type and whether different
|
||||
Runners are used for passing the cache between jobs).
|
||||
|
||||
### Where the caches are stored
|
||||
|
||||
Since the Runner is the one responsible for storing the cache, it's essential
|
||||
to know **where** it's stored. All the cache paths defined under a job in
|
||||
`.gitlab-ci.yml` are archived in a single `cache.zip` file and stored in the
|
||||
Runner's configured cache location. By default, they are stored locally in the
|
||||
machine where the Runner is installed and depends on the type of the executor.
|
||||
|
||||
| GitLab Runner executor | Default path of the cache |
|
||||
| ---------------------- | ------------------------- |
|
||||
| [Shell](https://docs.gitlab.com/runner/executors/shell.html) | Locally, stored under the `gitlab-runner` user's home directory: `/home/gitlab-runner/cache/<user>/<project>/<cache-key>/cache.zip`. |
|
||||
| [Docker](https://docs.gitlab.com/runner/executors/docker.html) | Locally, stored under [Docker volumes](https://docs.gitlab.com/runner/executors/docker.html#the-builds-and-cache-storage): `/var/lib/docker/volumes/<volume-id>/_data/<user>/<project>/<cache-key>/cache.zip`. |
|
||||
| [Docker machine](https://docs.gitlab.com/runner/executors/docker_machine.html) (autoscale Runners) | Behaves the same as the Docker executor. |
|
||||
|
||||
### How archiving and extracting works
|
||||
|
||||
In the most simple scenario, consider that you use only one machine where the
|
||||
Runner is installed, and all jobs of your project run on the same host.
|
||||
|
||||
Let's see the following example of two jobs that belong to two consecutive
|
||||
stages:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
before_script:
|
||||
- echo "Hello"
|
||||
|
||||
job A:
|
||||
stage: build
|
||||
script:
|
||||
- mkdir vendor/
|
||||
- echo "build" > vendor/hello.txt
|
||||
cache:
|
||||
key: build-cache
|
||||
paths:
|
||||
- vendor/
|
||||
after_script:
|
||||
- echo "World"
|
||||
|
||||
job B:
|
||||
stage: test
|
||||
script:
|
||||
- cat vendor/hello.txt
|
||||
cache:
|
||||
key: build-cache
|
||||
```
|
||||
|
||||
Here's what happens behind the scenes:
|
||||
|
||||
1. Pipeline starts
|
||||
1. `job A` runs
|
||||
1. `before_script` is executed
|
||||
1. `script` is executed
|
||||
1. `after_script` is executed
|
||||
1. `cache` runs and the `vendor/` directory is zipped into `cache.zip`.
|
||||
This file is then saved in the directory based on the
|
||||
[Runner's setting](#where-the-caches-are-stored) and the `cache: key`.
|
||||
1. `job B` runs
|
||||
1. The cache is extracted (if found)
|
||||
1. `before_script` is executed
|
||||
1. `script` is executed
|
||||
1. Pipeline finishes
|
||||
|
||||
By using a single Runner on a single machine, you'll not have the issue where
|
||||
`job B` might execute on a Runner different from `job A`, thus guaranteeing the
|
||||
cache between stages. That will only work if the build goes from stage `build`
|
||||
to `test` in the same Runner/machine, otherwise, you [might not have the cache
|
||||
available](#cache-mismatch).
|
||||
|
||||
During the caching process, there's also a couple of things to consider:
|
||||
|
||||
- If some other job, with another cache configuration had saved its
|
||||
cache in the same zip file, it is overwritten. If the S3 based shared cache is
|
||||
used, the file is additionally uploaded to S3 to an object based on the cache
|
||||
key. So, two jobs with different paths, but the same cache key, will overwrite
|
||||
their cache.
|
||||
- When extracting the cache from `cache.zip`, everything in the zip file is
|
||||
extracted in the job's working directory (usually the repository which is
|
||||
pulled down), and the Runner doesn't mind if the archive of `job A` overwrites
|
||||
things in the archive of `job B`.
|
||||
|
||||
The reason why it works this way is because the cache created for one Runner
|
||||
often will not be valid when used by a different one which can run on a
|
||||
**different architecture** (e.g., when the cache includes binary files). And
|
||||
since the different steps might be executed by Runners running on different
|
||||
machines, it is a safe default.
|
||||
|
||||
### Cache mismatch
|
||||
|
||||
In the following table, you can see some reasons where you might hit a cache
|
||||
mismatch and a few ideas how to fix it.
|
||||
|
||||
| Reason of a cache mismatch | How to fix it |
|
||||
| -------------------------- | ------------- |
|
||||
| You use multiple standalone Runners (not in autoscale mode) attached to one project without a shared cache | Use only one Runner for your project or use multiple Runners with distributed cache enabled |
|
||||
| You use Runners in autoscale mode without a distributed cache enabled | Configure the autoscale Runner to use a distributed cache |
|
||||
| The machine the Runner is installed on is low on disk space or, if you've set up distributed cache, the S3 bucket where the cache is stored doesn't have enough space | Make sure you clear some space to allow new caches to be stored. Currently, there's no automatic way to do this. |
|
||||
| You use the same `key` for jobs where they cache different paths. | Use different cache keys to that the cache archive is stored to a different location and doesn't overwrite wrong caches. |
|
||||
|
||||
Let's explore some examples.
|
||||
|
||||
---
|
||||
|
||||
Let's assume you have only one Runner assigned to your project, so the cache
|
||||
will be stored in the Runner's machine by default. If two jobs, A and B,
|
||||
have the same cache key, but they cache different paths, cache B would overwrite
|
||||
cache A, even if their `paths` don't match:
|
||||
|
||||
We want `job A` and `job B` to re-use their
|
||||
cache when the pipeline is run for a second time.
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
job A:
|
||||
stage: build
|
||||
script: make build
|
||||
cache:
|
||||
key: same-key
|
||||
paths:
|
||||
- public/
|
||||
|
||||
job B:
|
||||
stage: test
|
||||
script: make test
|
||||
cache:
|
||||
key: same-key
|
||||
paths:
|
||||
- vendor/
|
||||
```
|
||||
|
||||
1. `job A` runs
|
||||
1. `public/` is cached as cache.zip
|
||||
1. `job B` runs
|
||||
1. The previous cache, if any, is unzipped
|
||||
1. `vendor/` is cached as cache.zip and overwrites the previous one
|
||||
1. The next time `job A` runs it will use the cache of `job B` which is different
|
||||
and thus will be ineffective
|
||||
|
||||
To fix that, use different `keys` for each job.
|
||||
|
||||
---
|
||||
|
||||
In another case, let's assume you have more than one Runners assigned to your
|
||||
project, but the distributed cache is not enabled. We want the second time the
|
||||
pipeline is run, `job A` and `job B` to re-use their cache (which in this case
|
||||
will be different):
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
job A:
|
||||
stage: build
|
||||
script: build
|
||||
cache:
|
||||
key: keyA
|
||||
paths:
|
||||
- vendor/
|
||||
|
||||
job B:
|
||||
stage: test
|
||||
script: test
|
||||
cache:
|
||||
key: keyB
|
||||
paths:
|
||||
- vendor/
|
||||
```
|
||||
|
||||
In that case, even if the `key` is different (no fear of overwriting), you
|
||||
might experience the cached files to "get cleaned" before each stage if the
|
||||
jobs run on different Runners in the subsequent pipelines.
|
||||
|
||||
## Clearing the cache
|
||||
|
||||
GitLab Runners use [cache](../yaml/README.md#cache) to speed up the execution
|
||||
of your jobs by reusing existing data. This however, can sometimes lead to an
|
||||
inconsistent behavior.
|
||||
|
||||
To start with a fresh copy of the cache, there are two ways to do that.
|
||||
|
||||
### Clearing the cache by changing `cache:key`
|
||||
|
||||
All you have to do is set a new `cache: key` in your `.gitlab-ci.yml`. In the
|
||||
next run of the pipeline, the cache will be stored in a different location.
|
||||
|
||||
### Clearing the cache manually
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/41249) in GitLab 10.4.
|
||||
|
||||
If you want to avoid editing `.gitlab-ci.yml`, you can easily clear the cache
|
||||
via GitLab's UI. This will have an impact on all caches of your project as
|
||||
name of the cache directory will be renamed by appending an integer to it
|
||||
(`-1`, `-2`, etc.):
|
||||
|
||||
1. Navigate to your project's **CI/CD > Pipelines** page.
|
||||
1. Click on the **Clear Runner caches** to clean up the cache.
|
||||
1. On the next push, your CI/CD job will use a new cache.
|
||||
|
||||
Behind the scenes, this works by increasing a counter in the database, and the
|
||||
value of that counter is used to create the key for the cache. After a push, a
|
||||
new key is generated and the old cache is not valid anymore.
|
||||
|
||||
## Cache vs artifacts
|
||||
|
||||
NOTE: **Note:**
|
||||
Be careful if you use cache and artifacts to store the same path in your jobs
|
||||
as **caches are restored before artifacts** and the content would be overwritten.
|
||||
|
||||
Don't mix the caching with passing artifacts between stages. Caching is not
|
||||
designed to pass artifacts between stages. Cache is for runtime dependencies
|
||||
needed to compile the project:
|
||||
|
||||
- `cache` - **Use for temporary storage for project dependencies.** Not useful
|
||||
for keeping intermediate build results, like `jar` or `apk` files.
|
||||
Cache was designed to be used to speed up invocations of subsequent runs of a
|
||||
given job, by keeping things like dependencies (e.g., npm packages, Go vendor
|
||||
packages, etc.) so they don't have to be re-fetched from the public internet.
|
||||
While the cache can be abused to pass intermediate build results between stages,
|
||||
there may be cases where artifacts are a better fit.
|
||||
- `artifacts` - **Use for stage results that will be passed between stages.**
|
||||
Artifacts were designed to upload some compiled/generated bits of the build,
|
||||
and they can be fetched by any number of concurrent Runners. They are
|
||||
guaranteed to be available and are there to pass data between jobs. They are
|
||||
also exposed to be downloaded from the UI.
|
||||
|
||||
It's sometimes confusing because the name artifact sounds like something that
|
||||
is only useful outside of the job, like for downloading a final image. But
|
||||
artifacts are also available in between stages within a pipeline. So if you
|
||||
build your application by downloading all the required modules, you might want
|
||||
to declare them as artifacts so that each subsequent stage can depend on them
|
||||
being there. There are some optimizations like declaring an
|
||||
[expiry time](../yaml/README.md#artifacts-expire_in) so you don't keep artifacts
|
||||
around too long, and using [dependencies](../yaml/README.md#dependencies) to
|
||||
control exactly where artifacts are passed around.
|
||||
|
||||
So, to sum up:
|
||||
- Caches are disabled if not defined globally or per job (using `cache:`)
|
||||
- Caches are available for all jobs in your `.gitlab-ci.yml` if enabled globally
|
||||
- Caches can be used by subsequent pipelines of that very same job (a script in
|
||||
a stage) in which the cache was created (if not defined globally).
|
||||
- Caches are stored where the Runner is installed **and** uploaded to S3 if
|
||||
[distributed cache is enabled](https://docs.gitlab.com/runner/configuration/autoscale.html#distributed-runners-caching)
|
||||
- Caches defined per job are only used either a) for the next pipeline of that job,
|
||||
or b) if that same cache is also defined in a subsequent job of the same pipeline
|
||||
- Artifacts are disabled if not defined per job (using `artifacts:`)
|
||||
- Artifacts can only be enabled per job, not globally
|
||||
- Artifacts are created during a pipeline and can be used by the subsequent
|
||||
jobs of that currently active pipeline
|
||||
- Artifacts are always uploaded to GitLab (known as coordinator)
|
||||
- Artifacts can have an expiration value for controlling disk usage (30 days by default)
|
|
@ -146,24 +146,7 @@ To protect/unprotect Runners:
|
|||
|
||||
## Manually clearing the Runners cache
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/41249) in GitLab 10.4.
|
||||
|
||||
GitLab Runners use [cache](../yaml/README.md#cache) to speed up the execution
|
||||
of your jobs by reusing existing data. This however, can sometimes lead to an
|
||||
inconsistent behavior.
|
||||
|
||||
To start with a fresh copy of the cache, you can easily do it via GitLab's UI:
|
||||
|
||||
1. Navigate to your project's **CI/CD > Pipelines** page.
|
||||
1. Click on the **Clear Runner caches** to clean up the cache.
|
||||
1. On the next push, your CI/CD job will use a new cache.
|
||||
|
||||
That way, you don't have to change the [cache key](../yaml/README.md#cache-key)
|
||||
in your `.gitlab-ci.yml`.
|
||||
|
||||
Behind the scenes, this works by increasing a counter in the database, and the
|
||||
value of that counter is used to create the key for the cache. After a push, a
|
||||
new key is generated and the old cache is not valid anymore.
|
||||
Read [clearing the cache](../caching/index.md#clearing-the-cache).
|
||||
|
||||
## How shared Runners pick jobs
|
||||
|
||||
|
@ -227,15 +210,16 @@ that it may encounter on the projects it's shared over. This would be
|
|||
problematic for large amounts of projects, if it wasn't for tags.
|
||||
|
||||
By tagging a Runner for the types of jobs it can handle, you can make sure
|
||||
shared Runners will only run the jobs they are equipped to run.
|
||||
shared Runners will [only run the jobs they are equipped to run](../yaml/README.md#tags).
|
||||
|
||||
For instance, at GitLab we have Runners tagged with "rails" if they contain
|
||||
the appropriate dependencies to run Rails test suites.
|
||||
|
||||
### Preventing Runners with tags from picking jobs without tags
|
||||
|
||||
You can configure a Runner to prevent it from picking jobs with tags when
|
||||
the Runner does not have tags assigned. This setting can be enabled the first
|
||||
You can configure a Runner to prevent it from picking
|
||||
[jobs with tags](../yaml/README.md#tags) when the Runner does not have tags
|
||||
assigned. This setting can be enabled the first
|
||||
time you [register a Runner][register] and can be changed afterwards under
|
||||
each Runner's settings.
|
||||
|
||||
|
@ -280,3 +264,36 @@ We're always looking for contributions that can mitigate these
|
|||
[register]: http://docs.gitlab.com/runner/register/
|
||||
[protected branches]: ../../user/project/protected_branches.md
|
||||
[protected tags]: ../../user/project/protected_tags.md
|
||||
|
||||
## Determining the IP address of a Runner
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/17286) in GitLab 10.6.
|
||||
|
||||
It may be useful to know the IP address of a Runner so you can troubleshoot
|
||||
issues with that Runner. GitLab stores and displays the IP address by viewing
|
||||
the source of the HTTP requests it makes to GitLab when polling for jobs. The
|
||||
IP address is always kept up to date so if the Runner IP changes it will be
|
||||
automatically updated in GitLab.
|
||||
|
||||
The IP address for shared Runners and specific Runners can be found in
|
||||
different places.
|
||||
|
||||
### Shared Runners
|
||||
|
||||
To view the IP address of a shared Runner you must have admin access to
|
||||
the GitLab instance. To determine this:
|
||||
|
||||
1. Visit **Admin area ➔ Overview ➔ Runners**
|
||||
1. Look for the Runner in the table and you should see a column for "IP Address"
|
||||
|
||||
![shared Runner IP address](img/shared_runner_ip_address.png)
|
||||
|
||||
### Specific Runners
|
||||
|
||||
You can find the IP address of a Runner for a specific project by:
|
||||
|
||||
1. Visit your project's **Settings ➔ CI/CD**
|
||||
1. Find the Runner and click on it's ID which links you to the details page
|
||||
1. On the details page you should see a row for "IP Address"
|
||||
|
||||
![specific Runner IP address](img/specific_runner_ip_address.png)
|
||||
|
|
BIN
doc/ci/runners/img/shared_runner_ip_address.png
Normal file
BIN
doc/ci/runners/img/shared_runner_ip_address.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
BIN
doc/ci/runners/img/specific_runner_ip_address.png
Normal file
BIN
doc/ci/runners/img/specific_runner_ip_address.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
|
@ -843,6 +843,185 @@ GitLab's web interface in order to run.
|
|||
|
||||
The `stop_review_app` job is **required** to have the following keywords defined:
|
||||
|
||||
- `when` - [reference](#when)
|
||||
- `environment:name`
|
||||
- `environment:action`
|
||||
- `stage` should be the same as the `review_app` in order for the environment
|
||||
to stop automatically when the branch is deleted
|
||||
|
||||
### Dynamic environments
|
||||
|
||||
>
|
||||
**Notes:**
|
||||
- [Introduced][ce-6323] in GitLab 8.12 and GitLab Runner 1.6.
|
||||
- The `$CI_ENVIRONMENT_SLUG` was [introduced][ce-7983] in GitLab 8.15.
|
||||
- The `name` and `url` parameters can use any of the defined CI variables,
|
||||
including predefined, secure variables and `.gitlab-ci.yml` [`variables`](#variables).
|
||||
You however cannot use variables defined under `script`.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
deploy as review app:
|
||||
stage: deploy
|
||||
script: make deploy
|
||||
environment:
|
||||
name: review/$CI_COMMIT_REF_NAME
|
||||
url: https://$CI_ENVIRONMENT_SLUG.example.com/
|
||||
```
|
||||
|
||||
The `deploy as review app` job will be marked as deployment to dynamically
|
||||
create the `review/$CI_COMMIT_REF_NAME` environment, where `$CI_COMMIT_REF_NAME`
|
||||
is an [environment variable][variables] set by the Runner. The
|
||||
`$CI_ENVIRONMENT_SLUG` variable is based on the environment name, but suitable
|
||||
for inclusion in URLs. In this case, if the `deploy as review app` job was run
|
||||
in a branch named `pow`, this environment would be accessible with an URL like
|
||||
`https://review-pow.example.com/`.
|
||||
|
||||
This of course implies that the underlying server which hosts the application
|
||||
is properly configured.
|
||||
|
||||
The common use case is to create dynamic environments for branches and use them
|
||||
as Review Apps. You can see a simple example using Review Apps at
|
||||
<https://gitlab.com/gitlab-examples/review-apps-nginx/>.
|
||||
|
||||
## `cache`
|
||||
|
||||
>
|
||||
**Notes:**
|
||||
- Introduced in GitLab Runner v0.7.0.
|
||||
- `cache` can be set globally and per-job.
|
||||
- From GitLab 9.0, caching is enabled and shared between pipelines and jobs
|
||||
by default.
|
||||
- From GitLab 9.2, caches are restored before [artifacts](#artifacts).
|
||||
|
||||
TIP: **Learn more:**
|
||||
Read how caching works and find out some good practices in the
|
||||
[caching dependencies documentation](../caching/index.md).
|
||||
|
||||
`cache` is used to specify a list of files and directories which should be
|
||||
cached between jobs. You can only use paths that are within the project
|
||||
workspace.
|
||||
|
||||
If `cache` is defined outside the scope of jobs, it means it is set
|
||||
globally and all jobs will use that definition.
|
||||
|
||||
### `cache:paths`
|
||||
|
||||
Use the `paths` directive to choose which files or directories will be cached.
|
||||
Wildcards can be used as well.
|
||||
|
||||
Cache all files in `binaries` that end in `.apk` and the `.config` file:
|
||||
|
||||
```yaml
|
||||
rspec:
|
||||
script: test
|
||||
cache:
|
||||
paths:
|
||||
- binaries/*.apk
|
||||
- .config
|
||||
```
|
||||
|
||||
Locally defined cache overrides globally defined options. The following `rspec`
|
||||
job will cache only `binaries/`:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
paths:
|
||||
- my/files
|
||||
|
||||
rspec:
|
||||
script: test
|
||||
cache:
|
||||
paths:
|
||||
- binaries/
|
||||
```
|
||||
|
||||
### `cache:key`
|
||||
|
||||
> Introduced in GitLab Runner v1.0.0.
|
||||
|
||||
Since the cache is shared between jobs, if you're using different
|
||||
paths for different jobs, you should also set a different `cache:key`
|
||||
otherwise cache content can be overwritten.
|
||||
|
||||
The `key` directive allows you to define the affinity of caching between jobs,
|
||||
allowing to have a single cache for all jobs, cache per-job, cache per-branch
|
||||
or any other way that fits your workflow. This way, you can fine tune caching,
|
||||
allowing you to cache data between different jobs or even different branches.
|
||||
|
||||
The `cache:key` variable can use any of the
|
||||
[predefined variables](../variables/README.md), and the default key, if not set,
|
||||
is `$CI_JOB_NAME-$CI_COMMIT_REF_NAME` which translates as "per-job and
|
||||
per-branch". It is the default across the project, therefore everything is
|
||||
shared between pipelines and jobs running on the same branch by default.
|
||||
|
||||
NOTE: **Note:**
|
||||
The `cache:key` variable cannot contain the `/` character, or the equivalent
|
||||
URI-encoded `%2F`; a value made only of dots (`.`, `%2E`) is also forbidden.
|
||||
|
||||
For example, to enable per-branch caching:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key: "$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- binaries/
|
||||
```
|
||||
|
||||
If you use **Windows Batch** to run your shell scripts you need to replace
|
||||
`$` with `%`:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key: "%CI_JOB_STAGE%-%CI_COMMIT_REF_SLUG%"
|
||||
paths:
|
||||
- binaries/
|
||||
```
|
||||
|
||||
If you use **Windows PowerShell** to run your shell scripts you need to replace
|
||||
`$` with `$env:`:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- binaries/
|
||||
```
|
||||
|
||||
### `cache:untracked`
|
||||
|
||||
Set `untracked: true` to cache all files that are untracked in your Git
|
||||
repository:
|
||||
|
||||
```yaml
|
||||
rspec:
|
||||
script: test
|
||||
cache:
|
||||
untracked: true
|
||||
```
|
||||
|
||||
Cache all Git untracked files and files in `binaries`:
|
||||
|
||||
```yaml
|
||||
rspec:
|
||||
script: test
|
||||
cache:
|
||||
untracked: true
|
||||
paths:
|
||||
- binaries/
|
||||
>>>>>>> 03bbd847deb... Merge branch 'docs/ci-caching' into 'master'
|
||||
```
|
||||
|
||||
In the above example we set up the `review_app` job to deploy to the `review`
|
||||
environment, and we also defined a new `stop_review_app` job under `on_stop`.
|
||||
Once the `review_app` job is successfully finished, it will trigger the
|
||||
`stop_review_app` job based on what is defined under `when`. In this case we
|
||||
set it up to `manual` so it will need a [manual action](#manual-actions) via
|
||||
GitLab's web interface in order to run.
|
||||
|
||||
The `stop_review_app` job is **required** to have the following keywords defined:
|
||||
|
||||
- `when` - [reference](#when)
|
||||
- `environment:name`
|
||||
- `environment:action`
|
||||
|
|
|
@ -10,7 +10,7 @@ should be deployed, upgraded, and configured.
|
|||
## Chart Overview
|
||||
|
||||
* **[GitLab-Omnibus](gitlab_omnibus.md)**: The best way to run GitLab on Kubernetes today, suited for small deployments. The chart is in beta and will be deprecated by the [cloud native GitLab chart](#cloud-native-gitlab-chart).
|
||||
* **[Cloud Native GitLab Chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md)**: The next generation GitLab chart, currently in development. Will support large deployments with horizontal scaling of individual GitLab components.
|
||||
* **[Cloud Native GitLab Chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md)**: The next generation GitLab chart, currently in alpha. Will support large deployments with horizontal scaling of individual GitLab components.
|
||||
* Other Charts
|
||||
* [GitLab Runner Chart](gitlab_runner_chart.md): For deploying just the GitLab Runner.
|
||||
* [Advanced GitLab Installation](gitlab_chart.md): Deprecated, being replaced by the [cloud native GitLab chart](#cloud-native-gitlab-chart). Provides additional deployment options, but provides less functionality out-of-the-box.
|
||||
|
@ -35,7 +35,7 @@ By offering individual containers and charts, we will be able to provide a numbe
|
|||
* Potential for rolling updates and canaries within a service,
|
||||
* and plenty more.
|
||||
|
||||
This is a large project and will be worked on over the span of multiple releases. For the most up-to-date status and release information, please see our [tracking issue](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/2420). We are planning to launch this chart in beta by the end of 2017.
|
||||
Presently this chart is available in alpha for testing, and not recommended for production use.
|
||||
|
||||
Learn more about the [cloud native GitLab chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md).
|
||||
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
# Allow maintainer pushes for merge requests across forks
|
||||
|
||||
> [Introduced][ce-17395] in GitLab 10.6.
|
||||
|
||||
This feature is available for merge requests across forked projects that are
|
||||
publicly accessible. It makes it easier for maintainers of projects to collaborate
|
||||
on merge requests across forks.
|
||||
publicly accessible. It makes it easier for maintainers of projects to
|
||||
collaborate on merge requests across forks.
|
||||
|
||||
When enabling this feature for a merge request, you give can give members with push access to the target project rights to edit files on the source branch of the merge request.
|
||||
When enabled for a merge request, members with merge access to the target
|
||||
branch of the project will be granted write permissions to the source branch
|
||||
of the merge request.
|
||||
|
||||
The feature can only be enabled by users who already have push access to the source project. And only lasts while the merge request is open.
|
||||
The feature can only be enabled by users who already have push access to the
|
||||
source project, and only lasts while the merge request is open.
|
||||
|
||||
Enable this functionality while creating a merge request:
|
||||
|
||||
|
|
|
@ -21,12 +21,13 @@ module Banzai
|
|||
#
|
||||
# See http://en.wikipedia.org/wiki/URI_scheme
|
||||
#
|
||||
# The negative lookbehind ensures that users can paste a URL followed by a
|
||||
# period or comma for punctuation without those characters being included
|
||||
# in the generated link.
|
||||
# The negative lookbehind ensures that users can paste a URL followed by
|
||||
# punctuation without those characters being included in the generated
|
||||
# link. It matches the behaviour of Rinku 2.0.1:
|
||||
# https://github.com/vmg/rinku/blob/v2.0.1/ext/rinku/autolink.c#L65
|
||||
#
|
||||
# Rubular: http://rubular.com/r/JzPhi6DCZp
|
||||
LINK_PATTERN = %r{([a-z][a-z0-9\+\.-]+://[^\s>]+)(?<!,|\.)}
|
||||
# Rubular: http://rubular.com/r/nrL3r9yUiq
|
||||
LINK_PATTERN = %r{([a-z][a-z0-9\+\.-]+://[^\s>]+)(?<!\?|!|\.|,|:)}
|
||||
|
||||
# Text matching LINK_PATTERN inside these elements will not be linked
|
||||
IGNORE_PARENTS = %w(a code kbd pre script style).to_set
|
||||
|
|
|
@ -69,7 +69,11 @@ module Gitlab
|
|||
|
||||
authenticators.compact!
|
||||
|
||||
user if authenticators.find { |auth| auth.login(login, password) }
|
||||
# return found user that was authenticated first for given login credentials
|
||||
authenticators.find do |auth|
|
||||
authenticated_user = auth.login(login, password)
|
||||
break authenticated_user if authenticated_user
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ module Gitlab
|
|||
def login(login, password)
|
||||
return false unless Gitlab::CurrentSettings.password_authentication_enabled_for_git?
|
||||
|
||||
user&.valid_password?(password)
|
||||
return user if user&.valid_password?(password)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,30 +12,26 @@ module Gitlab
|
|||
return unless Gitlab::Auth::LDAP::Config.enabled?
|
||||
return unless login.present? && password.present?
|
||||
|
||||
auth = nil
|
||||
# loop through providers until valid bind
|
||||
# return found user that was authenticated by first provider for given login credentials
|
||||
providers.find do |provider|
|
||||
auth = new(provider)
|
||||
auth.login(login, password) # true will exit the loop
|
||||
break auth.user if auth.login(login, password) # true will exit the loop
|
||||
end
|
||||
|
||||
# If (login, password) was invalid for all providers, the value of auth is now the last
|
||||
# Gitlab::Auth::LDAP::Authentication instance we tried.
|
||||
auth.user
|
||||
end
|
||||
|
||||
def self.providers
|
||||
Gitlab::Auth::LDAP::Config.providers
|
||||
end
|
||||
|
||||
attr_accessor :ldap_user
|
||||
|
||||
def login(login, password)
|
||||
@ldap_user = adapter.bind_as(
|
||||
result = adapter.bind_as(
|
||||
filter: user_filter(login),
|
||||
size: 1,
|
||||
password: password
|
||||
)
|
||||
return unless result
|
||||
|
||||
@user = Gitlab::Auth::LDAP::User.find_by_uid_and_provider(result.dn, provider)
|
||||
end
|
||||
|
||||
def adapter
|
||||
|
@ -56,12 +52,6 @@ module Gitlab
|
|||
|
||||
filter
|
||||
end
|
||||
|
||||
def user
|
||||
return unless ldap_user
|
||||
|
||||
Gitlab::Auth::LDAP::User.find_by_uid_and_provider(ldap_user.dn, provider)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,6 +12,7 @@ module Gitlab
|
|||
@user = user
|
||||
end
|
||||
|
||||
# Implementation must return user object if login successful
|
||||
def login(login, password)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
|
|
@ -40,7 +40,10 @@ module Gitlab
|
|||
# when there are no conflict files.
|
||||
files.each(&:lines)
|
||||
files.any?
|
||||
rescue Gitlab::Git::CommandError, Gitlab::Git::Conflict::Parser::UnresolvableError, Gitlab::Git::Conflict::Resolver::ConflictSideMissing
|
||||
rescue Gitlab::Git::CommandError,
|
||||
Gitlab::Git::Conflict::Parser::UnresolvableError,
|
||||
Gitlab::Git::Conflict::Resolver::ConflictSideMissing,
|
||||
Gitlab::Git::Conflict::File::UnsupportedEncoding
|
||||
false
|
||||
end
|
||||
cache_method :can_be_resolved_in_ui?
|
||||
|
|
|
@ -90,7 +90,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def clean(message)
|
||||
message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: "")
|
||||
message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: "".encode("UTF-16BE"))
|
||||
.encode("UTF-8")
|
||||
.gsub("\0".encode("UTF-8"), "")
|
||||
end
|
||||
|
|
|
@ -2,17 +2,19 @@ module Gitlab
|
|||
module Git
|
||||
module Conflict
|
||||
class File
|
||||
UnsupportedEncoding = Class.new(StandardError)
|
||||
|
||||
attr_reader :their_path, :our_path, :our_mode, :repository, :commit_oid
|
||||
|
||||
attr_accessor :content
|
||||
attr_accessor :raw_content
|
||||
|
||||
def initialize(repository, commit_oid, conflict, content)
|
||||
def initialize(repository, commit_oid, conflict, raw_content)
|
||||
@repository = repository
|
||||
@commit_oid = commit_oid
|
||||
@their_path = conflict[:theirs][:path]
|
||||
@our_path = conflict[:ours][:path]
|
||||
@our_mode = conflict[:ours][:mode]
|
||||
@content = content
|
||||
@raw_content = raw_content
|
||||
end
|
||||
|
||||
def lines
|
||||
|
@ -29,6 +31,14 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def content
|
||||
@content ||= @raw_content.dup.force_encoding('UTF-8')
|
||||
|
||||
raise UnsupportedEncoding unless @content.valid_encoding?
|
||||
|
||||
@content
|
||||
end
|
||||
|
||||
def type
|
||||
lines unless @type
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ module Gitlab
|
|||
class Parser
|
||||
UnresolvableError = Class.new(StandardError)
|
||||
UnmergeableFile = Class.new(UnresolvableError)
|
||||
UnsupportedEncoding = Class.new(UnresolvableError)
|
||||
|
||||
# Recoverable errors - the conflict can be resolved in an editor, but not with
|
||||
# sections.
|
||||
|
@ -75,10 +74,6 @@ module Gitlab
|
|||
def validate_text!(text)
|
||||
raise UnmergeableFile if text.blank? # Typically a binary file
|
||||
raise UnmergeableFile if text.length > 200.kilobytes
|
||||
|
||||
text.force_encoding('UTF-8')
|
||||
|
||||
raise UnsupportedEncoding unless text.valid_encoding?
|
||||
end
|
||||
|
||||
def validate_delimiter!(condition)
|
||||
|
|
|
@ -17,7 +17,7 @@ module Gitlab
|
|||
|
||||
current_file = file_from_gitaly_header(gitaly_file.header)
|
||||
else
|
||||
current_file.content << gitaly_file.content
|
||||
current_file.raw_content << gitaly_file.content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -122,14 +122,10 @@ describe Banzai::Filter::AutolinkFilter do
|
|||
end
|
||||
|
||||
it 'does not include trailing punctuation' do
|
||||
doc = filter("See #{link}.")
|
||||
expect(doc.at_css('a').text).to eq link
|
||||
|
||||
doc = filter("See #{link}, ok?")
|
||||
expect(doc.at_css('a').text).to eq link
|
||||
|
||||
doc = filter("See #{link}...")
|
||||
expect(doc.at_css('a').text).to eq link
|
||||
['.', ', ok?', '...', '?', '!', ': is that ok?'].each do |trailing_punctuation|
|
||||
doc = filter("See #{link}#{trailing_punctuation}")
|
||||
expect(doc.at_css('a').text).to eq link
|
||||
end
|
||||
end
|
||||
|
||||
it 'includes trailing punctuation when part of a balanced pair' do
|
||||
|
|
|
@ -315,13 +315,19 @@ describe Gitlab::Auth do
|
|||
it "tries to autheticate with db before ldap" do
|
||||
expect(Gitlab::Auth::LDAP::Authentication).not_to receive(:login)
|
||||
|
||||
gl_auth.find_with_user_password(username, password)
|
||||
expect(gl_auth.find_with_user_password(username, password)).to eq(user)
|
||||
end
|
||||
|
||||
it "uses ldap as fallback to for authentication" do
|
||||
expect(Gitlab::Auth::LDAP::Authentication).to receive(:login)
|
||||
it "does not find user by using ldap as fallback to for authentication" do
|
||||
expect(Gitlab::Auth::LDAP::Authentication).to receive(:login).and_return(nil)
|
||||
|
||||
gl_auth.find_with_user_password('ldap_user', 'password')
|
||||
expect(gl_auth.find_with_user_password('ldap_user', 'password')).to be_nil
|
||||
end
|
||||
|
||||
it "find new user by using ldap as fallback to for authentication" do
|
||||
expect(Gitlab::Auth::LDAP::Authentication).to receive(:login).and_return(user)
|
||||
|
||||
expect(gl_auth.find_with_user_password('ldap_user', 'password')).to eq(user)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -510,6 +510,28 @@ describe Gitlab::Ci::Trace do
|
|||
|
||||
it_behaves_like 'source trace in database stays intact', error: ActiveRecord::RecordInvalid
|
||||
end
|
||||
|
||||
context 'when there is a validation error on Ci::Build' do
|
||||
before do
|
||||
allow_any_instance_of(Ci::Build).to receive(:save).and_return(false)
|
||||
allow_any_instance_of(Ci::Build).to receive_message_chain(:errors, :full_messages)
|
||||
.and_return(%w[Error Error])
|
||||
end
|
||||
|
||||
context "when erase old trace with 'save'" do
|
||||
before do
|
||||
build.send(:write_attribute, :trace, nil)
|
||||
build.save
|
||||
end
|
||||
|
||||
it 'old trace is not deleted' do
|
||||
build.reload
|
||||
expect(build.trace.raw).to eq(trace_content)
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'archive trace in database'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -161,6 +161,11 @@ describe Gitlab::EncodingHelper do
|
|||
'removes invalid bytes from ASCII-8bit encoded multibyte string.',
|
||||
"Lorem ipsum\xC3\n dolor sit amet, xy\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg".force_encoding('ASCII-8BIT'),
|
||||
"Lorem ipsum\n dolor sit amet, xyàyùabcdùefg"
|
||||
],
|
||||
[
|
||||
'handles UTF-16BE encoded strings',
|
||||
"\xFE\xFF\x00\x41".force_encoding('ASCII-8BIT'), # An "A" prepended with UTF-16 BOM
|
||||
"\xEF\xBB\xBFA" # An "A" prepended with UTF-8 BOM
|
||||
]
|
||||
].each do |description, test_string, xpect|
|
||||
it description do
|
||||
|
|
50
spec/lib/gitlab/git/conflict/file_spec.rb
Normal file
50
spec/lib/gitlab/git/conflict/file_spec.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# coding: utf-8
|
||||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::Git::Conflict::File do
|
||||
let(:conflict) { { theirs: { path: 'foo', mode: 33188 }, ours: { path: 'foo', mode: 33188 } } }
|
||||
let(:invalid_content) { described_class.new(nil, nil, conflict, "a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }
|
||||
let(:valid_content) { described_class.new(nil, nil, conflict, "Espa\xC3\xB1a".force_encoding(Encoding::ASCII_8BIT)) }
|
||||
|
||||
describe '#lines' do
|
||||
context 'when the content contains non-UTF-8 characters' do
|
||||
it 'raises UnsupportedEncoding' do
|
||||
expect { invalid_content.lines }
|
||||
.to raise_error(described_class::UnsupportedEncoding)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the content can be converted to UTF-8' do
|
||||
it 'sets lines to the lines' do
|
||||
expect(valid_content.lines).to eq([{
|
||||
full_line: 'España',
|
||||
type: nil,
|
||||
line_obj_index: 0,
|
||||
line_old: 1,
|
||||
line_new: 1
|
||||
}])
|
||||
end
|
||||
|
||||
it 'sets the type to text' do
|
||||
expect(valid_content.type).to eq('text')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#content' do
|
||||
context 'when the content contains non-UTF-8 characters' do
|
||||
it 'raises UnsupportedEncoding' do
|
||||
expect { invalid_content.content }
|
||||
.to raise_error(described_class::UnsupportedEncoding)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the content can be converted to UTF-8' do
|
||||
it 'returns a valid UTF-8 string' do
|
||||
expect(valid_content.content).to eq('España')
|
||||
expect(valid_content.content).to be_valid_encoding
|
||||
expect(valid_content.content.encoding).to eq(Encoding::UTF_8)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -212,13 +212,6 @@ CONFLICT
|
|||
.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the file contains non-UTF-8 characters' do
|
||||
it 'raises UnsupportedEncoding' do
|
||||
expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }
|
||||
.to raise_error(Gitlab::Git::Conflict::Parser::UnsupportedEncoding)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2050,6 +2050,35 @@ describe Ci::Build do
|
|||
|
||||
subject.drop!
|
||||
end
|
||||
|
||||
context 'when retry service raises Gitlab::Access::AccessDeniedError exception' do
|
||||
let(:retry_service) { Ci::RetryBuildService.new(subject.project, subject.user) }
|
||||
|
||||
before do
|
||||
allow_any_instance_of(Ci::RetryBuildService)
|
||||
.to receive(:execute)
|
||||
.with(subject)
|
||||
.and_raise(Gitlab::Access::AccessDeniedError)
|
||||
allow(Rails.logger).to receive(:error)
|
||||
end
|
||||
|
||||
it 'handles raised exception' do
|
||||
expect { subject.drop! }.not_to raise_exception(Gitlab::Access::AccessDeniedError)
|
||||
end
|
||||
|
||||
it 'logs the error' do
|
||||
subject.drop!
|
||||
|
||||
expect(Rails.logger)
|
||||
.to have_received(:error)
|
||||
.with(a_string_matching("Unable to auto-retry job #{subject.id}"))
|
||||
end
|
||||
|
||||
it 'fails the job' do
|
||||
subject.drop!
|
||||
expect(subject.failed?).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when build is not configured to be retried' do
|
||||
|
|
2235
vendor/assets/javascripts/xterm/xterm.js
vendored
Normal file
2235
vendor/assets/javascripts/xterm/xterm.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue