summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-04 09:09:59 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-04 09:09:59 +0000
commite2c471038ab2b4f09487c1feb74520f74f834986 (patch)
tree21d8ea3ce88222c1419adaa2f79012326f29621e
parent04a893be75405b262c0899bd09eb79438210e632 (diff)
downloadgitlab-ce-e2c471038ab2b4f09487c1feb74520f74f834986.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--Dangerfile8
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/boards/constants.js8
-rw-r--r--app/assets/javascripts/boards/index.js2
-rw-r--r--app/assets/javascripts/boards/stores/actions.js34
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js3
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/views/layouts/nav/sidebar/_project_menus.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_project_packages_link.html.haml27
-rw-r--r--danger/changes_size/Dangerfile19
-rw-r--r--danger/database/Dangerfile2
-rw-r--r--danger/feature_flag/Dangerfile2
-rw-r--r--doc/api/services.md4
-rw-r--r--lib/sidebars/projects/menus/packages_registries_menu.rb71
-rw-r--r--lib/sidebars/projects/panel.rb1
-rw-r--r--qa/qa/page/project/sub_menus/packages.rb20
-rw-r--r--spec/features/boards/user_visits_board_spec.rb78
-rw-r--r--spec/features/projects/settings/packages_settings_spec.rb26
-rw-r--r--spec/frontend/boards/stores/actions_spec.js81
-rw-r--r--spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb139
-rw-r--r--spec/tooling/danger/project_helper_spec.rb2
-rw-r--r--spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb84
-rw-r--r--tooling/danger/project_helper.rb15
25 files changed, 478 insertions, 162 deletions
diff --git a/Dangerfile b/Dangerfile
index 37a45674e16..699be613f2d 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -2,14 +2,10 @@
require 'gitlab-dangerfiles'
-gitlab_dangerfiles = Gitlab::Dangerfiles::Engine.new(self)
-gitlab_dangerfiles.import_plugins
-
-return if helper.release_automation?
-
+Gitlab::Dangerfiles.import_plugins(danger)
danger.import_plugin('danger/plugins/*.rb')
-gitlab_dangerfiles.import_dangerfiles
+return if helper.release_automation?
project_helper.rule_names.each do |rule|
danger.import_dangerfile(path: File.join('danger', rule))
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index ada363b4fbc..83823ce4036 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-d7c7ca994f16601bda8854ca9d20175dc8a11c74
+bb763fb573555a0f9714002c2755bdd396cab3dd
diff --git a/Gemfile b/Gemfile
index 4aecc60600e..fcf5aae2585 100644
--- a/Gemfile
+++ b/Gemfile
@@ -403,7 +403,7 @@ group :development, :test do
end
group :development, :test, :danger do
- gem 'gitlab-dangerfiles', '~> 2.0.0', require: false
+ gem 'gitlab-dangerfiles', '~> 1.1.1', require: false
end
group :development, :test, :coverage do
diff --git a/Gemfile.lock b/Gemfile.lock
index 4d39fc99de6..1054af774c7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -447,7 +447,7 @@ GEM
terminal-table (~> 1.5, >= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
- gitlab-dangerfiles (2.0.0)
+ gitlab-dangerfiles (1.1.1)
danger-gitlab
gitlab-experiment (0.5.3)
activesupport (>= 3.0)
@@ -1449,7 +1449,7 @@ DEPENDENCIES
gitaly (~> 13.11.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
- gitlab-dangerfiles (~> 2.0.0)
+ gitlab-dangerfiles (~> 1.1.1)
gitlab-experiment (~> 0.5.3)
gitlab-fog-azure-rm (~> 1.0.1)
gitlab-fog-google (~> 1.13)
diff --git a/app/assets/javascripts/boards/constants.js b/app/assets/javascripts/boards/constants.js
index 4519992ca94..d88774d11c1 100644
--- a/app/assets/javascripts/boards/constants.js
+++ b/app/assets/javascripts/boards/constants.js
@@ -1,9 +1,11 @@
+import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
import { __ } from '~/locale';
import updateEpicSubscriptionMutation from '~/sidebar/queries/update_epic_subscription.mutation.graphql';
import updateEpicTitleMutation from '~/sidebar/queries/update_epic_title.mutation.graphql';
import boardBlockingIssuesQuery from './graphql/board_blocking_issues.query.graphql';
import destroyBoardListMutation from './graphql/board_list_destroy.mutation.graphql';
import updateBoardListMutation from './graphql/board_list_update.mutation.graphql';
+
import issueSetSubscriptionMutation from './graphql/issue_set_subscription.mutation.graphql';
import issueSetTitleMutation from './graphql/issue_set_title.mutation.graphql';
@@ -62,6 +64,12 @@ export const NOT_FILTER = 'not[';
export const flashAnimationDuration = 2000;
+export const listsQuery = {
+ [issuableTypes.issue]: {
+ query: boardListsQuery,
+ },
+};
+
export const blockingIssuablesQueries = {
[issuableTypes.issue]: {
query: boardBlockingIssuesQuery,
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index b13b04430c0..84beaebfb4b 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -37,6 +37,7 @@ import {
import { __ } from '~/locale';
import sidebarEventHub from '~/sidebar/event_hub';
import introspectionQueryResultData from '~/sidebar/fragmentTypes.json';
+import { fullBoardId } from './boards_util';
import boardConfigToggle from './config_toggle';
import mountMultipleBoardsSwitcher from './mount_multiple_boards_switcher';
@@ -135,6 +136,7 @@ export default () => {
created() {
this.setInitialBoardData({
boardId: $boardApp.dataset.boardId,
+ fullBoardId: fullBoardId($boardApp.dataset.boardId),
fullPath: $boardApp.dataset.fullPath,
boardType: this.parent,
disabled: this.disabled,
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 27dccd91b40..19285a1dc85 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -9,10 +9,11 @@ import {
subscriptionQueries,
SupportedFilters,
deleteListQueries,
+ listsQuery,
updateListQueries,
+ issuableTypes,
} from 'ee_else_ce/boards/constants';
import createBoardListMutation from 'ee_else_ce/boards/graphql/board_list_create.mutation.graphql';
-import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import createGqClient, { fetchPolicies } from '~/lib/graphql';
@@ -21,7 +22,6 @@ import { s__ } from '~/locale';
import {
formatBoardLists,
formatListIssues,
- fullBoardId,
formatListsPageInfo,
formatIssue,
formatIssueInput,
@@ -86,24 +86,22 @@ export default {
}
},
- fetchLists: ({ dispatch }) => {
- dispatch('fetchIssueLists');
- },
-
- fetchIssueLists: ({ commit, state, dispatch }) => {
- const { boardType, filterParams, fullPath, boardId } = state;
+ fetchLists: ({ commit, state, dispatch }) => {
+ const { boardType, filterParams, fullPath, fullBoardId, issuableType } = state;
const variables = {
fullPath,
- boardId: fullBoardId(boardId),
+ boardId: fullBoardId,
filters: filterParams,
- isGroup: boardType === BoardType.group,
- isProject: boardType === BoardType.project,
+ ...(issuableType === issuableTypes.issue && {
+ isGroup: boardType === BoardType.group,
+ isProject: boardType === BoardType.project,
+ }),
};
return gqlClient
.query({
- query: boardListsQuery,
+ query: listsQuery[issuableType].query,
variables,
})
.then(({ data }) => {
@@ -137,7 +135,7 @@ export default {
{ state, commit, dispatch, getters },
{ backlog, labelId, milestoneId, assigneeId, iterationId },
) => {
- const { boardId } = state;
+ const { fullBoardId } = state;
const existingList = getters.getListByLabelId(labelId);
@@ -150,7 +148,7 @@ export default {
.mutate({
mutation: createBoardListMutation,
variables: {
- boardId: fullBoardId(boardId),
+ boardId: fullBoardId,
backlog,
labelId,
milestoneId,
@@ -296,11 +294,11 @@ export default {
fetchItemsForList: ({ state, commit }, { listId, fetchNext = false }) => {
commit(types.REQUEST_ITEMS_FOR_LIST, { listId, fetchNext });
- const { fullPath, boardId, boardType, filterParams } = state;
+ const { fullPath, fullBoardId, boardType, filterParams } = state;
const variables = {
fullPath,
- boardId: fullBoardId(boardId),
+ boardId: fullBoardId,
id: listId,
filters: filterParams,
isGroup: boardType === BoardType.group,
@@ -429,7 +427,7 @@ export default {
try {
const { itemId, fromListId, toListId, moveBeforeId, moveAfterId } = moveData;
const {
- boardId,
+ fullBoardId,
boardItems: {
[itemId]: { iid, referencePath },
},
@@ -440,7 +438,7 @@ export default {
variables: {
iid,
projectPath: referencePath.split(/[#]/)[0],
- boardId: fullBoardId(boardId),
+ boardId: fullBoardId,
fromListId: getIdFromGraphQLId(fromListId),
toListId: getIdFromGraphQLId(toListId),
moveBeforeId,
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 561c21b78c1..4f89d7e9d1f 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -40,8 +40,9 @@ export const addItemToList = ({ state, listId, itemId, moveBeforeId, moveAfterId
export default {
[mutationTypes.SET_INITIAL_BOARD_DATA](state, data) {
- const { boardType, disabled, boardId, fullPath, boardConfig, issuableType } = data;
+ const { boardType, disabled, boardId, fullBoardId, fullPath, boardConfig, issuableType } = data;
state.boardId = boardId;
+ state.fullBoardId = fullBoardId;
state.fullPath = fullPath;
state.boardType = boardType;
state.disabled = disabled;
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index da8ece06bcd..68bd6a30925 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -718,12 +718,12 @@ module ProjectsHelper
end
def settings_container_registry_expiration_policy_available?(project)
- Feature.disabled?(:sidebar_refactor) &&
+ Feature.disabled?(:sidebar_refactor, current_user) &&
can_destroy_container_registry_image?(current_user, project)
end
def settings_packages_and_registries_enabled?(project)
- Feature.enabled?(:sidebar_refactor) &&
+ Feature.enabled?(:sidebar_refactor, current_user) &&
can_destroy_container_registry_image?(current_user, project)
end
diff --git a/app/views/layouts/nav/sidebar/_project_menus.html.haml b/app/views/layouts/nav/sidebar/_project_menus.html.haml
index 8d838617b64..f802488aa80 100644
--- a/app/views/layouts/nav/sidebar/_project_menus.html.haml
+++ b/app/views/layouts/nav/sidebar/_project_menus.html.haml
@@ -1,5 +1,3 @@
-= render_if_exists 'layouts/nav/sidebar/project_packages_link'
-
- if project_nav_tab? :analytics
= render 'layouts/nav/sidebar/analytics_links', links: project_analytics_navbar_links(@project, current_user)
diff --git a/app/views/layouts/nav/sidebar/_project_packages_link.html.haml b/app/views/layouts/nav/sidebar/_project_packages_link.html.haml
deleted file mode 100644
index aa25136dfc0..00000000000
--- a/app/views/layouts/nav/sidebar/_project_packages_link.html.haml
+++ /dev/null
@@ -1,27 +0,0 @@
-- packages_link = project_nav_tab?(:packages) ? project_packages_path(@project) : project_container_registry_index_path(@project)
-
-- if project_nav_tab?(:packages) || project_nav_tab?(:container_registry)
- = nav_link controller: [:packages, :repositories, :infrastructure_registry] do
- = link_to packages_link, data: { qa_selector: 'packages_link' } do
- .nav-icon-container
- = sprite_icon('package')
- %span.nav-item-name
- = _('Packages & Registries')
- %ul.sidebar-sub-level-items
- = nav_link(controller: [:packages, :repositories, :infrastructure_registry], html_options: { class: "fly-out-top-item" } ) do
- = link_to packages_link do
- %strong.fly-out-top-item-name
- = _('Packages & Registries')
- %li.divider.fly-out-top-item
- - if project_nav_tab? :packages
- = nav_link controller: :packages do
- = link_to project_packages_path(@project), title: _('Package Registry') do
- %span= _('Package Registry')
- - if project_nav_tab? :container_registry
- = nav_link controller: :repositories do
- = link_to project_container_registry_index_path(@project), class: 'shortcuts-container-registry', title: _('Container Registry') do
- %span= _('Container Registry')
- - if project_nav_tab? :infrastructure_registry
- = nav_link controller: :infrastructure_registry do
- = link_to project_infrastructure_registry_index_path(@project), title: _('Infrastructure Registry') do
- %span= _('Infrastructure Registry')
diff --git a/danger/changes_size/Dangerfile b/danger/changes_size/Dangerfile
new file mode 100644
index 00000000000..52e6cb65d04
--- /dev/null
+++ b/danger/changes_size/Dangerfile
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+# FIXME: git.info_for_file raises the following error
+# /usr/local/bundle/gems/git-1.4.0/lib/git/lib.rb:956:in `command': (Danger::DSLError)
+# [!] Invalid `Dangerfile` file:
+# [!] Invalid `Dangerfile` file: git '--git-dir=/builds/gitlab-org/gitlab/.git' '--work-tree=/builds/gitlab-org/gitlab' cat-file '-t' '' 2>&1:fatal: Not a valid object name
+# This seems to be the same as https://github.com/danger/danger/issues/535.
+
+# locale_files_updated = git.modified_files.select { |path| path.start_with?('locale') }
+# locale_files_updated.each do |locale_file_updated|
+# git_stats = git.info_for_file(locale_file_updated)
+# message "Git stats for #{locale_file_updated}: #{git_stats[:insertions]} insertions, #{git_stats[:deletions]} insertions"
+# end
+
+if git.lines_of_code > 2_000
+ warn "This merge request is definitely too big (#{git.lines_of_code} lines changed), please split it into multiple merge requests."
+elsif git.lines_of_code > 500
+ warn "This merge request is quite big (#{git.lines_of_code} lines changed), please consider splitting it into multiple merge requests."
+end
diff --git a/danger/database/Dangerfile b/danger/database/Dangerfile
index cd56ea8dd22..af4d6ed513d 100644
--- a/danger/database/Dangerfile
+++ b/danger/database/Dangerfile
@@ -55,7 +55,7 @@ if gitlab.mr_labels.include?('database') || db_paths_to_review.any?
markdown(DB_MESSAGE)
markdown(DB_FILES_MESSAGE + helper.markdown_list(db_paths_to_review)) if db_paths_to_review.any?
- unless helper.has_database_scoped_labels?
+ unless helper.has_database_scoped_labels?(gitlab.mr_labels)
gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
gitlab.mr_json['iid'],
add_labels: 'database::review pending')
diff --git a/danger/feature_flag/Dangerfile b/danger/feature_flag/Dangerfile
index 88ce6393b64..d14dd97380f 100644
--- a/danger/feature_flag/Dangerfile
+++ b/danger/feature_flag/Dangerfile
@@ -13,7 +13,7 @@ group: "%<group>s"
SUGGEST_COMMENT
def check_feature_flag_yaml(feature_flag)
- mr_group_label = helper.group_label
+ mr_group_label = helper.group_label(gitlab.mr_labels)
if feature_flag.group.nil?
message_for_feature_flag_missing_group!(feature_flag: feature_flag, mr_group_label: mr_group_label)
diff --git a/doc/api/services.md b/doc/api/services.md
index 27e057081bc..e658c51f7e6 100644
--- a/doc/api/services.md
+++ b/doc/api/services.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Services API **(FREE)**
NOTE:
-This API requires an access token with Maintainer or Owner permissions
+This API requires an access token with Maintainer or Owner permissions.
## List all active services
@@ -1253,7 +1253,7 @@ Parameters:
| `confidential_issue_channel` | string | false | The name of the channel to receive confidential issues events notifications |
| `merge_request_channel` | string | false | The name of the channel to receive merge request events notifications |
| `note_channel` | string | false | The name of the channel to receive note events notifications |
-| `confidential_note_channel` | boolean | The name of the channel to receive confidential note events notifications |
+| `confidential_note_channel` | string | false | The name of the channel to receive confidential note events notifications |
| `tag_push_channel` | string | false | The name of the channel to receive tag push events notifications |
| `pipeline_channel` | string | false | The name of the channel to receive pipeline events notifications |
| `wiki_page_channel` | string | false | The name of the channel to receive wiki page events notifications |
diff --git a/lib/sidebars/projects/menus/packages_registries_menu.rb b/lib/sidebars/projects/menus/packages_registries_menu.rb
new file mode 100644
index 00000000000..51a1df7f1d3
--- /dev/null
+++ b/lib/sidebars/projects/menus/packages_registries_menu.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module Menus
+ class PackagesRegistriesMenu < ::Sidebars::Menu
+ override :configure_menu_items
+ def configure_menu_items
+ add_item(packages_registry_menu_item)
+ add_item(container_registry_menu_item)
+ add_item(infrastructure_registry_menu_item)
+
+ true
+ end
+
+ override :link
+ def link
+ items.first.link
+ end
+
+ override :title
+ def title
+ _('Packages & Registries')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'package'
+ end
+
+ private
+
+ def packages_registry_menu_item
+ return unless ::Gitlab.config.packages.enabled
+ return unless can?(context.current_user, :read_package, context.project)
+
+ ::Sidebars::MenuItem.new(
+ title: _('Package Registry'),
+ link: project_packages_path(context.project),
+ active_routes: { controller: :packages },
+ item_id: :packages_registry,
+ container_html_options: { class: 'shortcuts-container-registry' }
+ )
+ end
+
+ def container_registry_menu_item
+ return unless ::Gitlab.config.registry.enabled
+ return unless can?(context.current_user, :read_container_image, context.project)
+
+ ::Sidebars::MenuItem.new(
+ title: _('Container Registry'),
+ link: project_container_registry_index_path(context.project),
+ active_routes: { controller: :repositories },
+ item_id: :container_registry
+ )
+ end
+
+ def infrastructure_registry_menu_item
+ return if Feature.disabled?(:infrastructure_registry_page, context.current_user)
+
+ ::Sidebars::MenuItem.new(
+ title: _('Infrastructure Registry'),
+ link: project_infrastructure_registry_index_path(context.project),
+ active_routes: { controller: :infrastructure_registry },
+ item_id: :infrastructure_registry
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/panel.rb b/lib/sidebars/projects/panel.rb
index 50a82a97adf..58f2e9e7fb4 100644
--- a/lib/sidebars/projects/panel.rb
+++ b/lib/sidebars/projects/panel.rb
@@ -17,6 +17,7 @@ module Sidebars
add_menu(Sidebars::Projects::Menus::CiCdMenu.new(context))
add_menu(Sidebars::Projects::Menus::SecurityComplianceMenu.new(context))
add_menu(Sidebars::Projects::Menus::OperationsMenu.new(context))
+ add_menu(Sidebars::Projects::Menus::PackagesRegistriesMenu.new(context))
end
override :render_raw_menus_partial
diff --git a/qa/qa/page/project/sub_menus/packages.rb b/qa/qa/page/project/sub_menus/packages.rb
index 46eae01e10d..88e2101a86d 100644
--- a/qa/qa/page/project/sub_menus/packages.rb
+++ b/qa/qa/page/project/sub_menus/packages.rb
@@ -7,19 +7,11 @@ module QA
module Packages
extend QA::Page::PageConcern
- def self.included(base)
- super
-
- base.class_eval do
- view 'app/views/layouts/nav/sidebar/_project_packages_link.html.haml' do
- element :packages_link
- end
- end
- end
-
def click_packages_link
- within_sidebar do
- click_element :packages_link
+ hover_registry do
+ within_submenu do
+ click_element(:sidebar_menu_item_link, menu_item: 'Package Registry')
+ end
end
end
@@ -35,8 +27,8 @@ module QA
def hover_registry
within_sidebar do
- scroll_to_element(:packages_link)
- find_element(:packages_link).hover
+ scroll_to_element(:sidebar_menu_link, menu_item: 'Packages & Registries')
+ find_element(:sidebar_menu_link, menu_item: 'Packages & Registries').hover
yield
end
diff --git a/spec/features/boards/user_visits_board_spec.rb b/spec/features/boards/user_visits_board_spec.rb
new file mode 100644
index 00000000000..7fe32557d6a
--- /dev/null
+++ b/spec/features/boards/user_visits_board_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User visits issue boards', :js do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:group) { create_default(:group, :public) }
+ let_it_be(:project) { create_default(:project, :public, group: group) }
+
+ # TODO use 'let' when rspec-parameterized supports it.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/329746
+ label_name1 = 'foobar'
+ label_name2 = 'in dev'
+ assignee_username = 'root'
+ issue_with_label1 = "issue with label1"
+ issue_with_label2 = "issue with label2"
+ issue_with_assignee = "issue with assignee"
+ issue_with_milestone = "issue with milestone"
+ issue_with_all_filters = "issue with all filters"
+
+ let_it_be(:label1) { create(:group_label, group: group, name: label_name1) }
+ let_it_be(:label2) { create(:group_label, group: group, name: label_name2) }
+ let_it_be(:assignee) { create_default(:group_member, :maintainer, user: create(:user, username: assignee_username), group: group ).user }
+ let_it_be(:milestone) { create_default(:milestone, project: project, start_date: Date.today - 1, due_date: 7.days.from_now) }
+
+ before_all do
+ create_default(:issue, project: project, title: issue_with_label1, labels: [label1])
+ create_default(:issue, project: project, title: issue_with_label2, labels: [label2])
+ create_default(:issue, project: project, title: issue_with_assignee, assignees: [assignee])
+ create_default(:issue, project: project, title: issue_with_milestone, milestone: milestone)
+ create_default(:issue, project: project, title: issue_with_all_filters, labels: [label1, label2], assignees: [assignee], milestone: milestone)
+ end
+
+ shared_examples "visiting board path with search params" do
+ where(:params, :expected_issues) do
+ { "label_name" => [label_name1] } | [issue_with_label1, issue_with_all_filters]
+ { "label_name" => [label_name2] } | [issue_with_label2, issue_with_all_filters]
+ { "label_name" => [label_name1, label_name2] } | [issue_with_all_filters]
+ { "assignee_username" => assignee_username } | [issue_with_assignee, issue_with_all_filters]
+ { "milestone_title" => '#started' } | [issue_with_milestone, issue_with_all_filters]
+ { "label_name" => [label_name1, label_name2], "assignee_username" => assignee_username } | [issue_with_all_filters]
+ end
+
+ with_them do
+ before do
+ visit board_path
+
+ wait_for_requests
+ end
+
+ it 'displays all issues satisfiying filter params and correctly sets url params' do
+ expect(page).to have_current_path(board_path)
+
+ page.assert_selector('[data-testid="board_card"]', count: expected_issues.length)
+ expected_issues.each { |issue_title| expect(page).to have_link issue_title }
+ end
+ end
+ end
+
+ context "project boards" do
+ let_it_be(:board) { create_default(:board, project: project) }
+ let_it_be(:backlog_list) { create_default(:backlog_list, board: board) }
+
+ let(:board_path) { project_boards_path(project, params) }
+
+ include_examples "visiting board path with search params"
+ end
+
+ context "group boards" do
+ let_it_be(:board) { create_default(:board, group: group) }
+ let_it_be(:backlog_list) { create_default(:backlog_list, board: board) }
+
+ let(:board_path) { group_boards_path(group, params) }
+
+ include_examples 'visiting board path with search params'
+ end
+end
diff --git a/spec/features/projects/settings/packages_settings_spec.rb b/spec/features/projects/settings/packages_settings_spec.rb
index 0b40cbee582..62f31fd027b 100644
--- a/spec/features/projects/settings/packages_settings_spec.rb
+++ b/spec/features/projects/settings/packages_settings_spec.rb
@@ -3,36 +3,32 @@
require 'spec_helper'
RSpec.describe 'Projects > Settings > Packages', :js do
- let(:project) { create(:project) }
- let(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+
+ let(:user) { project.owner }
before do
sign_in(user)
- project.add_maintainer(user)
+
+ stub_config(packages: { enabled: packages_enabled })
+
+ visit edit_project_path(project)
end
context 'Packages enabled in config' do
- before do
- allow(Gitlab.config.packages).to receive(:enabled).and_return(true)
- end
+ let(:packages_enabled) { true }
it 'displays the packages toggle button' do
- visit edit_project_path(project)
-
- expect(page).to have_content('Packages')
+ expect(page).to have_button('Packages', class: 'gl-toggle')
expect(page).to have_selector('input[name="project[packages_enabled]"] + button', visible: true)
end
end
context 'Packages disabled in config' do
- before do
- allow(Gitlab.config.packages).to receive(:enabled).and_return(false)
- end
+ let(:packages_enabled) { false }
it 'does not show up in UI' do
- visit edit_project_path(project)
-
- expect(page).not_to have_content('Packages')
+ expect(page).not_to have_button('Packages', class: 'gl-toggle')
end
end
end
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index afc8f20b507..34e24fe0a1c 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -1,15 +1,21 @@
import * as Sentry from '@sentry/browser';
+import {
+ inactiveId,
+ ISSUABLE,
+ ListType,
+ issuableTypes,
+ BoardType,
+ listsQuery,
+} from 'ee_else_ce/boards/constants';
import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
import testAction from 'helpers/vuex_action_helper';
import {
- fullBoardId,
formatListIssues,
formatBoardLists,
formatIssueInput,
formatIssue,
getMoveData,
} from '~/boards/boards_util';
-import { inactiveId, ISSUABLE, ListType, issuableTypes } from '~/boards/constants';
import destroyBoardListMutation from '~/boards/graphql/board_list_destroy.mutation.graphql';
import issueCreateMutation from '~/boards/graphql/issue_create.mutation.graphql';
import actions, { gqlClient } from '~/boards/stores/actions';
@@ -132,20 +138,12 @@ describe('setActiveId', () => {
});
describe('fetchLists', () => {
- it('should dispatch fetchIssueLists action', () => {
- testAction({
- action: actions.fetchLists,
- expectedActions: [{ type: 'fetchIssueLists' }],
- });
- });
-});
-
-describe('fetchIssueLists', () => {
- const state = {
+ let state = {
fullPath: 'gitlab-org',
- boardId: '1',
+ fullBoardId: 'gid://gitlab/Board/1',
filterParams: {},
boardType: 'group',
+ issuableType: 'issue',
};
let queryResponse = {
@@ -167,7 +165,7 @@ describe('fetchIssueLists', () => {
jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
testAction(
- actions.fetchIssueLists,
+ actions.fetchLists,
{},
state,
[
@@ -185,7 +183,7 @@ describe('fetchIssueLists', () => {
jest.spyOn(gqlClient, 'query').mockResolvedValue(Promise.reject());
testAction(
- actions.fetchIssueLists,
+ actions.fetchLists,
{},
state,
[
@@ -214,7 +212,7 @@ describe('fetchIssueLists', () => {
jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
testAction(
- actions.fetchIssueLists,
+ actions.fetchLists,
{},
state,
[
@@ -227,6 +225,43 @@ describe('fetchIssueLists', () => {
done,
);
});
+
+ it.each`
+ issuableType | boardType | fullBoardId | isGroup | isProject
+ ${issuableTypes.issue} | ${BoardType.group} | ${'gid://gitlab/Board/1'} | ${true} | ${false}
+ ${issuableTypes.issue} | ${BoardType.project} | ${'gid://gitlab/Board/1'} | ${false} | ${true}
+ `(
+ 'calls $issuableType query with correct variables',
+ async ({ issuableType, boardType, fullBoardId, isGroup, isProject }) => {
+ const commit = jest.fn();
+ const dispatch = jest.fn();
+
+ state = {
+ fullPath: 'gitlab-org',
+ fullBoardId,
+ filterParams: {},
+ boardType,
+ issuableType,
+ };
+
+ const variables = {
+ query: listsQuery[issuableType].query,
+ variables: {
+ fullPath: 'gitlab-org',
+ boardId: fullBoardId,
+ filters: {},
+ isGroup,
+ isProject,
+ },
+ };
+
+ jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
+
+ await actions.fetchLists({ commit, state, dispatch });
+
+ expect(gqlClient.query).toHaveBeenCalledWith(variables);
+ },
+ );
});
describe('createList', () => {
@@ -248,7 +283,7 @@ describe('createIssueList', () => {
beforeEach(() => {
state = {
fullPath: 'gitlab-org',
- boardId: '1',
+ fullBoardId: 'gid://gitlab/Board/1',
boardType: 'group',
disabled: false,
boardLists: [{ type: 'closed' }],
@@ -378,7 +413,7 @@ describe('moveList', () => {
const state = {
fullPath: 'gitlab-org',
- boardId: '1',
+ fullBoardId: 'gid://gitlab/Board/1',
boardType: 'group',
disabled: false,
boardLists: initialBoardListsState,
@@ -421,7 +456,7 @@ describe('moveList', () => {
const state = {
fullPath: 'gitlab-org',
- boardId: '1',
+ fullBoardId: 'gid://gitlab/Board/1',
boardType: 'group',
disabled: false,
boardLists: initialBoardListsState,
@@ -455,7 +490,7 @@ describe('updateList', () => {
const state = {
fullPath: 'gitlab-org',
- boardId: '1',
+ fullBoardId: 'gid://gitlab/Board/1',
boardType: 'group',
disabled: false,
boardLists: [{ type: 'closed' }],
@@ -573,7 +608,7 @@ describe('fetchItemsForList', () => {
const state = {
fullPath: 'gitlab-org',
- boardId: '1',
+ fullBoardId: 'gid://gitlab/Board/1',
filterParams: {},
boardType: 'group',
};
@@ -960,7 +995,7 @@ describe('updateIssueOrder', () => {
const state = {
boardItems: issues,
- boardId: 'gid://gitlab/Board/1',
+ fullBoardId: 'gid://gitlab/Board/1',
};
const moveData = {
@@ -974,7 +1009,7 @@ describe('updateIssueOrder', () => {
mutation: issueMoveListMutation,
variables: {
projectPath: getProjectPath(mockIssue.referencePath),
- boardId: fullBoardId(state.boardId),
+ boardId: state.fullBoardId,
iid: mockIssue.iid,
fromListId: 1,
toListId: 2,
diff --git a/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb b/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb
new file mode 100644
index 00000000000..fc0d7710a5e
--- /dev/null
+++ b/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb
@@ -0,0 +1,139 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do
+ let(:project) { build(:project) }
+ let(:user) { project.owner }
+ let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
+
+ subject { described_class.new(context) }
+
+ describe '#render?' do
+ context 'when menu does not have any menu item to show' do
+ it 'returns false' do
+ allow(subject).to receive(:has_items?).and_return(false)
+
+ expect(subject.render?).to eq false
+ end
+ end
+
+ context 'when menu has menu items to show' do
+ it 'returns true' do
+ expect(subject.render?).to eq true
+ end
+ end
+ end
+
+ describe '#link' do
+ let(:registry_enabled) { true }
+ let(:packages_enabled) { true }
+
+ before do
+ stub_container_registry_config(enabled: registry_enabled)
+ stub_config(packages: { enabled: packages_enabled })
+ end
+
+ context 'when Packages Registry is visible' do
+ it 'menu link points to Packages Registry page' do
+ expect(subject.link).to eq described_class.new(context).items.find { |i| i.item_id == :packages_registry }.link
+ end
+ end
+
+ context 'when Packages Registry is not visible' do
+ let(:packages_enabled) { false }
+
+ it 'menu link points to Container Registry page' do
+ expect(subject.link).to eq described_class.new(context).items.find { |i| i.item_id == :container_registry }.link
+ end
+
+ context 'when Container Registry is not visible' do
+ let(:registry_enabled) { false }
+
+ it 'menu link points to Infrastructure Registry page' do
+ expect(subject.link).to eq described_class.new(context).items.find { |i| i.item_id == :infrastructure_registry }.link
+ end
+ end
+ end
+ end
+
+ describe 'Packages Registry' do
+ subject { described_class.new(context).items.find { |i| i.item_id == :packages_registry }}
+
+ context 'when user can read packages' do
+ context 'when config package setting is disabled' do
+ it 'the menu item is not added to list of menu items' do
+ stub_config(packages: { enabled: false })
+
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when config package setting is enabled' do
+ it 'the menu item is added to list of menu items' do
+ stub_config(packages: { enabled: true })
+
+ is_expected.not_to be_nil
+ end
+ end
+ end
+
+ context 'when user cannot read packages' do
+ let(:user) { nil }
+
+ it 'the menu item is not added to list of menu items' do
+ is_expected.to be_nil
+ end
+ end
+ end
+
+ describe 'Container Registry' do
+ subject { described_class.new(context).items.find { |i| i.item_id == :container_registry }}
+
+ context 'when user can read container images' do
+ context 'when config registry setting is disabled' do
+ it 'the menu item is not added to list of menu items' do
+ stub_container_registry_config(enabled: false)
+
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when config registry setting is enabled' do
+ it 'the menu item is added to list of menu items' do
+ stub_container_registry_config(enabled: true)
+
+ is_expected.not_to be_nil
+ end
+ end
+ end
+
+ context 'when user cannot read container images' do
+ let(:user) { nil }
+
+ it 'the menu item is not added to list of menu items' do
+ is_expected.to be_nil
+ end
+ end
+ end
+
+ describe 'Infrastructure Registry' do
+ subject { described_class.new(context).items.find { |i| i.item_id == :infrastructure_registry }}
+
+ context 'when feature flag :infrastructure_registry_page is enabled' do
+ it 'the menu item is added to list of menu items' do
+ stub_feature_flags(infrastructure_registry_page: true)
+
+ is_expected.not_to be_nil
+ end
+ end
+
+ context 'when feature flag :infrastructure_registry_page is disabled' do
+ it 'the menu item is not added to list of menu items' do
+ stub_feature_flags(infrastructure_registry_page: false)
+
+ is_expected.to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb
index 6bec176b39b..5d106f08402 100644
--- a/spec/tooling/danger/project_helper_spec.rb
+++ b/spec/tooling/danger/project_helper_spec.rb
@@ -220,7 +220,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
describe '.local_warning_message' do
it 'returns an informational message with rules that can run' do
- expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, commit_messages, database, datateam, documentation, duplicate_yarn_dependencies, eslint, karma, pajamas, pipeline, prettier, product_intelligence, utility_css')
+ expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, changes_size, commit_messages, database, datateam, documentation, duplicate_yarn_dependencies, eslint, karma, pajamas, pipeline, prettier, product_intelligence, utility_css')
end
end
diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
index f83a515fb23..b86164a6639 100644
--- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
+++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
@@ -580,78 +580,72 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
- describe 'packages tab' do
- before do
- stub_container_registry_config(enabled: true)
+ describe 'Packages and Registries' do
+ let(:registry_enabled) { true }
+ let(:packages_enabled) { true }
- allow(controller).to receive(:controller_name)
- .and_return('repositories')
- allow(controller).to receive(:controller_path)
- .and_return('projects/registry/repositories')
+ before do
+ stub_container_registry_config(enabled: registry_enabled)
+ stub_config(packages: { enabled: packages_enabled })
end
- it 'highlights sidebar item and flyout' do
+ it 'top level navigation link is visible and points to package registry page' do
render
- expect(rendered).to have_css('.sidebar-top-level-items > li.active', count: 1)
- expect(rendered).to have_css('.sidebar-sub-level-items > li.fly-out-top-item.active', count: 1)
+ expect(rendered).to have_link('Packages & Registries', href: project_packages_path(project))
end
- it 'highlights container registry tab' do
- render
+ describe 'Packages Registry' do
+ it 'shows link to package registry page' do
+ render
- expect(rendered).to have_css('.sidebar-sub-level-items > li:not(.fly-out-top-item).active', text: 'Container Registry')
- end
- end
+ expect(rendered).to have_link('Package Registry', href: project_packages_path(project))
+ end
- describe 'Packages' do
- let_it_be(:user) { create(:user) }
+ context 'when packages config setting is not enabled' do
+ let(:packages_enabled) { false }
- let_it_be(:package_menu_name) { 'Packages & Registries' }
- let_it_be(:package_entry_name) { 'Package Registry' }
+ it 'does not show link to package registry page' do
+ render
- before do
- project.team.add_developer(user)
- sign_in(user)
- stub_container_registry_config(enabled: true)
+ expect(rendered).not_to have_link('Package Registry', href: project_packages_path(project))
+ end
+ end
end
- context 'when packages is enabled' do
- it 'packages link is visible' do
+ describe 'Container Registry' do
+ it 'shows link to container registry page' do
render
- expect(rendered).to have_link(package_menu_name, href: project_packages_path(project))
+ expect(rendered).to have_link('Container Registry', href: project_container_registry_index_path(project))
end
- it 'packages list link is visible' do
- render
-
- expect(rendered).to have_link(package_entry_name, href: project_packages_path(project))
- end
+ context 'when container config setting is not enabled' do
+ let(:registry_enabled) { false }
- it 'container registry link is visible' do
- render
+ it 'does not show link to package registry page' do
+ render
- expect(rendered).to have_link('Container Registry', href: project_container_registry_index_path(project))
+ expect(rendered).not_to have_link('Container Registry', href: project_container_registry_index_path(project))
+ end
end
end
- context 'when container registry is disabled' do
- before do
- stub_container_registry_config(enabled: false)
- end
-
- it 'packages top level and list link are visible' do
+ describe 'Infrastructure Registry' do
+ it 'shows link to infrastructure registry page' do
render
- expect(rendered).to have_link(package_menu_name, href: project_packages_path(project))
- expect(rendered).to have_link(package_entry_name, href: project_packages_path(project))
+ expect(rendered).to have_link('Infrastructure Registry', href: project_infrastructure_registry_index_path(project))
end
- it 'container registry link is not visible' do
- render
+ context 'when feature flag :infrastructure_registry_page is disabled' do
+ it 'does not show link to package registry page' do
+ stub_feature_flags(infrastructure_registry_page: false)
- expect(rendered).not_to have_link('Container Registry', href: project_container_registry_index_path(project))
+ render
+
+ expect(rendered).not_to have_link('Infrastructure Registry', href: project_infrastructure_registry_index_path(project))
+ end
end
end
end
diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb
index b60a3aa1adc..7aac0de0b6b 100644
--- a/tooling/danger/project_helper.rb
+++ b/tooling/danger/project_helper.rb
@@ -5,6 +5,7 @@ module Tooling
module ProjectHelper
LOCAL_RULES ||= %w[
changelog
+ changes_size
commit_messages
database
datateam
@@ -175,12 +176,26 @@ module Tooling
ee? ? 'gitlab' : 'gitlab-foss'
end
+ def missing_database_labels(current_mr_labels)
+ labels = if has_database_scoped_labels?(current_mr_labels)
+ ['database']
+ else
+ ['database', 'database::review pending']
+ end
+
+ labels - current_mr_labels
+ end
+
private
def ee?
# Support former project name for `dev` and support local Danger run
%w[gitlab gitlab-ee].include?(ENV['CI_PROJECT_NAME']) || Dir.exist?(File.expand_path('../../../ee', __dir__))
end
+
+ def has_database_scoped_labels?(current_mr_labels)
+ current_mr_labels.any? { |label| label.start_with?('database::') }
+ end
end
end
end