Commit b570d73e authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 34b3567c
......@@ -188,6 +188,7 @@ module ProjectsHelper
"cross-project:#{can?(current_user, :read_cross_project)}",
max_project_member_access_cache_key(project),
pipeline_status,
Gitlab::I18n.locale,
'v2.6'
]
......
......@@ -599,12 +599,6 @@ module Ci
project.notes.for_commit_id(sha)
end
# rubocop: disable CodeReuse/ServiceClass
def process!(trigger_build_ids = nil)
Ci::ProcessPipelineService.new(project, user).execute(self, trigger_build_ids)
end
# rubocop: enable CodeReuse/ServiceClass
def update_status
retry_optimistic_lock(self) do
new_status = latest_builds_status.to_s
......
......@@ -23,7 +23,6 @@ module Issuable
include Sortable
include CreatedAtFilterable
include UpdatedAtFilterable
include IssuableStates
include ClosedAtFilterable
include VersionedDescription
......
# frozen_string_literal: true
module IssuableStates
extend ActiveSupport::Concern
# The state:string column is being migrated to state_id:integer column
# This is a temporary hook to keep state column in sync until it is removed.
# Check https: https://gitlab.com/gitlab-org/gitlab/issues/33814 for more information
# The state column can be safely removed after 2019-10-27
included do
before_save :sync_issuable_deprecated_state
end
def sync_issuable_deprecated_state
return if self.is_a?(Epic)
return unless respond_to?(:state)
return if state_id.nil?
deprecated_state = self.class.available_states.key(state_id)
self.write_attribute(:state, deprecated_state)
end
end
......@@ -66,7 +66,10 @@ class Issue < ApplicationRecord
scope :public_only, -> { where(confidential: false) }
scope :confidential_only, -> { where(confidential: true) }
scope :counts_by_state, -> { reorder(nil).group(:state).count }
scope :counts_by_state, -> { reorder(nil).group(:state_id).count }
# Only remove after 2019-12-22 and with %12.7
self.ignored_columns += %i[state]
after_commit :expire_etag_cache
after_save :ensure_metrics, unless: :imported?
......
......@@ -228,6 +228,9 @@ class MergeRequest < ApplicationRecord
with_state(:opened).where(auto_merge_enabled: true)
end
# Only remove after 2019-12-22 and with %12.7
self.ignored_columns += %i[state]
after_save :keep_around_commit
alias_attribute :project, :target_project
......
......@@ -58,6 +58,7 @@ class ReleasePresenter < Gitlab::View::Presenter::Delegated
end
def release_edit_page_available?
::Feature.enabled?(:release_edit_page, project, default_enabled: true)
::Feature.enabled?(:release_edit_page, project, default_enabled: true) &&
can?(current_user, :update_release, release)
end
end
# frozen_string_literal: true
class AnalyticsMergeRequestEntity < AnalyticsIssueEntity
expose :state
expose :state do |object|
MergeRequest.available_states.key(object[:state_id])
end
expose :url do |object|
url_to(:namespace_project_merge_request, object)
......
......@@ -57,7 +57,9 @@ module Ci
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
pipeline.process!
Ci::ProcessPipelineService
.new(pipeline)
.execute
end
end
......
# frozen_string_literal: true
module Ci
class ProcessPipelineService < BaseService
class ProcessPipelineService
include Gitlab::Utils::StrongMemoize
attr_reader :pipeline
def execute(pipeline, trigger_build_ids = nil)
def initialize(pipeline)
@pipeline = pipeline
end
def execute(trigger_build_ids = nil)
update_retried
success = process_stages_without_needs
......@@ -72,7 +74,7 @@ module Ci
def process_build(build, current_status)
Gitlab::OptimisticLocking.retry_lock(build) do |subject|
Ci::ProcessBuildService.new(project, @user)
Ci::ProcessBuildService.new(project, build.user)
.execute(subject, current_status)
end
end
......@@ -129,5 +131,9 @@ module Ci
.update_all(retried: true) if latest_statuses.any?
end
# rubocop: enable CodeReuse/ActiveRecord
def project
pipeline.project
end
end
end
......@@ -24,7 +24,9 @@ module Ci
.new(project, current_user)
.close_all(pipeline)
pipeline.process!
Ci::ProcessPipelineService
.new(pipeline)
.execute
end
end
end
......@@ -397,7 +397,7 @@ class IssuableBaseService < BaseService
end
def update_project_counter_caches?(issuable)
issuable.state_changed?
issuable.state_id_changed?
end
def parent
......
......@@ -11,7 +11,9 @@ class PipelineProcessWorker
# rubocop: disable CodeReuse/ActiveRecord
def perform(pipeline_id, build_ids = nil)
Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline|
pipeline.process!(build_ids)
Ci::ProcessPipelineService
.new(pipeline)
.execute(build_ids)
end
end
# rubocop: enable CodeReuse/ActiveRecord
......
---
title: Creates DB tables for storing mentioned users, groups, projects referenced
in a note or issuable description
merge_request: 18316
author:
type: added
---
title: Add link color to design comments
merge_request: 20302
author:
type: fixed
---
title: Remove Release edit url for users not allowed to update a release
merge_request: 20136
author:
type: fixed
---
title: Fix projects list to show info in user's locale
merge_request: 20015
author: Arun Kumar Mohan
type: fixed
......@@ -93,7 +93,7 @@ tables:
- updated_at
- description
- milestone_id
- state
- state_id
- updated_by_id
- weight
- due_date
......@@ -174,7 +174,7 @@ tables:
- created_at
- updated_at
- milestone_id
- state
- state_id
- merge_status
- target_project_id
- updated_by_id
......
# frozen_string_literal: true
class CreateIssueUserMentions < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :issue_user_mentions do |t|
t.references :issue, type: :integer, index: false, null: false, foreign_key: { on_delete: :cascade }
t.references :note, type: :integer,
index: { where: 'note_id IS NOT NULL', unique: true }, null: true, foreign_key: { on_delete: :cascade }
t.integer :mentioned_users_ids, array: true
t.integer :mentioned_projects_ids, array: true
t.integer :mentioned_groups_ids, array: true
end
add_index :issue_user_mentions, [:issue_id], where: 'note_id is null', unique: true, name: 'issue_user_mentions_on_issue_id_index'
add_index :issue_user_mentions, [:issue_id, :note_id], unique: true, name: 'issue_user_mentions_on_issue_id_and_note_id_index'
end
end
# frozen_string_literal: true
class CreateMergeRequestUserMentions < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :merge_request_user_mentions do |t|
t.references :merge_request, type: :integer, index: false, null: false, foreign_key: { on_delete: :cascade }
t.references :note, type: :integer,
index: { where: 'note_id IS NOT NULL', unique: true }, null: true, foreign_key: { on_delete: :cascade }
t.integer :mentioned_users_ids, array: true
t.integer :mentioned_projects_ids, array: true
t.integer :mentioned_groups_ids, array: true
end
add_index :merge_request_user_mentions, [:merge_request_id], where: 'note_id is null', unique: true, name: 'merge_request_user_mentions_on_mr_id_index'
add_index :merge_request_user_mentions, [:merge_request_id, :note_id], unique: true, name: 'merge_request_user_mentions_on_mr_id_and_note_id_index'
end
end
# frozen_string_literal: true
class CreateEpicUserMentions < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :epic_user_mentions do |t|
t.references :epic, type: :integer, index: false, null: false, foreign_key: { on_delete: :cascade }
t.references :note, type: :integer,
index: { where: 'note_id IS NOT NULL', unique: true }, null: true, foreign_key: { on_delete: :cascade }
t.integer :mentioned_users_ids, array: true
t.integer :mentioned_projects_ids, array: true
t.integer :mentioned_groups_ids, array: true
end
add_index :epic_user_mentions, [:epic_id], where: 'note_id is null', unique: true, name: 'epic_user_mentions_on_epic_id_index'
add_index :epic_user_mentions, [:epic_id, :note_id], unique: true, name: 'epic_user_mentions_on_epic_id_and_note_id_index'
end
end
# frozen_string_literal: true
class CreateCommitUserMentions < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :commit_user_mentions do |t|
t.references :note, type: :integer,
index: { unique: true }, null: false, foreign_key: { on_delete: :cascade }
t.binary :commit_id, null: false
t.integer :mentioned_users_ids, array: true
t.integer :mentioned_projects_ids, array: true
t.integer :mentioned_groups_ids, array: true
end
add_index :commit_user_mentions, [:commit_id, :note_id], name: 'commit_user_mentions_on_commit_id_and_note_id_index'
end
end
# frozen_string_literal: true
class CreateSnippetUserMentions < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :snippet_user_mentions do |t|
t.references :snippet, type: :integer, index: false, null: false, foreign_key: { on_delete: :cascade }
t.references :note, type: :integer,
index: { where: 'note_id IS NOT NULL', unique: true }, null: true, foreign_key: { on_delete: :cascade }
t.integer :mentioned_users_ids, array: true
t.integer :mentioned_projects_ids, array: true
t.integer :mentioned_groups_ids, array: true
end
add_index :snippet_user_mentions, [:snippet_id], where: 'note_id is null', unique: true, name: 'snippet_user_mentions_on_snippet_id_index'
add_index :snippet_user_mentions, [:snippet_id, :note_id], unique: true, name: 'snippet_user_mentions_on_snippet_id_and_note_id_index'
end
end
# frozen_string_literal: true
class CreateDesignUserMentions < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :design_user_mentions do |t|
t.references :design, type: :integer, index: false, null: false,
foreign_key: { to_table: :design_management_designs, column: :design_id, on_delete: :cascade }
t.references :note, type: :integer,
index: { unique: true }, null: false, foreign_key: { on_delete: :cascade }
t.integer :mentioned_users_ids, array: true
t.integer :mentioned_projects_ids, array: true
t.integer :mentioned_groups_ids, array: true
end
add_index :design_user_mentions, [:design_id, :note_id], name: 'design_user_mentions_on_design_id_and_note_id_index'
end
end
# frozen_string_literal: true
class CreateServiceDeskSettings < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :service_desk_settings, id: false do |t|
t.references :project,
primary_key: true,
default: nil,
null: false,
index: false,
foreign_key: { on_delete: :cascade }
t.string :issue_template_key, limit: 255
end
end
end
# frozen_string_literal: true
class NullifyUsersRole < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
INDEX_NAME = 'partial_index_users_updated_at_for_cleaning_mistaken_values'.freeze
DOWNTIME = false
def up
# expected updated users count is around 10K
# rubocop: disable Migration/UpdateLargeTable
add_concurrent_index(:users, :updated_at, where: 'role = 0', name: INDEX_NAME)
update_column_in_batches(:users, :role, nil) do |table, query|
query.where(table[:updated_at].lt('2019-11-05 12:08:00')).where(table[:role].eq(0))
end
remove_concurrent_index_by_name(:users, INDEX_NAME)
end
def down
# noop
end
end
This diff is collapsed.
......@@ -49,6 +49,22 @@ purposes.
In this setup guide we will start by configuring Praefect, then its child
Gitaly nodes, and lastly the GitLab server configuration.
#### Secrets
We need to manage the following secrets and make them match across hosts:
1. `GITLAB_SHELL_SECRET_TOKEN`: this is used by Git hooks to make
callback HTTP API requests to GitLab when accepting a Git push. This
secret is shared with GitLab Shell for legacy reasons.
1. `PRAEFECT_EXTERNAL_TOKEN`: repositories hosted on your Praefect
cluster can only be accessed by Gitaly clients that carry this
token.
1. `PRAEFECT_INTERNAL_TOKEN`: this token is used for replication
traffic inside your Praefect cluster. This is distinct from
`PRAEFECT_EXTERNAL_TOKEN` because Gitaly clients must not be able to
access internal nodes of the Praefect cluster directly; that could
lead to data loss.
#### Praefect
On the Praefect node we disable all other services, including Gitaly. We list each
......@@ -57,14 +73,8 @@ Gitaly node that will be connected to Praefect under `praefect['storage_nodes']`
In the example below, the Gitaly nodes are named `praefect-gitaly-N`. Note that one
node is designated as primary by setting the primary to `true`.
`praefect['auth_token']` is the token used to authenticate with the GitLab server,
just like `gitaly['auth_token']` is used for a standard Gitaly server.
The `token` field under each storage listed in `praefect['storage_nodes']` is used
to authenticate each child Gitaly node with Praefect.
```ruby
# /etc/gitlab/gitlab.rb
# /etc/gitlab/gitlab.rb on praefect server
# Avoid running unnecessary services on the Gitaly server
postgresql['enable'] = false
......@@ -83,7 +93,7 @@ In the example below, the Gitaly nodes are named `praefect-git-X`. Note that one
primary, by setting the primary to `true`:
```ruby
# /etc/gitlab/gitlab.rb
# /etc/gitlab/gitlab.rb on praefect server
# Prevent database connections during 'gitlab-ctl reconfigure'
gitlab_rails['rake_cache_clear'] = false
......@@ -98,22 +108,24 @@ praefect['listen_addr'] = '0.0.0.0:2305'
# virtual_storage_name must match the same storage name given to praefect in git_data_dirs
praefect['virtual_storage_name'] = 'praefect'
# Authentication token to ensure only authorized servers can communicate with
# Praefect server
praefect['auth_token'] = 'praefect-token'
# Replace PRAEFECT_EXTERNAL_TOKEN with a real secret
praefect['auth_token'] = 'PRAEFECT_EXTERNAL_TOKEN'
# Replace each instance of PRAEFECT_INTERNAL_TOKEN below with a real
# secret, distinct from PRAEFECT_EXTERNAL_TOKEN.
praefect['storage_nodes'] = {
'praefect-gitaly-1' => {
'address' => 'tcp://praefect-git-1.internal:8075',
'token' => 'praefect-gitaly-token',
'token' => 'PRAEFECT_INTERNAL_TOKEN',
'primary' => true
},
'praefect-gitaly-2' => {
'address' => 'tcp://praefect-git-2.internal:8075',
'token' => 'praefect-gitaly-token'
'token' => 'PRAEFECT_INTERNAL_TOKEN'
},
'praefect-gitaly-3' => {
'address' => 'tcp://praefect-git-3.internal:8075',
'token' => 'praefect-gitaly-token'
'token' => 'PRAEFECT_INTERNAL_TOKEN'
}
}
```
......@@ -133,7 +145,7 @@ Note that `gitaly['auth_token']` matches the `token` value listed under `praefec
on the Praefect node.
```ruby
# /etc/gitlab/gitlab.rb
# /etc/gitlab/gitlab.rb on gitaly node inside praefect cluster
# Avoid running unnecessary services on the Gitaly server
postgresql['enable'] = false
......@@ -148,15 +160,16 @@ gitlab_workhorse['enable'] = false
gitlab_rails['rake_cache_clear'] = false
gitlab_rails['auto_migrate'] = false
# Replace GITLAB_SHELL_SECRET_TOKEN below with real secret
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
# Configure the gitlab-shell API callback URL. Without this, `git push` will
# fail. This can be your 'front door' GitLab URL or an internal load
# balancer.
# Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from web server to Gitaly server.
gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
# Authentication token to ensure only authorized servers can communicate with
# Gitaly server
gitaly['auth_token'] = 'praefect-gitaly-token'
# Replace PRAEFECT_INTERNAL_TOKEN below with a real secret.
gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN'
# Make Gitaly accept connections on all network interfaces. You must use
# firewalls to restrict access to this address/port.
......@@ -170,9 +183,6 @@ git_data_dirs({
})
```
Note that just as with a standard Gitaly server, `/etc/gitlab/gitlab-secrets.json` must
be copied from the GitLab server to the Gitaly node for authentication purposes.
For more information on Gitaly server configuration, see our [gitaly documentation](index.md#3-gitaly-server-configuration).
#### GitLab
......@@ -182,24 +192,26 @@ is done through setting the `git_data_dirs`. Assuming the default storage
is present, there should be two storages available to GitLab:
```ruby
# /etc/gitlab/gitlab.rb on gitlab server
# Replace PRAEFECT_EXTERNAL_TOKEN below with real secret.
git_data_dirs({
"default" => {
"gitaly_address" => "tcp://gitaly.internal"
},
"praefect" => {
"gitaly_address" => "tcp://praefect.internal:2305"
"gitaly_address" => "tcp://praefect.internal:2305",
"gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
}
})
gitlab_rails['gitaly_token'] = 'praefect-token'
# Replace GITLAB_SHELL_SECRET_TOKEN below with real secret
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
```
Note that the storage name used is the same as the `praefect['virtual_storage_name']` set
on the Praefect node.
Also, the `gitlab_rails['gitaly_token']` matches the value of `praefect['auth_token']`
on Praefect.
Restart GitLab using `gitlab-ctl restart` on the GitLab node.
### Testing Praefect
......@@ -211,7 +223,3 @@ create a new project and check the "Initialize repository with a README" box.
If you receive a 503 error, check `/var/log/gitlab/gitlab-rails/production.log`.
A `GRPC::Unavailable (14:failed to connect to all addresses)` error indicates
that GitLab was unable to connect to Praefect.
If the project is created but the README is not, then ensure that the
`/etc/gitlab/gitlab-secrets.json` file from the GitLab server has been copied
to the Gitaly servers.
......@@ -15,7 +15,7 @@ SAST supports the following official analyzers:
- [`bandit`](https://gitlab.com/gitlab-org/security-products/analyzers/bandit) (Bandit)
- [`brakeman`](https://gitlab.com/gitlab-org/security-products/analyzers/brakeman) (Brakeman)
- [`eslint`](https://gitlab.com/gitlab-org/security-products/analyzers/eslint) (ESLint (JavaScript))
- [`eslint`](https://gitlab.com/gitlab-org/security-products/analyzers/eslint) (ESLint (JavaScript and React))
- [`flawfinder`](https://gitlab.com/gitlab-org/security-products/analyzers/flawfinder) (Flawfinder)
- [`gosec`](https://gitlab.com/gitlab-org/security-products/analyzers/gosec) (Gosec)
- [`nodejs-scan`](https://gitlab.com/gitlab-org/security-products/analyzers/nodejs-scan) (NodeJsScan)
......
......@@ -76,6 +76,7 @@ The following table shows which languages, package managers and frameworks are s
| Node.js | [NodeJsScan](https://github.com/ajinabraham/NodeJsScan) | 11.1 |
| PHP | [phpcs-security-audit](https://github.com/FloeDesignTechnologies/phpcs-security-audit) | 10.8 |
| Python ([pip](https://pip.pypa.io/en/stable/)) | [bandit](https://github.com/PyCQA/bandit) | 10.3 |
| React | [ESLint react plugin](https://github.com/yannickcr/eslint-plugin-react) | 12.5 |
| Ruby on Rails | [brakeman](https://brakemanscanner.org) | 10.3 |
| Scala ([Ant](https://ant.apache.org/), [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) and [SBT](https://www.scala-sbt.org/)) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 11.0 (SBT) & 11.9 (Ant, Gradle, Maven) |
| TypeScript | [TSLint config security](https://github.com/webschik/tslint-config-security/) | 11.9 |
......
# GitLab Conan Repository **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/8248) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.5.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/8248) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.6.
With the GitLab Conan Repository, every
project can have its own space to store Conan packages.
......
......@@ -21,7 +21,7 @@ module Gitlab
finder_class: MergeRequestsFinder,
serializer_class: AnalyticsMergeRequestSerializer,
includes_for_query: { target_project: [:namespace], author: [] },
columns_for_select: %I[title iid id created_at author_id state target_project_id]
columns_for_select: %I[title iid id created_at author_id state_id target_project_id]
}
}.freeze
......
......@@ -200,7 +200,6 @@ module Gitlab
target_project_id: project.id,
target_branch: Gitlab::Git.ref_name(pull_request.target_branch_name),
target_branch_sha: pull_request.target_branch_sha,
state: pull_request.state,
state_id: MergeRequest.available_states[pull_request.state],
author_id: author_id,
assignee_id: nil,
......
......@@ -10,7 +10,7 @@ module Gitlab
mr_table[:iid],
mr_table[:id],
mr_table[:created_at],
mr_table[:state],
mr_table[:state_id],
mr_table[:author_id]]
@order = mr_table[:created_at]
......
......@@ -10,7 +10,7 @@ module Gitlab
mr_table[:iid],
mr_table[:id],
mr_table[:created_at],
mr_table[:state],
mr_table[:state_id],
mr_table[:author_id]]
super(*args)
......
......@@ -52,7 +52,6 @@ module Gitlab
project_id: project.id,
description: description,
milestone_id: milestone_finder.id_for(issue),
state: issue.state,
state_id: ::Issue.available_states[issue.state],
created_at: issue.created_at,
updated_at: issue.updated_at
......
......@@ -54,7 +54,6 @@ module Gitlab
target_project_id: project.id,
source_branch: pull_request.formatted_source_branch,
target_branch: pull_request.target_branch,
state: pull_request.state,
state_id: ::MergeRequest.available_states[pull_request.state],
milestone_id: milestone_finder.id_for(pull_request),
author_id: author_id,
......
......@@ -23,7 +23,7 @@ module Gitlab
milestone_id
source_branch
source_project_id
state
state_id
target_branch
target_project_id
time_estimate
......@@ -53,7 +53,8 @@ module Gitlab
human_total_time_spent: merge_request.human_total_time_spent,
human_time_estimate: merge_request.human_time_estimate,
assignee_ids: merge_request.assignee_ids,
assignee_id: merge_request.assignee_ids.first # This key is deprecated
assignee_id: merge_request.assignee_ids.first, # This key is deprecated
state: merge_request.state # This key is deprecated
}
merge_request.attributes.with_indifferent_access.slice(*self.class.safe_hook_attributes)
......
......@@ -275,3 +275,4 @@ ee:
- :unprotect_access_levels
- protected_environments:
- :deploy_access_levels
- :service_desk_setting
......@@ -7348,6 +7348,9 @@ msgstr ""
msgid "FeatureFlags|Inactive flag for %{scope}"
msgstr ""
msgid "FeatureFlags|Include additional user IDs"
msgstr ""
msgid "FeatureFlags|Install a %{docs_link_anchored_start}compatible client library%{docs_link_anchored_end} and specify the API URL, application name, and instance ID during the configuration setup. %{docs_link_start}More Information%{docs_link_end}"
msgstr ""
......
......@@ -79,7 +79,8 @@ describe 'Database schema' do
vulnerability_identifiers: %w[external_id],
vulnerability_scanners: %w[external_id],
web_hooks: %w[service_id group_id],
suggestions: %w[commit_id]
suggestions: %w[commit_id],
commit_user_mentions: %w[commit_id]
}.with_indifferent_access.freeze
context 'for table' do
......
......@@ -38,7 +38,7 @@
"additionalProperties": false
},
"_links": {
"required": ["merge_requests_url", "issues_url", "edit_url"],
"required": ["merge_requests_url", "issues_url"],
"properties": {
"merge_requests_url": { "type": "string" },
"issues_url": { "type": "string" },
......
......@@ -26,11 +26,10 @@
"additionalProperties": false
},
"_links": {
"required": ["merge_requests_url", "issues_url", "edit_url"],
"required": ["merge_requests_url", "issues_url"],
"properties": {
"merge_requests_url": { "type": "string" },
"issues_url": { "type": "string" },
"edit_url": { "type": "string"}
"issues_url": { "type": "string" }
}
}
},
......
......@@ -157,6 +157,7 @@ describe ProjectsHelper do
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:can?).with(user, :read_cross_project) { true }
allow(user).to receive(:max_member_access_for_project).and_return(40)
allow(Gitlab::I18n).to receive(:locale).and_return('es')
end
it "includes the route" do
......@@ -203,6 +204,10 @@ describe ProjectsHelper do
expect(helper.project_list_cache_key(project)).to include("pipeline-status/#{project.commit.sha}-success")
end
it "includes the user locale" do
expect(helper.project_list_cache_key(project)).to include('es')
end
it "includes the user max member access" do
expect(helper.project_list_cache_key(project)).to include('access:40')
end
......
......@@ -99,7 +99,6 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach
project_id: project.id,
description: 'This is my issue',
milestone_id: milestone.id,
state: :opened,
state_id: 1,
created_at: created_at,
updated_at: updated_at
......@@ -129,7 +128,6 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach
project_id: project.id,
description: "*Created by: alice*\n\nThis is my issue",
milestone_id: milestone.id,
state: :opened,
state_id: 1,
created_at: created_at,
updated_at: updated_at
......
......@@ -94,7 +94,6 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
target_project_id: project.id,
source_branch: 'github/fork/alice/feature',
target_branch: 'master',
state: :merged,
state_id: 3,
milestone_id: milestone.id,
author_id: user.id,
......@@ -140,7 +139,6 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
target_project_id: project.id,
source_branch: 'github/fork/alice/feature',
target_branch: 'master',
state: :merged,
state_id: 3,
milestone_id: milestone.id,
author_id: project.creator_id,
......@@ -187,7 +185,6 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
target_project_id: project.id,
source_branch: 'master-42',
target_branch: 'master',
state: :merged,
state_id: 3,
milestone_id: milestone.id,
author_id: user.id,
......
......@@ -18,7 +18,7 @@ describe Gitlab::Import::MergeRequestHelpers, type: :helper do
target_project_id: project.id,
source_branch: 'master-42',
target_branch: 'master',
state: :merged,
state_id: 3,
author_id: user.id,
assignee_id: user.id
}
......
......@@ -432,6 +432,7 @@ project:
- downstream_projects
- upstream_project_subscriptions
- downstream_project_subscriptions
- service_desk_setting
award_emoji:
- awardable
- user
......
......@@ -762,3 +762,6 @@ ZoomMeeting:
- url
- created_at
- updated_at
ServiceDeskSetting:
- project_id
- issue_template_key
......@@ -73,11 +73,11 @@ describe Gitlab::MarkdownCache::ActiveRecord::Extension do
let(:thing) { klass.new(title: markdown, title_html: html, cached_markdown_version: cache_version) }
before do
thing.state = 'closed'
thing.state_id = 2
thing.save
end
it { expect(thing.state).to eq('closed') }
it { expect(thing.state_id).to eq(2) }
it { expect(thing.title).to eq(markdown) }
it { expect(thing.title_html).to eq(html) }
it { expect(thing.cached_markdown_version).to eq(cache_version) }
......
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20191104142124_nullify_users_role.rb')
describe NullifyUsersRole, :migration do
let(:users) { table(:users) }
before do
allow(Gitlab).to receive(:com?).and_return(true)
users.create!(role: 0, updated_at: '2019-11-04 12:08:00', projects_limit: 0, email: '1')
users.create!(role: 1, updated_at: '2019-11-04 12:08:00', projects_limit: 0, email: '2')
users.create!(role: 0, updated_at: '2019-11-06 12:08:00', projects_limit: 0, email: '3')
migrate!
end
it 'nullifies the role of the user with updated_at < 2019-11-05 12:08:00 and a role of 0' do
expect(users.where(role: nil).count).to eq(1)
expect(users.where(role: nil).first.email).to eq('1')
end
it 'leaves the user with role of 1' do
expect(users.where(role: 1).count).to eq(1)
expect(users.where(role: 1).first.email).to eq('2')
end
it 'leaves the user with updated_at > 2019-11-05 12:08:00' do
expect(users.where(role: 0).count).to eq(1)
expect(users.where(role: 0).first.email).to eq('3')
end
end
......@@ -1045,7 +1045,9 @@ describe Ci::Pipeline, :mailer do
stage_idx: 0,
status: 'success')
pipeline.process!
Ci::ProcessPipelineService
.new(pipeline)
.execute
end
it 'ignores the previous state' do
......
# frozen_string_literal: true
require 'spec_helper'
# This spec checks if state_id column of issues and merge requests
# are being synced on every save.
# It can be removed in the next release. Check https://gitlab.com/gitlab-org/gitlab-foss/issues/51789 for more information.
describe IssuableStates do
[Issue, MergeRequest].each do |klass|
it "syncs state_id column when #{klass.model_name.human} gets created" do
klass.available_states.each do |state, state_id|
issuable = build(klass.model_name.param_key, state: state.to_s)
issuable.save!
expect(issuable.state_id).to eq(state_id)
end
end
it "syncs state_id column when #{klass.model_name.human} gets updated" do
klass.available_states.each do |state, state_id|
issuable = create(klass.model_name.param_key, state: state.to_s)
issuable.update(state: state)
expect(issuable.state_id).to eq(state_id)
end
end
end
end
......@@ -97,5 +97,11 @@ describe ReleasePresenter do
it { is_expected.to be_nil }
end
context 'when a user is not allowed to update a release' do
let(:presenter) { described_class.new(release, current_user: guest) }
it { is_expected.to be_nil }
end
end
end
......@@ -845,7 +845,7 @@ describe Ci::ProcessPipelineService, '#execute' do
end
def process_pipeline
described_class.new(pipeline.project, user).execute(pipeline)
described_class.new(pipeline).execute
end
def all_builds
......
......@@ -223,7 +223,7 @@ describe Ci::RetryPipelineService, '#execute' do
end
it 'reprocesses the pipeline' do
expect(pipeline).to receive(:process!)
expect_any_instance_of(Ci::ProcessPipelineService).to receive(:execute)
service.execute(pipeline)
end
......
......@@ -8,7 +8,11 @@ def webmock_allowed_hosts
if ENV.key?('ELASTIC_URL')
hosts << URI.parse(ENV['ELASTIC_URL']).host
end
end.uniq
if Gitlab.config.webpack&.dev_server&.enabled
hosts << Gitlab.config.webpack.dev_server.host
end
end.compact.uniq
end
WebMock.disable_net_connect!(allow_localhost: true, allow: webmock_allowed_hosts)
......@@ -8,7 +8,7 @@ describe PipelineProcessWorker do
let(:pipeline) { create(:ci_pipeline) }
it 'processes pipeline' do
expect_any_instance_of(Ci::Pipeline).to receive(:process!)
expect_any_instance_of(Ci::ProcessPipelineService).to receive(:execute)
described_class.new.perform(pipeline.id)
end
......@@ -17,7 +17,7 @@ describe PipelineProcessWorker do
let(:build) { create(:ci_build, pipeline: pipeline, name: 'my-build') }
it 'processes pipeline with a list of builds' do
expect_any_instance_of(Ci::Pipeline).to receive(:process!)
expect_any_instance_of(Ci::ProcessPipelineService).to receive(:execute)
.with([build.id])
described_class.new.perform(pipeline.id, [build.id])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment