summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock12
-rw-r--r--app/models/ci/pipeline.rb6
-rw-r--r--app/models/clusters/platforms/kubernetes.rb4
-rw-r--r--app/models/clusters/providers/gcp.rb2
-rw-r--r--app/models/concerns/atomic_internal_id.rb16
-rw-r--r--app/models/concerns/iid_routes.rb9
-rw-r--r--app/models/deployment.rb1
-rw-r--r--app/models/internal_id.rb2
-rw-r--r--app/models/issue.rb1
-rw-r--r--app/models/merge_request.rb1
-rw-r--r--app/models/milestone.rb1
-rw-r--r--changelogs/unreleased/47183-update-selenium-webdriver-to-3-12-0.yml5
-rw-r--r--changelogs/unreleased/per-project-pipeline-iid.yml5
-rw-r--r--changelogs/unreleased/sh-fix-secrets-not-working.yml5
-rw-r--r--config/settings.rb23
-rw-r--r--db/migrate/20180424160449_add_pipeline_iid_to_ci_pipelines.rb13
-rw-r--r--db/migrate/20180425205249_add_index_constraints_to_pipeline_iid.rb15
-rw-r--r--db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb2
-rw-r--r--db/schema.rb2
-rw-r--r--doc/administration/pages/index.md22
-rw-r--r--doc/administration/pages/source.md18
-rw-r--r--doc/api/merge_requests.md1
-rw-r--r--doc/ci/variables/README.md4
-rw-r--r--doc/install/kubernetes/gitlab_omnibus.md2
-rw-r--r--lib/gitlab/ci/pipeline/chain/populate.rb3
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb65
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/models/ci/build_spec.rb1
-rw-r--r--spec/models/ci/pipeline_spec.rb13
-rw-r--r--spec/models/deployment_spec.rb1
-rw-r--r--spec/models/issue_spec.rb1
-rw-r--r--spec/models/merge_request_spec.rb1
-rw-r--r--spec/models/milestone_spec.rb2
-rw-r--r--spec/support/shared_examples/models/atomic_internal_id_spec.rb29
35 files changed, 224 insertions, 69 deletions
diff --git a/Gemfile b/Gemfile
index 68c7b3dcb08..ae1301c335a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -342,7 +342,7 @@ group :development, :test do
gem 'capybara', '~> 2.15'
gem 'capybara-screenshot', '~> 1.0.0'
- gem 'selenium-webdriver', '~> 3.5'
+ gem 'selenium-webdriver', '~> 3.12'
gem 'spring', '~> 2.0.0'
gem 'spring-commands-rspec', '~> 1.0.4'
@@ -384,7 +384,7 @@ group :test do
gem 'test-prof', '~> 0.2.5'
end
-gem 'octokit', '~> 4.8'
+gem 'octokit', '~> 4.9'
gem 'mail_room', '~> 0.9.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 2efd89bf40d..e6e8f3d11bc 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -115,7 +115,7 @@ GEM
mime-types (>= 1.16)
cause (0.1)
charlock_holmes (0.7.6)
- childprocess (0.7.0)
+ childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
chronic (0.10.2)
chronic_duration (0.10.6)
@@ -517,7 +517,7 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
- octokit (4.8.0)
+ octokit (4.9.0)
sawyer (~> 0.8.0, >= 0.5.3)
omniauth (1.8.1)
hashie (>= 3.4.6, < 3.6.0)
@@ -828,9 +828,9 @@ GEM
activesupport (>= 3.1)
select2-rails (3.5.9.3)
thor (~> 0.14)
- selenium-webdriver (3.5.0)
+ selenium-webdriver (3.12.0)
childprocess (~> 0.5)
- rubyzip (~> 1.0)
+ rubyzip (~> 1.2)
sentry-raven (2.7.2)
faraday (>= 0.7.6, < 1.0)
settingslogic (2.0.9)
@@ -1084,7 +1084,7 @@ DEPENDENCIES
net-ssh (~> 4.2.0)
nokogiri (~> 1.8.2)
oauth2 (~> 1.4)
- octokit (~> 4.8)
+ octokit (~> 4.9)
omniauth (~> 1.8)
omniauth-auth0 (~> 2.0.0)
omniauth-authentiq (~> 0.3.3)
@@ -1154,7 +1154,7 @@ DEPENDENCIES
scss_lint (~> 0.56.0)
seed-fu (~> 2.3.7)
select2-rails (~> 3.5.9)
- selenium-webdriver (~> 3.5)
+ selenium-webdriver (~> 3.12)
sentry-raven (~> 2.7)
settingslogic (~> 2.0.9)
sham_rack (~> 1.3.6)
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 53af87a271a..5eb30f4aaa0 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -7,12 +7,17 @@ module Ci
include Presentable
include Gitlab::OptimisticLocking
include Gitlab::Utils::StrongMemoize
+ include AtomicInternalId
belongs_to :project, inverse_of: :pipelines
belongs_to :user
belongs_to :auto_canceled_by, class_name: 'Ci::Pipeline'
belongs_to :pipeline_schedule, class_name: 'Ci::PipelineSchedule'
+ has_internal_id :iid, scope: :project, presence: false, init: ->(s) do
+ s&.project&.pipelines&.maximum(:iid) || s&.project&.pipelines&.count
+ end
+
has_many :stages
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
has_many :builds, foreign_key: :commit_id, inverse_of: :pipeline
@@ -531,6 +536,7 @@ module Ci
def predefined_variables
Gitlab::Ci::Variables::Collection.new
+ .append(key: 'CI_PIPELINE_IID', value: iid.to_s)
.append(key: 'CI_CONFIG_PATH', value: ci_yaml_file_path)
.append(key: 'CI_PIPELINE_SOURCE', value: source.to_s)
.append(key: 'CI_COMMIT_MESSAGE', value: git_commit_message)
diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb
index 25eac5160f1..36631d57ad1 100644
--- a/app/models/clusters/platforms/kubernetes.rb
+++ b/app/models/clusters/platforms/kubernetes.rb
@@ -11,12 +11,12 @@ module Clusters
attr_encrypted :password,
mode: :per_attribute_iv,
- key: Settings.attr_encrypted_db_key_base,
+ key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc'
attr_encrypted :token,
mode: :per_attribute_iv,
- key: Settings.attr_encrypted_db_key_base,
+ key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc'
before_validation :enforce_namespace_to_lower_case
diff --git a/app/models/clusters/providers/gcp.rb b/app/models/clusters/providers/gcp.rb
index eb2e42fd3fe..4db1bb35c12 100644
--- a/app/models/clusters/providers/gcp.rb
+++ b/app/models/clusters/providers/gcp.rb
@@ -11,7 +11,7 @@ module Clusters
attr_encrypted :access_token,
mode: :per_attribute_iv,
- key: Settings.attr_encrypted_db_key_base,
+ key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc'
validates :gcp_project_id,
diff --git a/app/models/concerns/atomic_internal_id.rb b/app/models/concerns/atomic_internal_id.rb
index 22f516a172f..164c704260e 100644
--- a/app/models/concerns/atomic_internal_id.rb
+++ b/app/models/concerns/atomic_internal_id.rb
@@ -25,9 +25,13 @@ module AtomicInternalId
extend ActiveSupport::Concern
module ClassMethods
- def has_internal_id(column, scope:, init:) # rubocop:disable Naming/PredicateName
- before_validation(on: :create) do
+ def has_internal_id(column, scope:, init:, presence: true) # rubocop:disable Naming/PredicateName
+ before_validation :"ensure_#{scope}_#{column}!", on: :create
+ validates column, presence: presence
+
+ define_method("ensure_#{scope}_#{column}!") do
scope_value = association(scope).reader
+
if read_attribute(column).blank? && scope_value
scope_attrs = { scope_value.class.table_name.singularize.to_sym => scope_value }
usage = self.class.table_name.to_sym
@@ -35,13 +39,9 @@ module AtomicInternalId
new_iid = InternalId.generate_next(self, scope_attrs, usage, init)
write_attribute(column, new_iid)
end
- end
- validates column, presence: true, numericality: true
+ read_attribute(column)
+ end
end
end
-
- def to_param
- iid.to_s
- end
end
diff --git a/app/models/concerns/iid_routes.rb b/app/models/concerns/iid_routes.rb
new file mode 100644
index 00000000000..246748cf52c
--- /dev/null
+++ b/app/models/concerns/iid_routes.rb
@@ -0,0 +1,9 @@
+module IidRoutes
+ ##
+ # This automagically enforces all related routes to use `iid` instead of `id`
+ # If you want to use `iid` for some routes and `id` for other routes, this module should not to be included,
+ # instead you should define `iid` or `id` explictly at each route generators. e.g. pipeline_path(project.id, pipeline.iid)
+ def to_param
+ iid.to_s
+ end
+end
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 254764eefde..ac86e9e8de0 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -1,5 +1,6 @@
class Deployment < ActiveRecord::Base
include AtomicInternalId
+ include IidRoutes
belongs_to :project, required: true
belongs_to :environment, required: true
diff --git a/app/models/internal_id.rb b/app/models/internal_id.rb
index f7f930e86ed..f50f28deffe 100644
--- a/app/models/internal_id.rb
+++ b/app/models/internal_id.rb
@@ -14,7 +14,7 @@ class InternalId < ActiveRecord::Base
belongs_to :project
belongs_to :namespace
- enum usage: { issues: 0, merge_requests: 1, deployments: 2, milestones: 3, epics: 4 }
+ enum usage: { issues: 0, merge_requests: 1, deployments: 2, milestones: 3, epics: 4, ci_pipelines: 5 }
validates :usage, presence: true
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 41a290f34b4..d136700836d 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -2,6 +2,7 @@ require 'carrierwave/orm/activerecord'
class Issue < ActiveRecord::Base
include AtomicInternalId
+ include IidRoutes
include Issuable
include Noteable
include Referable
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 79fc155fd3c..4c1628d2bdb 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1,5 +1,6 @@
class MergeRequest < ActiveRecord::Base
include AtomicInternalId
+ include IidRoutes
include Issuable
include Noteable
include Referable
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index d14e3a4ded5..d05dcfd083a 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -9,6 +9,7 @@ class Milestone < ActiveRecord::Base
include CacheMarkdownField
include AtomicInternalId
+ include IidRoutes
include Sortable
include Referable
include StripAttribute
diff --git a/changelogs/unreleased/47183-update-selenium-webdriver-to-3-12-0.yml b/changelogs/unreleased/47183-update-selenium-webdriver-to-3-12-0.yml
new file mode 100644
index 00000000000..b0d51d810f2
--- /dev/null
+++ b/changelogs/unreleased/47183-update-selenium-webdriver-to-3-12-0.yml
@@ -0,0 +1,5 @@
+---
+title: Update selenium-webdriver to 3.12.0
+merge_request: 19351
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/per-project-pipeline-iid.yml b/changelogs/unreleased/per-project-pipeline-iid.yml
new file mode 100644
index 00000000000..78a513a9986
--- /dev/null
+++ b/changelogs/unreleased/per-project-pipeline-iid.yml
@@ -0,0 +1,5 @@
+---
+title: Add per-project pipeline id
+merge_request: 18558
+author:
+type: added
diff --git a/changelogs/unreleased/sh-fix-secrets-not-working.yml b/changelogs/unreleased/sh-fix-secrets-not-working.yml
new file mode 100644
index 00000000000..044a873ecd9
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-secrets-not-working.yml
@@ -0,0 +1,5 @@
+---
+title: Fix attr_encryption key settings
+merge_request:
+author:
+type: fixed
diff --git a/config/settings.rb b/config/settings.rb
index 58f38d103ea..3f3481bb65d 100644
--- a/config/settings.rb
+++ b/config/settings.rb
@@ -85,17 +85,24 @@ class Settings < Settingslogic
File.expand_path(path, Rails.root)
end
- # Returns a 256-bit key for attr_encrypted
- def attr_encrypted_db_key_base
- # Ruby 2.4+ requires passing in the exact required length for OpenSSL keys
- # (https://github.com/ruby/ruby/commit/ce635262f53b760284d56bb1027baebaaec175d1).
- # Previous versions quietly truncated the input.
- #
- # The default mode for the attr_encrypted gem is to use a 256-bit key.
- # We truncate the 128-byte string to 32 bytes.
+ # Ruby 2.4+ requires passing in the exact required length for OpenSSL keys
+ # (https://github.com/ruby/ruby/commit/ce635262f53b760284d56bb1027baebaaec175d1).
+ # Previous versions quietly truncated the input.
+ #
+ # Use this when using :per_attribute_iv mode for attr_encrypted.
+ # We have to truncate the string to 32 bytes for a 256-bit cipher.
+ def attr_encrypted_db_key_base_truncated
Gitlab::Application.secrets.db_key_base[0..31]
end
+ # This should be used for :per_attribute_salt_and_iv mode. There is no
+ # need to truncate the key because the encryptor will use the salt to
+ # generate a hash of the password:
+ # https://github.com/attr-encrypted/encryptor/blob/c3a62c4a9e74686dd95e0548f9dc2a361fdc95d1/lib/encryptor.rb#L77
+ def attr_encrypted_db_key_base
+ Gitlab::Application.secrets.db_key_base
+ end
+
private
def base_url(config)
diff --git a/db/migrate/20180424160449_add_pipeline_iid_to_ci_pipelines.rb b/db/migrate/20180424160449_add_pipeline_iid_to_ci_pipelines.rb
new file mode 100644
index 00000000000..e8f0c91d612
--- /dev/null
+++ b/db/migrate/20180424160449_add_pipeline_iid_to_ci_pipelines.rb
@@ -0,0 +1,13 @@
+class AddPipelineIidToCiPipelines < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ add_column :ci_pipelines, :iid, :integer
+ end
+
+ def down
+ remove_column :ci_pipelines, :iid, :integer
+ end
+end
diff --git a/db/migrate/20180425205249_add_index_constraints_to_pipeline_iid.rb b/db/migrate/20180425205249_add_index_constraints_to_pipeline_iid.rb
new file mode 100644
index 00000000000..3fa59b44d5d
--- /dev/null
+++ b/db/migrate/20180425205249_add_index_constraints_to_pipeline_iid.rb
@@ -0,0 +1,15 @@
+class AddIndexConstraintsToPipelineIid < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :ci_pipelines, [:project_id, :iid], unique: true, where: 'iid IS NOT NULL'
+ end
+
+ def down
+ remove_concurrent_index :ci_pipelines, [:project_id, :iid]
+ end
+end
diff --git a/db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb b/db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb
index 1586a7eb92f..a957f107405 100644
--- a/db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb
+++ b/db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb
@@ -48,7 +48,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati
attr_encrypted :token,
mode: :per_attribute_iv,
- key: Settings.attr_encrypted_db_key_base,
+ key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc'
end
diff --git a/db/schema.rb b/db/schema.rb
index 97247387bc7..0d6b44d1b92 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -451,10 +451,12 @@ ActiveRecord::Schema.define(version: 20180529093006) do
t.integer "config_source"
t.boolean "protected"
t.integer "failure_reason"
+ t.integer "iid"
end
add_index "ci_pipelines", ["auto_canceled_by_id"], name: "index_ci_pipelines_on_auto_canceled_by_id", using: :btree
add_index "ci_pipelines", ["pipeline_schedule_id"], name: "index_ci_pipelines_on_pipeline_schedule_id", using: :btree
+ add_index "ci_pipelines", ["project_id", "iid"], name: "index_ci_pipelines_on_project_id_and_iid", unique: true, where: "(iid IS NOT NULL)", using: :btree
add_index "ci_pipelines", ["project_id", "ref", "status", "id"], name: "index_ci_pipelines_on_project_id_and_ref_and_status_and_id", using: :btree
add_index "ci_pipelines", ["project_id", "sha"], name: "index_ci_pipelines_on_project_id_and_sha", using: :btree
add_index "ci_pipelines", ["project_id"], name: "index_ci_pipelines_on_project_id", using: :btree
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index c0221533f13..9b1297ca4ba 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -83,12 +83,12 @@ you need to add a [wildcard DNS A record][wiki-wildcard-dns] pointing to the
host that GitLab runs. For example, an entry would look like this:
```
-*.example.io. 1800 IN A 1.1.1.1
+*.example.io. 1800 IN A 192.0.2.1
*.example.io. 1800 IN AAAA 2001::1
```
where `example.io` is the domain under which GitLab Pages will be served
-and `1.1.1.1` is the IPv4 address of your GitLab instance and `2001::1` is the
+and `192.0.2.1` is the IPv4 address of your GitLab instance and `2001::1` is the
IPv6 address. If you don't have IPv6, you can omit the AAAA record.
> **Note:**
@@ -193,13 +193,13 @@ world. Custom domains are supported, but no TLS.
```shell
pages_external_url "http://example.io"
- nginx['listen_addresses'] = ['1.1.1.1']
+ nginx['listen_addresses'] = ['192.0.2.1']
pages_nginx['enable'] = false
- gitlab_pages['external_http'] = ['1.1.1.2:80', '[2001::2]:80']
+ gitlab_pages['external_http'] = ['192.0.2.2:80', '[2001::2]:80']
```
- where `1.1.1.1` is the primary IP address that GitLab is listening to and
- `1.1.1.2` and `2001::2` are the secondary IPs the GitLab Pages daemon
+ where `192.0.2.1` is the primary IP address that GitLab is listening to and
+ `192.0.2.2` and `2001::2` are the secondary IPs the GitLab Pages daemon
listens on. If you don't have IPv6, you can omit the IPv6 address.
1. [Reconfigure GitLab][reconfigure]
@@ -228,16 +228,16 @@ world. Custom domains and TLS are supported.
```shell
pages_external_url "https://example.io"
- nginx['listen_addresses'] = ['1.1.1.1']
+ nginx['listen_addresses'] = ['192.0.2.1']
pages_nginx['enable'] = false
gitlab_pages['cert'] = "/etc/gitlab/ssl/example.io.crt"
gitlab_pages['cert_key'] = "/etc/gitlab/ssl/example.io.key"
- gitlab_pages['external_http'] = ['1.1.1.2:80', '[2001::2]:80']
- gitlab_pages['external_https'] = ['1.1.1.2:443', '[2001::2]:443']
+ gitlab_pages['external_http'] = ['192.0.2.2:80', '[2001::2]:80']
+ gitlab_pages['external_https'] = ['192.0.2.2:443', '[2001::2]:443']
```
- where `1.1.1.1` is the primary IP address that GitLab is listening to and
- `1.1.1.2` and `2001::2` are the secondary IPs where the GitLab Pages daemon
+ where `192.0.2.1` is the primary IP address that GitLab is listening to and
+ `192.0.2.2` and `2001::2` are the secondary IPs where the GitLab Pages daemon
listens on. If you don't have IPv6, you can omit the IPv6 address.
1. [Reconfigure GitLab][reconfigure]
diff --git a/doc/administration/pages/source.md b/doc/administration/pages/source.md
index a45c3306457..4e40a7cb18d 100644
--- a/doc/administration/pages/source.md
+++ b/doc/administration/pages/source.md
@@ -67,11 +67,11 @@ you need to add a [wildcard DNS A record][wiki-wildcard-dns] pointing to the
host that GitLab runs. For example, an entry would look like this:
```
-*.example.io. 1800 IN A 1.1.1.1
+*.example.io. 1800 IN A 192.0.2.1
```
where `example.io` is the domain under which GitLab Pages will be served
-and `1.1.1.1` is the IP address of your GitLab instance.
+and `192.0.2.1` is the IP address of your GitLab instance.
> **Note:**
You should not use the GitLab domain to serve user pages. For more information
@@ -253,7 +253,7 @@ world. Custom domains are supported, but no TLS.
port: 80
https: false
- external_http: 1.1.1.2:80
+ external_http: 192.0.2.2:80
```
1. Edit `/etc/default/gitlab` and set `gitlab_pages_enabled` to `true` in
@@ -263,7 +263,7 @@ world. Custom domains are supported, but no TLS.
```
gitlab_pages_enabled=true
- gitlab_pages_options="-pages-domain example.io -pages-root $app_root/shared/pages -listen-proxy 127.0.0.1:8090 -listen-http 1.1.1.2:80"
+ gitlab_pages_options="-pages-domain example.io -pages-root $app_root/shared/pages -listen-proxy 127.0.0.1:8090 -listen-http 192.0.2.2:80"
```
1. Copy the `gitlab-pages-ssl` Nginx configuration file:
@@ -274,7 +274,7 @@ world. Custom domains are supported, but no TLS.
```
1. Edit all GitLab related configs in `/etc/nginx/site-available/` and replace
- `0.0.0.0` with `1.1.1.1`, where `1.1.1.1` the primary IP where GitLab
+ `0.0.0.0` with `192.0.2.1`, where `192.0.2.1` the primary IP where GitLab
listens to.
1. Restart NGINX
1. [Restart GitLab][restart]
@@ -320,8 +320,8 @@ world. Custom domains and TLS are supported.
port: 443
https: true
- external_http: 1.1.1.2:80
- external_https: 1.1.1.2:443
+ external_http: 192.0.2.2:80
+ external_https: 192.0.2.2:443
```
1. Edit `/etc/default/gitlab` and set `gitlab_pages_enabled` to `true` in
@@ -333,7 +333,7 @@ world. Custom domains and TLS are supported.
```
gitlab_pages_enabled=true
- gitlab_pages_options="-pages-domain example.io -pages-root $app_root/shared/pages -listen-proxy 127.0.0.1:8090 -listen-http 1.1.1.2:80 -listen-https 1.1.1.2:443 -root-cert /path/to/example.io.crt -root-key /path/to/example.io.key
+ gitlab_pages_options="-pages-domain example.io -pages-root $app_root/shared/pages -listen-proxy 127.0.0.1:8090 -listen-http 192.0.2.2:80 -listen-https 192.0.2.2:443 -root-cert /path/to/example.io.crt -root-key /path/to/example.io.key
```
1. Copy the `gitlab-pages-ssl` Nginx configuration file:
@@ -344,7 +344,7 @@ world. Custom domains and TLS are supported.
```
1. Edit all GitLab related configs in `/etc/nginx/site-available/` and replace
- `0.0.0.0` with `1.1.1.1`, where `1.1.1.1` the primary IP where GitLab
+ `0.0.0.0` with `192.0.2.1`, where `192.0.2.1` the primary IP where GitLab
listens to.
1. Restart NGINX
1. [Restart GitLab][restart]
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 051d2a10bc6..62f9884e264 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -582,6 +582,7 @@ Parameters:
"changes_count": "1",
"should_remove_source_branch": true,
"force_remove_source_branch": false,
+ "squash": false,
"web_url": "http://example.com/example/example/merge_requests/1",
"discussion_locked": false,
"time_stats": {
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index f10423b92cf..aa4395b01a9 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -72,6 +72,7 @@ future GitLab releases.**
| **CI_RUNNER_REVISION** | all | 10.6 | GitLab Runner revision that is executing the current job |
| **CI_RUNNER_EXECUTABLE_ARCH** | all | 10.6 | The OS/architecture of the GitLab Runner executable (note that this is not necessarily the same as the environment of the executor) |
| **CI_PIPELINE_ID** | 8.10 | 0.5 | The unique id of the current pipeline that GitLab CI uses internally |
+| **CI_PIPELINE_IID** | 11.0 | all | The unique id of the current pipeline scoped to project |
| **CI_PIPELINE_TRIGGERED** | all | all | The flag to indicate that job was [triggered] |
| **CI_PIPELINE_SOURCE** | 10.0 | all | Indicates how the pipeline was triggered. Possible options are: `push`, `web`, `trigger`, `schedule`, `api`, and `pipeline`. For pipelines created before GitLab 9.5, this will show as `unknown` |
| **CI_PROJECT_DIR** | all | all | The full path where the repository is cloned and where the job is run |
@@ -352,6 +353,8 @@ Running on runner-8a2f473d-project-1796893-concurrent-0 via runner-8a2f473d-mach
++ CI_PROJECT_URL=https://example.com/gitlab-examples/ci-debug-trace
++ export CI_PIPELINE_ID=52666
++ CI_PIPELINE_ID=52666
+++ export CI_PIPELINE_IID=123
+++ CI_PIPELINE_IID=123
++ export CI_RUNNER_ID=1337
++ CI_RUNNER_ID=1337
++ export CI_RUNNER_DESCRIPTION=shared-runners-manager-1.example.com
@@ -439,6 +442,7 @@ export CI_JOB_MANUAL="true"
export CI_JOB_TRIGGERED="true"
export CI_JOB_TOKEN="abcde-1234ABCD5678ef"
export CI_PIPELINE_ID="1000"
+export CI_PIPELINE_IID="10"
export CI_PROJECT_ID="34"
export CI_PROJECT_DIR="/builds/gitlab-org/gitlab-ce"
export CI_PROJECT_NAME="gitlab-ce"
diff --git a/doc/install/kubernetes/gitlab_omnibus.md b/doc/install/kubernetes/gitlab_omnibus.md
index 98af87455ec..e1d1969651e 100644
--- a/doc/install/kubernetes/gitlab_omnibus.md
+++ b/doc/install/kubernetes/gitlab_omnibus.md
@@ -144,7 +144,7 @@ helm install --name gitlab -f values.yaml gitlab/gitlab-omnibus
or passing them on the command line:
```bash
-helm install --name gitlab --set baseDomain=gitlab.io,baseIP=1.1.1.1,gitlab=ee,gitlabEELicense=$LICENSE,legoEmail=email@gitlab.com gitlab/gitlab-omnibus
+helm install --name gitlab --set baseDomain=gitlab.io,baseIP=192.0.2.1,gitlab=ee,gitlabEELicense=$LICENSE,legoEmail=email@gitlab.com gitlab/gitlab-omnibus
```
## Updating GitLab using the Helm Chart
diff --git a/lib/gitlab/ci/pipeline/chain/populate.rb b/lib/gitlab/ci/pipeline/chain/populate.rb
index 69b8a8fc68f..f34c11ca3c2 100644
--- a/lib/gitlab/ci/pipeline/chain/populate.rb
+++ b/lib/gitlab/ci/pipeline/chain/populate.rb
@@ -8,6 +8,9 @@ module Gitlab
PopulateError = Class.new(StandardError)
def perform!
+ # Allocate next IID. This operation must be outside of transactions of pipeline creations.
+ pipeline.ensure_project_iid!
+
##
# Populate pipeline with block argument of CreatePipelineService#execute.
#
diff --git a/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
index 4d7d6951a51..c5a4d9b4778 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
@@ -42,6 +42,10 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do
it 'correctly assigns user' do
expect(pipeline.builds).to all(have_attributes(user: user))
end
+
+ it 'has pipeline iid' do
+ expect(pipeline.iid).to be > 0
+ end
end
context 'when pipeline is empty' do
@@ -68,6 +72,10 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do
expect(pipeline.errors.to_a)
.to include 'No stages / jobs for this pipeline.'
end
+
+ it 'wastes pipeline iid' do
+ expect(InternalId.ci_pipelines.where(project_id: project.id).last.last_value).to be > 0
+ end
end
context 'when pipeline has validation errors' do
@@ -87,6 +95,10 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do
expect(pipeline.errors.to_a)
.to include 'Failed to build the pipeline!'
end
+
+ it 'wastes pipeline iid' do
+ expect(InternalId.ci_pipelines.where(project_id: project.id).last.last_value).to be > 0
+ end
end
context 'when there is a seed blocks present' do
@@ -111,6 +123,12 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do
expect(pipeline.variables.first.key).to eq 'VAR'
expect(pipeline.variables.first.value).to eq '123'
end
+
+ it 'has pipeline iid' do
+ step.perform!
+
+ expect(pipeline.iid).to be > 0
+ end
end
context 'when seeds block tries to persist some resources' do
@@ -121,6 +139,12 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do
it 'raises exception' do
expect { step.perform! }.to raise_error(ActiveRecord::RecordNotSaved)
end
+
+ it 'wastes pipeline iid' do
+ expect { step.perform! }.to raise_error
+
+ expect(InternalId.ci_pipelines.where(project_id: project.id).last.last_value).to be > 0
+ end
end
end
@@ -132,22 +156,39 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do
end
end
- context 'when using only/except build policies' do
- let(:config) do
- { rspec: { script: 'rspec', stage: 'test', only: ['master'] },
- prod: { script: 'cap prod', stage: 'deploy', only: ['tags'] } }
- end
+ context 'when variables policy is specified' do
+ shared_examples_for 'a correct pipeline' do
+ it 'populates pipeline according to used policies' do
+ step.perform!
- let(:pipeline) do
- build(:ci_pipeline, ref: 'master', config: config)
+ expect(pipeline.stages.size).to eq 1
+ expect(pipeline.stages.first.builds.size).to eq 1
+ expect(pipeline.stages.first.builds.first.name).to eq 'rspec'
+ end
end
- it 'populates pipeline according to used policies' do
- step.perform!
+ context 'when using only/except build policies' do
+ let(:config) do
+ { rspec: { script: 'rspec', stage: 'test', only: ['master'] },
+ prod: { script: 'cap prod', stage: 'deploy', only: ['tags'] } }
+ end
+
+ let(:pipeline) do
+ build(:ci_pipeline, ref: 'master', config: config)
+ end
- expect(pipeline.stages.size).to eq 1
- expect(pipeline.stages.first.builds.size).to eq 1
- expect(pipeline.stages.first.builds.first.name).to eq 'rspec'
+ it_behaves_like 'a correct pipeline'
+
+ context 'when variables expression is specified' do
+ context 'when pipeline iid is the subject' do
+ let(:config) do
+ { rspec: { script: 'rspec', only: { variables: ["$CI_PIPELINE_IID == '1'"] } },
+ prod: { script: 'cap prod', only: { variables: ["$CI_PIPELINE_IID == '1000'"] } } }
+ end
+
+ it_behaves_like 'a correct pipeline'
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 74e7a45fd6c..2aebdc57f7c 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -242,6 +242,7 @@ Ci::Pipeline:
- config_source
- failure_reason
- protected
+- iid
Ci::Stage:
- id
- name
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index b5eac913639..66c9708b4cf 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -1559,6 +1559,7 @@ describe Ci::Build do
{ key: 'CI_PROJECT_NAMESPACE', value: project.namespace.full_path, public: true },
{ key: 'CI_PROJECT_URL', value: project.web_url, public: true },
{ key: 'CI_PROJECT_VISIBILITY', value: 'private', public: true },
+ { key: 'CI_PIPELINE_IID', value: pipeline.iid.to_s, public: true },
{ key: 'CI_CONFIG_PATH', value: pipeline.ci_yaml_file_path, public: true },
{ key: 'CI_PIPELINE_SOURCE', value: pipeline.source, public: true },
{ key: 'CI_COMMIT_MESSAGE', value: pipeline.git_commit_message, public: true },
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index f5295bec65b..24692ebb9a3 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -35,6 +35,16 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe 'modules' do
+ it_behaves_like 'AtomicInternalId', validate_presence: false do
+ let(:internal_id_attribute) { :iid }
+ let(:instance) { build(:ci_pipeline) }
+ let(:scope) { :project }
+ let(:scope_attrs) { { project: instance.project } }
+ let(:usage) { :ci_pipelines }
+ end
+ end
+
describe '#source' do
context 'when creating new pipeline' do
let(:pipeline) do
@@ -195,7 +205,8 @@ describe Ci::Pipeline, :mailer do
it 'includes all predefined variables in a valid order' do
keys = subject.map { |variable| variable[:key] }
- expect(keys).to eq %w[CI_CONFIG_PATH
+ expect(keys).to eq %w[CI_PIPELINE_IID
+ CI_CONFIG_PATH
CI_PIPELINE_SOURCE
CI_COMMIT_MESSAGE
CI_COMMIT_TITLE
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index aee70bcfb29..e01906f4b6c 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -20,6 +20,7 @@ describe Deployment do
it_behaves_like 'AtomicInternalId' do
let(:internal_id_attribute) { :iid }
let(:instance) { build(:deployment) }
+ let(:scope) { :project }
let(:scope_attrs) { { project: instance.project } }
let(:usage) { :deployments }
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 128acf83686..e818fbeb9cf 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -17,6 +17,7 @@ describe Issue do
it_behaves_like 'AtomicInternalId' do
let(:internal_id_attribute) { :iid }
let(:instance) { build(:issue) }
+ let(:scope) { :project }
let(:scope_attrs) { { project: instance.project } }
let(:usage) { :issues }
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 9ffa91fc265..65cc9372cbe 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -84,6 +84,7 @@ describe MergeRequest do
it_behaves_like 'AtomicInternalId' do
let(:internal_id_attribute) { :iid }
let(:instance) { build(:merge_request) }
+ let(:scope) { :target_project }
let(:scope_attrs) { { project: instance.target_project } }
let(:usage) { :merge_requests }
end
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 4bb9717d33e..204d6b47832 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -6,6 +6,7 @@ describe Milestone do
it_behaves_like 'AtomicInternalId' do
let(:internal_id_attribute) { :iid }
let(:instance) { build(:milestone, project: build(:project), group: nil) }
+ let(:scope) { :project }
let(:scope_attrs) { { project: instance.project } }
let(:usage) { :milestones }
end
@@ -15,6 +16,7 @@ describe Milestone do
it_behaves_like 'AtomicInternalId' do
let(:internal_id_attribute) { :iid }
let(:instance) { build(:milestone, project: nil, group: build(:group)) }
+ let(:scope) { :group }
let(:scope_attrs) { { namespace: instance.group } }
let(:usage) { :milestones }
end
diff --git a/spec/support/shared_examples/models/atomic_internal_id_spec.rb b/spec/support/shared_examples/models/atomic_internal_id_spec.rb
index 6a6e13418a9..7ab1041d17c 100644
--- a/spec/support/shared_examples/models/atomic_internal_id_spec.rb
+++ b/spec/support/shared_examples/models/atomic_internal_id_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-shared_examples_for 'AtomicInternalId' do
+shared_examples_for 'AtomicInternalId' do |validate_presence: true|
describe '.has_internal_id' do
describe 'Module inclusion' do
subject { described_class }
@@ -9,14 +9,31 @@ shared_examples_for 'AtomicInternalId' do
end
describe 'Validation' do
- subject { instance }
-
before do
- allow(InternalId).to receive(:generate_next).and_return(nil)
+ allow_any_instance_of(described_class).to receive(:"ensure_#{scope}_#{internal_id_attribute}!")
+
+ instance.valid?
end
- it { is_expected.to validate_presence_of(internal_id_attribute) }
- it { is_expected.to validate_numericality_of(internal_id_attribute) }
+ context 'when presence validation is required' do
+ before do
+ skip unless validate_presence
+ end
+
+ it 'validates presence' do
+ expect(instance.errors[internal_id_attribute]).to include("can't be blank")
+ end
+ end
+
+ context 'when presence validation is not required' do
+ before do
+ skip if validate_presence
+ end
+
+ it 'does not validate presence' do
+ expect(instance.errors[internal_id_attribute]).to be_empty
+ end
+ end
end
describe 'Creating an instance' do