Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.vue8
-rw-r--r--app/assets/javascripts/boards/models/issue.js1
-rw-r--r--app/assets/javascripts/lib/utils/http_status.js1
-rw-r--r--app/assets/stylesheets/pages/boards.scss4
-rw-r--r--app/controllers/groups/boards_controller.rb5
-rw-r--r--app/policies/group_policy.rb1
-rw-r--r--app/services/ci/create_cross_project_pipeline_service.rb2
-rw-r--r--changelogs/unreleased/34723-visually-differentiate-blocked-issues.yml5
-rw-r--r--changelogs/unreleased/35546-child-epic-error-messages.yml5
-rw-r--r--changelogs/unreleased/drop-bridge-on-any-pipeline-errors.yml5
-rw-r--r--doc/administration/raketasks/project_import_export.md7
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql23
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json10
-rw-r--r--doc/api/graphql/reference/index.md8
-rw-r--r--doc/user/project/img/issue_boards_blocked_icon_v12_8.pngbin0 -> 66310 bytes
-rw-r--r--doc/user/project/issue_board.md8
-rw-r--r--doc/user/project/settings/import_export.md34
-rw-r--r--lib/api/group_boards.rb4
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/controllers/groups/boards_controller_spec.rb10
-rw-r--r--spec/frontend/boards/issue_card_spec.js22
-rw-r--r--spec/policies/group_policy_spec.rb4
-rw-r--r--spec/support/shared_contexts/policies/group_policy_shared_context.rb2
23 files changed, 136 insertions, 36 deletions
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue
index 0e0d1e64f4a..bdaed17fd09 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.vue
+++ b/app/assets/javascripts/boards/components/issue_card_inner.vue
@@ -162,6 +162,14 @@ export default {
<div class="d-flex board-card-header" dir="auto">
<h4 class="board-card-title append-bottom-0 prepend-top-0">
<icon
+ v-if="issue.blocked"
+ v-gl-tooltip
+ name="issue-block"
+ :title="__('Blocked issue')"
+ class="issue-blocked-icon append-right-4"
+ :aria-label="__('Blocked issue')"
+ />
+ <icon
v-if="issue.confidential"
v-gl-tooltip
name="eye-slash"
diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js
index 1cee9e5725a..044d96a9aec 100644
--- a/app/assets/javascripts/boards/models/issue.js
+++ b/app/assets/javascripts/boards/models/issue.js
@@ -37,6 +37,7 @@ class ListIssue {
this.project_id = obj.project_id;
this.timeEstimate = obj.time_estimate;
this.assignableLabelsEndpoint = obj.assignable_labels_endpoint;
+ this.blocked = obj.blocked;
if (obj.project) {
this.project = new IssueProject(obj.project);
diff --git a/app/assets/javascripts/lib/utils/http_status.js b/app/assets/javascripts/lib/utils/http_status.js
index 1c7d59054dc..08a77966bbd 100644
--- a/app/assets/javascripts/lib/utils/http_status.js
+++ b/app/assets/javascripts/lib/utils/http_status.js
@@ -19,6 +19,7 @@ const httpStatusCodes = {
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
+ CONFLICT: 409,
GONE: 410,
UNPROCESSABLE_ENTITY: 422,
SERVICE_UNAVAILABLE: 503,
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 31e87d1a7cf..42d7b0d08f7 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -287,6 +287,10 @@
cursor: help;
}
+ .issue-blocked-icon {
+ color: $red-500;
+ }
+
@include media-breakpoint-down(md) {
padding: $gl-padding-8;
}
diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb
index 8c9bf17f017..fab84fb8299 100644
--- a/app/controllers/groups/boards_controller.rb
+++ b/app/controllers/groups/boards_controller.rb
@@ -4,6 +4,7 @@ class Groups::BoardsController < Groups::ApplicationController
include BoardsActions
include RecordUserLastActivity
+ before_action :authorize_read_board!, only: [:index, :show]
before_action :assign_endpoint_vars
before_action do
push_frontend_feature_flag(:multi_select_board, default_enabled: true)
@@ -16,4 +17,8 @@ class Groups::BoardsController < Groups::ApplicationController
@namespace_path = group.to_param
@labels_endpoint = group_labels_url(group)
end
+
+ def authorize_read_board!
+ access_denied! unless can?(current_user, :read_board, group)
+ end
end
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 1cd400e4dfa..3bb7ab05be2 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -67,6 +67,7 @@ class GroupPolicy < BasePolicy
enable :read_milestone
enable :read_list
enable :read_label
+ enable :read_board
end
rule { has_access }.enable :read_namespace
diff --git a/app/services/ci/create_cross_project_pipeline_service.rb b/app/services/ci/create_cross_project_pipeline_service.rb
index a60793463b4..dd15fa8ddb8 100644
--- a/app/services/ci/create_cross_project_pipeline_service.rb
+++ b/app/services/ci/create_cross_project_pipeline_service.rb
@@ -30,7 +30,7 @@ module Ci
end
downstream_pipeline.tap do |pipeline|
- @bridge.drop!(:downstream_pipeline_creation_failed) if pipeline.has_yaml_errors?
+ @bridge.drop!(:downstream_pipeline_creation_failed) if pipeline.errors.any?
end
end
diff --git a/changelogs/unreleased/34723-visually-differentiate-blocked-issues.yml b/changelogs/unreleased/34723-visually-differentiate-blocked-issues.yml
new file mode 100644
index 00000000000..aa97ccd1e2c
--- /dev/null
+++ b/changelogs/unreleased/34723-visually-differentiate-blocked-issues.yml
@@ -0,0 +1,5 @@
+---
+title: Add blocked icon on issue board card
+merge_request: 24420
+author:
+type: added
diff --git a/changelogs/unreleased/35546-child-epic-error-messages.yml b/changelogs/unreleased/35546-child-epic-error-messages.yml
new file mode 100644
index 00000000000..ee8daf327a1
--- /dev/null
+++ b/changelogs/unreleased/35546-child-epic-error-messages.yml
@@ -0,0 +1,5 @@
+---
+title: Improve error messages when adding a child epic
+merge_request: 22688
+author:
+type: fixed
diff --git a/changelogs/unreleased/drop-bridge-on-any-pipeline-errors.yml b/changelogs/unreleased/drop-bridge-on-any-pipeline-errors.yml
new file mode 100644
index 00000000000..831192fc097
--- /dev/null
+++ b/changelogs/unreleased/drop-bridge-on-any-pipeline-errors.yml
@@ -0,0 +1,5 @@
+---
+title: Drop bridge on any downstream pipeline errors
+merge_request: 24735
+author:
+type: fixed
diff --git a/doc/administration/raketasks/project_import_export.md b/doc/administration/raketasks/project_import_export.md
index e8d2b36ab24..6d874d596e1 100644
--- a/doc/administration/raketasks/project_import_export.md
+++ b/doc/administration/raketasks/project_import_export.md
@@ -32,9 +32,10 @@ bundle exec rake gitlab:import_export:data RAILS_ENV=production
Note the following:
-- Importing is not possible if the version of the import instance is older than that of the exporter.
-- The project import option must be enabled in application settings
- (`/admin/application_settings/general`) under **Import sources**, which is available
+- Importing is only possible if the version of the import and export GitLab instances are
+ compatible as described in the [Version history](../../user/project/settings/import_export.md#version-history).
+- The project import option must be enabled in
+ application settings (`/admin/application_settings/general`) under **Import sources**, which is available
under **{admin}** **Admin Area >** **{settings}** **Settings > Visibility and access controls**.
- The exports are stored in a temporary [shared directory](../../development/shared_files.md)
and are deleted every 24 hours by a specific worker.
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 125009adc35..c8a91d830a0 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -1986,7 +1986,20 @@ type Epic implements Noteable {
"""
last: Int
): UserConnection
- reference(full: Boolean = false): String!
+
+ """
+ Internal reference of the epic. Returned in shortened format by default
+ """
+ reference(
+ """
+ Indicates if the reference should be returned in full
+ """
+ full: Boolean = false
+ ): String!
+
+ """
+ URI path of the epic-issue relationship
+ """
relationPath: String
"""
@@ -2043,7 +2056,15 @@ type Epic implements Noteable {
Permissions for the current user on the resource
"""
userPermissions: EpicPermissions!
+
+ """
+ Web path of the epic
+ """
webPath: String!
+
+ """
+ Web URL of the epic
+ """
webUrl: String!
}
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 17a3d8eb2e2..08b84a1ca35 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -5013,11 +5013,11 @@
},
{
"name": "reference",
- "description": null,
+ "description": "Internal reference of the epic. Returned in shortened format by default",
"args": [
{
"name": "full",
- "description": null,
+ "description": "Indicates if the reference should be returned in full",
"type": {
"kind": "SCALAR",
"name": "Boolean",
@@ -5040,7 +5040,7 @@
},
{
"name": "relationPath",
- "description": null,
+ "description": "URI path of the epic-issue relationship",
"args": [
],
@@ -5224,7 +5224,7 @@
},
{
"name": "webPath",
- "description": null,
+ "description": "Web path of the epic",
"args": [
],
@@ -5242,7 +5242,7 @@
},
{
"name": "webUrl",
- "description": null,
+ "description": "Web URL of the epic",
"args": [
],
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index beffd29d884..5e0b7465c20 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -295,8 +295,8 @@ Represents an epic.
| `id` | ID! | ID of the epic |
| `iid` | ID! | Internal ID of the epic |
| `parent` | Epic | Parent epic of the epic |
-| `reference` | String! | |
-| `relationPath` | String | |
+| `reference` | String! | Internal reference of the epic. Returned in shortened format by default |
+| `relationPath` | String | URI path of the epic-issue relationship |
| `relativePosition` | Int | The relative position of the epic in the epic tree |
| `startDate` | Time | Start date of the epic |
| `startDateFixed` | Time | Fixed start date of the epic |
@@ -308,8 +308,8 @@ Represents an epic.
| `updatedAt` | Time | Timestamp of the epic's last activity |
| `upvotes` | Int! | Number of upvotes the epic has received |
| `userPermissions` | EpicPermissions! | Permissions for the current user on the resource |
-| `webPath` | String! | |
-| `webUrl` | String! | |
+| `webPath` | String! | Web path of the epic |
+| `webUrl` | String! | Web URL of the epic |
## EpicDescendantCount
diff --git a/doc/user/project/img/issue_boards_blocked_icon_v12_8.png b/doc/user/project/img/issue_boards_blocked_icon_v12_8.png
new file mode 100644
index 00000000000..ede57b760ed
--- /dev/null
+++ b/doc/user/project/img/issue_boards_blocked_icon_v12_8.png
Binary files differ
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index 06ecc224f5f..0a5d7805e41 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -303,6 +303,14 @@ Different issue board features are available in different [GitLab tiers](https:/
| Premium / Silver | Multiple | Multiple | Yes | Yes |
| Ultimate / Gold | Multiple | Multiple | Yes | Yes |
+## Blocked issues
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34723) in GitLab 12.8.
+
+If an issue is blocked by another issue, an icon will display next to its title to differentiate it from unblocked issues.
+
+![Blocked issues](img/issue_boards_blocked_icon_v12_8.png)
+
## Actions you can take on an Issue Board
- [Create a new list](#creating-a-new-list).
diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md
index 2266534dc8f..cdf6a789ec2 100644
--- a/doc/user/project/settings/import_export.md
+++ b/doc/user/project/settings/import_export.md
@@ -6,28 +6,30 @@
Existing projects running on any GitLab instance or GitLab.com can be exported with all their related
data and be moved into a new GitLab instance.
+The **GitLab import/export** button is displayed if the project import option is enabled.
+
See also:
-- [Project import/export API](../../../api/project_import_export.md).
-- [Project import/export administration rake tasks](../../../administration/raketasks/project_import_export.md). **(CORE ONLY)**
+- [Project import/export API](../../../api/project_import_export.md)
+- [Project import/export administration rake tasks](../../../administration/raketasks/project_import_export.md) **(CORE ONLY)**
+
+To set up a project import/export:
+
+ 1. Navigate to **{admin}** **Admin Area >** **{settings}** **Settings > Visibility and access controls**.
+ 1. Scroll to **Import sources**
+ 1. Enable desired **Import sources**
## Important notes
Note the following:
-- Importing is not possible if the import instance version differs from
- that of the exporter.
-- The project import option must be enabled in application settings
- (`/admin/application_settings/general`) under **Import sources**, which is
- available under **{admin}** **Admin Area >** **{settings}** **Settings > Visibility and access controls**.
- Ask your administrator if you don't see the **GitLab export** button when
- creating a new project.
-- The exports are stored in a temporary [shared directory](../../../development/shared_files.md)
+- Imports will fail unless the import and export GitLab instances are
+ compatible as described in the [Version history](#version-history).
+- Exports are stored in a temporary [shared directory](../../../development/shared_files.md)
and are deleted every 24 hours by a specific worker.
- Group members are exported as project members, as long as the user has
- maintainer or admin access to the group where the exported project lives. An admin
- in the import side is required to map the users, based on email.
- Otherwise, a supplementary comment is left to mention the original author and
+ maintainer or admin access to the group where the exported project lives. Import admins should map users by email address.
+ Otherwise, a supplementary comment is left to mention that the original author and
the MRs, notes, or issues will be owned by the importer.
- Project members with owner access will be imported as maintainers.
- If an imported project contains merge requests originating from forks,
@@ -39,7 +41,7 @@ Note the following:
The following table lists updates to Import/Export:
-| GitLab version | Import/Export version |
+| GitLab version | Import/Export schema version |
| ---------------- | --------------------- |
| 11.1 to current | 0.2.4 |
| 10.8 | 0.2.3 |
@@ -56,7 +58,9 @@ The following table lists updates to Import/Export:
| 8.9.5 | 0.1.1 |
| 8.9.0 | 0.1.0 |
-For example, 8.10.3 and 8.11 will have the same Import/Export version (0.1.3)
+Projects can be exported and imported only between versions of GitLab with matching Import/Export versions.
+
+For example, 8.10.3 and 8.11 have the same Import/Export version (0.1.3)
and the exports between them will be compatible.
## Exported contents
diff --git a/lib/api/group_boards.rb b/lib/api/group_boards.rb
index f7ef0cfd0d8..88d04e70e11 100644
--- a/lib/api/group_boards.rb
+++ b/lib/api/group_boards.rb
@@ -28,6 +28,7 @@ module API
success ::API::Entities::Board
end
get '/:board_id' do
+ authorize!(:read_board, user_group)
present board, with: ::API::Entities::Board
end
@@ -39,6 +40,7 @@ module API
use :pagination
end
get '/' do
+ authorize!(:read_board, user_group)
present paginate(board_parent.boards.with_associations), with: Entities::Board
end
end
@@ -55,6 +57,7 @@ module API
use :pagination
end
get '/lists' do
+ authorize!(:read_board, user_group)
present paginate(board_lists), with: Entities::List
end
@@ -66,6 +69,7 @@ module API
requires :list_id, type: Integer, desc: 'The ID of a list'
end
get '/lists/:list_id' do
+ authorize!(:read_board, user_group)
present board_lists.find(params[:list_id]), with: Entities::List
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b6ecd5e5926..c64785c7e44 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2768,6 +2768,9 @@ msgstr ""
msgid "Blocked"
msgstr ""
+msgid "Blocked issue"
+msgstr ""
+
msgid "Blocks"
msgstr ""
diff --git a/spec/controllers/groups/boards_controller_spec.rb b/spec/controllers/groups/boards_controller_spec.rb
index 79edfd69429..acfa8bc9354 100644
--- a/spec/controllers/groups/boards_controller_spec.rb
+++ b/spec/controllers/groups/boards_controller_spec.rb
@@ -27,7 +27,8 @@ describe Groups::BoardsController do
context 'with unauthorized user' do
before do
allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(false)
+ allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(true)
+ allow(Ability).to receive(:allowed?).with(user, :read_board, group).and_return(false)
end
it 'returns a not found 404 response' do
@@ -70,7 +71,8 @@ describe Groups::BoardsController do
context 'with unauthorized user' do
before do
allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(false)
+ allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(true)
+ allow(Ability).to receive(:allowed?).with(user, :read_board, group).and_return(false)
end
it 'returns a not found 404 response' do
@@ -105,7 +107,8 @@ describe Groups::BoardsController do
context 'with unauthorized user' do
before do
allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(false)
+ allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(true)
+ allow(Ability).to receive(:allowed?).with(user, :read_board, group).and_return(false)
end
it 'returns a not found 404 response' do
@@ -142,6 +145,7 @@ describe Groups::BoardsController do
context 'with unauthorized user' do
before do
allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global).and_return(true)
+ allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(true)
allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(false)
end
diff --git a/spec/frontend/boards/issue_card_spec.js b/spec/frontend/boards/issue_card_spec.js
index 526cdb81ac6..1fd2b417aba 100644
--- a/spec/frontend/boards/issue_card_spec.js
+++ b/spec/frontend/boards/issue_card_spec.js
@@ -66,7 +66,11 @@ describe('Issue card component', () => {
});
it('does not render confidential icon', () => {
- expect(wrapper.find('.fa-eye-flash').exists()).toBe(false);
+ expect(wrapper.find('.confidential-icon').exists()).toBe(false);
+ });
+
+ it('does not render blocked icon', () => {
+ expect(wrapper.find('.issue-blocked-icon').exists()).toBe(false);
});
it('renders confidential icon', done => {
@@ -324,4 +328,20 @@ describe('Issue card component', () => {
.catch(done.fail);
});
});
+
+ describe('blocked', () => {
+ beforeEach(done => {
+ wrapper.setProps({
+ issue: {
+ ...wrapper.props('issue'),
+ blocked: true,
+ },
+ });
+ wrapper.vm.$nextTick(done);
+ });
+
+ it('renders blocked icon if issue is blocked', () => {
+ expect(wrapper.find('.issue-blocked-icon').exists()).toBe(true);
+ });
+ });
});
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index ae9d125f970..5a9ca9f7b7e 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -438,7 +438,7 @@ describe GroupPolicy do
end
end
- context "create_projects" do
+ context 'create_projects' do
context 'when group has no project creation level set' do
before_all do
group.update(project_creation_level: nil)
@@ -560,7 +560,7 @@ describe GroupPolicy do
end
end
- context "create_subgroup" do
+ context 'create_subgroup' do
context 'when group has subgroup creation level set to owner' do
before_all do
group.update(subgroup_creation_level: ::Gitlab::Access::OWNER_SUBGROUP_ACCESS)
diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
index c503197a773..63ebbcb93f9 100644
--- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
@@ -16,7 +16,7 @@ RSpec.shared_context 'GroupPolicy context' do
read_group_merge_requests
]
end
- let(:read_group_permissions) { %i[read_label read_list read_milestone] }
+ let(:read_group_permissions) { %i[read_label read_list read_milestone read_board] }
let(:reporter_permissions) { %i[admin_label read_container_image] }
let(:developer_permissions) { [:admin_milestone] }
let(:maintainer_permissions) do