summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/concerns/has_status.rb2
-rw-r--r--changelogs/unreleased/fix-gb-exclude-manual-actions-from-cancelable-jobs.yml4
-rw-r--r--db/post_migrate/20170518200835_rename_users_with_renamed_namespace.rb50
-rw-r--r--db/post_migrate/20170518231126_fix_wrongly_renamed_routes.rb104
-rw-r--r--db/schema.rb2
-rw-r--r--doc/user/img/gitlab_snippet.pngbin0 -> 34355 bytes
-rw-r--r--doc/user/project/issues/img/create_new_merge_request.pngbin26285 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]doc/user/project/issues/img/issues_main_view.pngbin48671 -> 73751 bytes
-rw-r--r--doc/user/project/issues/img/issues_main_view_numbered.jpgbin0 -> 103249 bytes
-rwxr-xr-xdoc/user/project/issues/img/issues_main_view_numbered.pngbin73508 -> 0 bytes
-rw-r--r--doc/user/project/issues/index.md4
-rw-r--r--doc/user/project/issues/issues_functionalities.md32
-rw-r--r--doc/user/snippets.md10
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb38
-rw-r--r--spec/migrations/fix_wrongly_renamed_routes_spec.rb73
-rw-r--r--spec/migrations/rename_users_with_renamed_namespace_spec.rb22
-rw-r--r--spec/models/ci/pipeline_spec.rb10
17 files changed, 333 insertions, 18 deletions
diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb
index dff7b6e3523..3c9c6584e02 100644
--- a/app/models/concerns/has_status.rb
+++ b/app/models/concerns/has_status.rb
@@ -82,7 +82,7 @@ module HasStatus
scope :failed_or_canceled, -> { where(status: [:failed, :canceled]) }
scope :cancelable, -> do
- where(status: [:running, :pending, :created, :manual])
+ where(status: [:running, :pending, :created])
end
end
diff --git a/changelogs/unreleased/fix-gb-exclude-manual-actions-from-cancelable-jobs.yml b/changelogs/unreleased/fix-gb-exclude-manual-actions-from-cancelable-jobs.yml
new file mode 100644
index 00000000000..a16fc775b5e
--- /dev/null
+++ b/changelogs/unreleased/fix-gb-exclude-manual-actions-from-cancelable-jobs.yml
@@ -0,0 +1,4 @@
+---
+title: Exclude manual actions when checking if pipeline can be canceled
+merge_request: 11562
+author:
diff --git a/db/post_migrate/20170518200835_rename_users_with_renamed_namespace.rb b/db/post_migrate/20170518200835_rename_users_with_renamed_namespace.rb
new file mode 100644
index 00000000000..da0fcda87a6
--- /dev/null
+++ b/db/post_migrate/20170518200835_rename_users_with_renamed_namespace.rb
@@ -0,0 +1,50 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class RenameUsersWithRenamedNamespace < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ DISALLOWED_ROOT_PATHS = %w[
+ abuse_reports
+ api
+ autocomplete
+ explore
+ health_check
+ import
+ invites
+ jwt
+ koding
+ member
+ notification_settings
+ oauth
+ sent_notifications
+ unicorn_test
+ uploads
+ users
+ ]
+
+ def up
+ DISALLOWED_ROOT_PATHS.each do |path|
+ users = Arel::Table.new(:users)
+ namespaces = Arel::Table.new(:namespaces)
+ predicate = namespaces[:owner_id].eq(users[:id])
+ .and(namespaces[:type].eq(nil))
+ .and(users[:username].matches(path))
+ update_sql = if Gitlab::Database.postgresql?
+ "UPDATE users SET username = namespaces.path "\
+ "FROM namespaces WHERE #{predicate.to_sql}"
+ else
+ "UPDATE users INNER JOIN namespaces "\
+ "ON namespaces.owner_id = users.id "\
+ "SET username = namespaces.path "\
+ "WHERE #{predicate.to_sql}"
+ end
+
+ connection.execute(update_sql)
+ end
+ end
+
+ def down
+ end
+end
diff --git a/db/post_migrate/20170518231126_fix_wrongly_renamed_routes.rb b/db/post_migrate/20170518231126_fix_wrongly_renamed_routes.rb
new file mode 100644
index 00000000000..c78beda9d21
--- /dev/null
+++ b/db/post_migrate/20170518231126_fix_wrongly_renamed_routes.rb
@@ -0,0 +1,104 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class FixWronglyRenamedRoutes < ActiveRecord::Migration
+ include Gitlab::Database::RenameReservedPathsMigration::V1
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ DISALLOWED_ROOT_PATHS = %w[
+ -
+ abuse_reports
+ api
+ autocomplete
+ explore
+ health_check
+ import
+ invites
+ jwt
+ koding
+ member
+ notification_settings
+ oauth
+ sent_notifications
+ unicorn_test
+ uploads
+ users
+ ]
+
+ FIXED_PATHS = DISALLOWED_ROOT_PATHS.map { |p| "#{p}0" }
+
+ class Route < Gitlab::Database::RenameReservedPathsMigration::V1::MigrationClasses::Route
+ self.table_name = 'routes'
+ end
+
+ def routes
+ @routes ||= Route.arel_table
+ end
+
+ def namespaces
+ @namespaces ||= Arel::Table.new(:namespaces)
+ end
+
+ def wildcard_collection(collection)
+ collection.map { |word| "#{word}%" }
+ end
+
+ # The routes that got incorrectly renamed before, still have a namespace that
+ # contains the correct path.
+ # This query fetches all rows from the `routes` table that meet the following
+ # conditions using `api` as an example:
+ # - route.path ILIKE `api0%`
+ # - route.source_type = `Namespace`
+ # - namespace.parent_id IS NULL
+ # - namespace.path ILIKE `api%`
+ # - NOT(namespace.path ILIKE `api0%`)
+ # This gives us all root-routes, that were renamed, but their namespace was not.
+ #
+ def wrongly_renamed
+ Route.joins("INNER JOIN namespaces ON routes.source_id = namespaces.id")
+ .where(
+ routes[:source_type].eq('Namespace')
+ .and(namespaces[:parent_id].eq(nil))
+ )
+ .where(namespaces[:path].matches_any(wildcard_collection(DISALLOWED_ROOT_PATHS)))
+ .where.not(namespaces[:path].matches_any(wildcard_collection(FIXED_PATHS)))
+ .where(routes[:path].matches_any(wildcard_collection(FIXED_PATHS)))
+ end
+
+ # Using the query above, we just fetch the `route.path` & the `namespace.path`
+ # `route.path` is the part of the route that is now incorrect
+ # `namespace.path` is what it should be
+ # We can use `route.path` to find all the namespaces that need to be fixed
+ # And we can use `namespace.path` to apply the correct name.
+ #
+ def paths_and_corrections
+ connection.select_all(
+ wrongly_renamed.select(routes[:path], namespaces[:path].as('namespace_path')).to_sql
+ )
+ end
+
+ # This can be used to limit the `update_in_batches` call to all routes for a
+ # single namespace, note the `/` that's what went wrong in the initial migration.
+ #
+ def routes_in_namespace_query(namespace)
+ routes[:path].matches_any([namespace, "#{namespace}/%"])
+ end
+
+ def up
+ paths_and_corrections.each do |root_namespace|
+ wrong_path = root_namespace['path']
+ correct_path = root_namespace['namespace_path']
+ replace_statement = replace_sql(Route.arel_table[:path], wrong_path, correct_path)
+
+ update_column_in_batches(:routes, :path, replace_statement) do |table, query|
+ query.where(routes_in_namespace_query(wrong_path))
+ end
+ end
+ end
+
+ def down
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 294e0b531eb..d14126401c9 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20170516183131) do
+ActiveRecord::Schema.define(version: 20170518231126) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
diff --git a/doc/user/img/gitlab_snippet.png b/doc/user/img/gitlab_snippet.png
new file mode 100644
index 00000000000..718347fc2d4
--- /dev/null
+++ b/doc/user/img/gitlab_snippet.png
Binary files differ
diff --git a/doc/user/project/issues/img/create_new_merge_request.png b/doc/user/project/issues/img/create_new_merge_request.png
deleted file mode 100644
index d4bfb6fa463..00000000000
--- a/doc/user/project/issues/img/create_new_merge_request.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/issues/img/issues_main_view.png b/doc/user/project/issues/img/issues_main_view.png
index e9a94a3aab0..4faa42e40ee 100755..100644
--- a/doc/user/project/issues/img/issues_main_view.png
+++ b/doc/user/project/issues/img/issues_main_view.png
Binary files differ
diff --git a/doc/user/project/issues/img/issues_main_view_numbered.jpg b/doc/user/project/issues/img/issues_main_view_numbered.jpg
new file mode 100644
index 00000000000..4b5d7fba459
--- /dev/null
+++ b/doc/user/project/issues/img/issues_main_view_numbered.jpg
Binary files differ
diff --git a/doc/user/project/issues/img/issues_main_view_numbered.png b/doc/user/project/issues/img/issues_main_view_numbered.png
deleted file mode 100755
index 9cff61d7041..00000000000
--- a/doc/user/project/issues/img/issues_main_view_numbered.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index c726da17259..9598cb801be 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -49,6 +49,10 @@ Read through the [documentation on creating issues](create_new_issue.md).
Read through the distinct ways to [close issues](closing_issues.md) on GitLab.
+## Create a merge request from an issue
+
+Learn more about it on the [GitLab Issues Functionalities documentation](issues_functionalities.md#18-new-merge-request).
+
## Search for an issue
Learn how to [find an issue](../../search/index.md) by searching for and filtering them.
diff --git a/doc/user/project/issues/issues_functionalities.md b/doc/user/project/issues/issues_functionalities.md
index e1923e91042..ba843201e1a 100644
--- a/doc/user/project/issues/issues_functionalities.md
+++ b/doc/user/project/issues/issues_functionalities.md
@@ -6,7 +6,7 @@ Please read through the [GitLab Issue Documentation](index.md) for an overview o
The image bellow illustrates how an issue looks like:
-![Issue view](img/issues_main_view_numbered.png)
+![Issue view](img/issues_main_view_numbered.jpg)
You can find all the information on that issue on one screen.
@@ -41,6 +41,21 @@ it's reassigned to someone else to take it from there.
if a user is not member of that project, it can only be
assigned to them if they created the issue themselves.
+##### 3.1. Multiple Assignees (EES/EEP)
+
+Issue Weights are only available in [GitLab Enterprise Edition](https://about.gitlab.com/gitlab-ee/).
+
+Often multiple people likely work on the same issue together,
+which can especially be difficult to track in large teams
+where there is shared ownership of an issue.
+
+In GitLab Enterprise Edition, you can also select multiple assignees
+to an issue.
+
+> **Note:**
+Multiple Assignees was [introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/1904)
+in [GitLab Enterprise Edition 9.2](https://about.gitlab.com/2017/05/22/gitlab-9-2-released/#multiple-assignees-for-issues).
+
#### 4. Milestone
- Select a [milestone](../milestones/index.md) to attribute that issue to.
@@ -153,14 +168,9 @@ Once you wrote your comment, you can either:
- Click "Start discussion": start a thread within that issue's thread to discuss specific points.
- Click "Comment and close issue": post your comment and close that issue in one click.
-#### 18. New branch
-
-- [New branch](../repository/web_editor.md#create-a-new-branch-from-an-issue):
-create a new branch, followed by a new merge request which will automatically close that
-issue as soon as that merge request is merged.
-
-#### 19. New merge request
-
-- Create a new merge request (with source branch) in one action. Optionally just create a new branch, as explained above.
+#### 18. New Merge Request
-![Create new merge request](img/create_new_merge_request.png)
+- Create a new merge request (with a new source branch named after the issue) in one action.
+The merge request will automatically close that issue as soon as merged.
+- Optionally, you can just create a [new branch](../repository/web_editor.md#create-a-new-branch-from-an-issue)
+named after that issue.
diff --git a/doc/user/snippets.md b/doc/user/snippets.md
index 417360e08ac..78861625f8a 100644
--- a/doc/user/snippets.md
+++ b/doc/user/snippets.md
@@ -2,8 +2,18 @@
Snippets are little bits of code or text.
+![GitLab Snippet](img/gitlab_snippet.png)
+
There are 2 types of snippets - project snippets and personal snippets.
+## Comments
+
+With GitLab Snippets you engage in a conversation about that piece of code,
+facilitating the collaboration among users.
+
+> **Note:**
+Comments on snippets was [introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/12910) in [GitLab Community Edition 9.2](https://about.gitlab.com/2017/05/22/gitlab-9-2-released/#comments-for-personal-snippets).
+
## Project snippets
Project snippets are always related to a specific project - see [Project features](../workflow/project_features.md) for more information.
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index fb4a4721a58..c880da1e36a 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -38,7 +38,7 @@ describe Projects::PipelinesController do
end
describe 'GET show JSON' do
- let!(:pipeline) { create(:ci_pipeline_with_one_job, project: project) }
+ let(:pipeline) { create(:ci_pipeline_with_one_job, project: project) }
it 'returns the pipeline' do
get_pipeline_json
@@ -49,20 +49,48 @@ describe Projects::PipelinesController do
expect(json_response['details']).to have_key 'stages'
end
- context 'when the pipeline has multiple jobs' do
+ context 'when the pipeline has multiple stages and groups' do
+ before do
+ RequestStore.begin!
+
+ create_build('build', 0, 'build')
+ create_build('test', 1, 'rspec 0')
+ create_build('deploy', 2, 'production')
+ create_build('post deploy', 3, 'pages 0')
+ end
+
+ after do
+ RequestStore.end!
+ RequestStore.clear!
+ end
+
+ let(:project) { create(:project) }
+ let(:pipeline) do
+ create(:ci_empty_pipeline, project: project, user: user, sha: project.commit.id)
+ end
+
it 'does not perform N + 1 queries' do
control_count = ActiveRecord::QueryRecorder.new { get_pipeline_json }.count
- create(:ci_build, pipeline: pipeline)
+ create_build('test', 1, 'rspec 1')
+ create_build('test', 1, 'spinach 0')
+ create_build('test', 1, 'spinach 1')
+ create_build('test', 1, 'audit')
+ create_build('post deploy', 3, 'pages 1')
+ create_build('post deploy', 3, 'pages 2')
- # The plus 2 is needed to group and sort
- expect { get_pipeline_json }.not_to exceed_query_limit(control_count + 2)
+ new_count = ActiveRecord::QueryRecorder.new { get_pipeline_json }.count
+ expect(new_count).to be_within(12).of(control_count)
end
end
def get_pipeline_json
get :show, namespace_id: project.namespace, project_id: project, id: pipeline, format: :json
end
+
+ def create_build(stage, stage_idx, name)
+ create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name)
+ end
end
describe 'GET stages.json' do
diff --git a/spec/migrations/fix_wrongly_renamed_routes_spec.rb b/spec/migrations/fix_wrongly_renamed_routes_spec.rb
new file mode 100644
index 00000000000..148290b0e7d
--- /dev/null
+++ b/spec/migrations/fix_wrongly_renamed_routes_spec.rb
@@ -0,0 +1,73 @@
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20170518231126_fix_wrongly_renamed_routes.rb')
+
+describe FixWronglyRenamedRoutes, truncate: true do
+ let(:subject) { described_class.new }
+ let(:broken_namespace) do
+ namespace = create(:group, name: 'apiis')
+ namespace.route.update_attribute(:path, 'api0is')
+ namespace
+ end
+
+ describe '#wrongly_renamed' do
+ it "includes routes that have names that don't match their namespace" do
+ broken_namespace
+ _other_namespace = create(:group, name: 'api0')
+
+ expect(subject.wrongly_renamed.map(&:id))
+ .to contain_exactly(broken_namespace.route.id)
+ end
+ end
+
+ describe "#paths_and_corrections" do
+ it 'finds the wrong path and gets the correction from the namespace' do
+ broken_namespace
+ namespace = create(:group, name: 'uploads-test')
+ namespace.route.update_attribute(:path, 'uploads0-test')
+
+ expected_result = [
+ { 'namespace_path' => 'apiis', 'path' => 'api0is' },
+ { 'namespace_path' => 'uploads-test', 'path' => 'uploads0-test' }
+ ]
+
+ expect(subject.paths_and_corrections).to include(*expected_result)
+ end
+ end
+
+ describe '#routes_in_namespace_query' do
+ it 'includes only the required routes' do
+ namespace = create(:group, path: 'hello')
+ project = create(:empty_project, namespace: namespace)
+ _other_namespace = create(:group, path: 'hello0')
+
+ result = Route.where(subject.routes_in_namespace_query('hello'))
+
+ expect(result).to contain_exactly(namespace.route, project.route)
+ end
+ end
+
+ describe '#up' do
+ let(:broken_project) do
+ project = create(:empty_project, namespace: broken_namespace, path: 'broken-project')
+ project.route.update_attribute(:path, 'api0is/broken-project')
+ project
+ end
+
+ it 'renames incorrectly named routes' do
+ broken_project
+
+ subject.up
+
+ expect(broken_project.route.reload.path).to eq('apiis/broken-project')
+ expect(broken_namespace.route.reload.path).to eq('apiis')
+ end
+
+ it "doesn't touch namespaces that look like something that should be renamed" do
+ namespace = create(:group, path: 'api0')
+
+ subject.up
+
+ expect(namespace.route.reload.path).to eq('api0')
+ end
+ end
+end
diff --git a/spec/migrations/rename_users_with_renamed_namespace_spec.rb b/spec/migrations/rename_users_with_renamed_namespace_spec.rb
new file mode 100644
index 00000000000..1e9aab3d9a1
--- /dev/null
+++ b/spec/migrations/rename_users_with_renamed_namespace_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20170518200835_rename_users_with_renamed_namespace.rb')
+
+describe RenameUsersWithRenamedNamespace, truncate: true do
+ it 'renames a user that had their namespace renamed to the namespace path' do
+ other_user = create(:user, username: 'kodingu')
+ other_user1 = create(:user, username: 'api0')
+
+ user = create(:user, username: "Users0")
+ user.update_attribute(:username, 'Users')
+ user1 = create(:user, username: "import0")
+ user1.update_attribute(:username, 'import')
+
+ described_class.new.up
+
+ expect(user.reload.username).to eq('Users0')
+ expect(user1.reload.username).to eq('import0')
+
+ expect(other_user.reload.username).to eq('kodingu')
+ expect(other_user1.reload.username).to eq('api0')
+ end
+end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 157d17fbb68..56b24ce62f3 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -854,6 +854,16 @@ describe Ci::Pipeline, models: true do
end
end
end
+
+ context 'when there is a manual action present in the pipeline' do
+ before do
+ create(:ci_build, :manual, pipeline: pipeline)
+ end
+
+ it 'is not cancelable' do
+ expect(pipeline).not_to be_cancelable
+ end
+ end
end
describe '#cancel_running' do