Commit d196ad3f authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets Committed by Filipa Lacerda

Add group packages page

Also move Dependency Proxy under Packages tab
Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parent e9056678
......@@ -45,7 +45,6 @@
= _('Contribution Analytics')
= render_if_exists 'layouts/nav/group_insights_link'
= render_if_exists 'groups/sidebar/dependency_proxy' # EE-specific
= render_if_exists "layouts/nav/ee/epic_link", group: @group
......@@ -119,6 +118,8 @@
%strong.fly-out-top-item-name
= _('Kubernetes')
= render_if_exists 'groups/sidebar/packages' # EE-specific
- if group_sidebar_link?(:group_members)
= nav_link(path: 'group_members#index') do
= link_to group_group_members_path(@group) do
......
......@@ -11,8 +11,7 @@ module DependencyProxyAccess
private
def verify_dependency_proxy_enabled!
render_404 unless Gitlab.config.dependency_proxy.enabled &&
group.feature_available?(:dependency_proxy)
render_404 unless group.dependency_proxy_feature_available?
end
def authorize_read_dependency_proxy!
......
# frozen_string_literal: true
module Groups
class PackagesController < Groups::ApplicationController
before_action :verify_packages_enabled!
def index
@packages = ::Packages::GroupPackagesFinder.new(current_user, group)
.execute
.page(params[:page])
end
private
def verify_packages_enabled!
render_404 unless group.packages_feature_available?
end
end
end
# frozen_string_literal: true
module Packages
class GroupPackagesFinder
attr_reader :current_user, :group
def initialize(current_user, group)
@current_user = current_user
@group = group
end
def execute
return ::Packages::Package.none unless group
packages_for_group_projects
end
private
def packages_for_group_projects
::Packages::Package.for_projects(group_projects_visible_to_current_user)
end
def group_projects_visible_to_current_user
::Project
.in_namespace(group.self_and_descendants.select(:id))
.public_or_visible_to_user(current_user, Gitlab::Access::REPORTER)
end
end
end
......@@ -9,7 +9,6 @@ module EE
super + %w[
groups/security/dashboard#show
groups/insights#show
groups/dependency_proxies#show
]
end
......@@ -28,6 +27,26 @@ module EE
"Repositories within this group #{show_lfs} will be restricted to this maximum size. Can be overridden inside each project. 0 for unlimited. Leave empty to inherit the global value."
end
def group_packages_nav_link_paths
%w[
groups/packages#index
groups/dependency_proxies#show
]
end
def group_packages_nav?
group_packages_list_nav? ||
group_dependency_proxy_nav?
end
def group_packages_list_nav?
@group.packages_feature_available?
end
def group_dependency_proxy_nav?
@group.dependency_proxy_feature_available?
end
private
def get_group_sidebar_links
......
......@@ -219,6 +219,14 @@ module EE
end
end
def packages_feature_available?
::Gitlab.config.packages.enabled && feature_available?(:packages)
end
def dependency_proxy_feature_available?
::Gitlab.config.dependency_proxy.enabled && feature_available?(:dependency_proxy)
end
private
def custom_project_templates_group_allowed
......
- page_title _("Packages")
- if @packages.any?
.table-holder
.gl-responsive-table-row.table-row-header{ role: 'row' }
.table-section.section-30{ role: 'rowheader' }
= _('Name')
.table-section.section-20{ role: 'rowheader' }
= _('Project')
.table-section.section-20{ role: 'rowheader' }
= _('Version')
.table-section.section-10{ role: 'rowheader' }
= _('Type')
.table-section.section-20{ role: 'rowheader' }
= _('Created')
- @packages.each do |package|
.gl-responsive-table-row
.table-section.section-30
.table-mobile-header{ role: "rowheader" }= _("Name")
.table-mobile-content.flex-truncate-parent
= link_to package.name, project_package_path(package.project, package), class: 'flex-truncate-child'
.table-section.section-20
.table-mobile-header{ role: "rowheader" }= _("Project")
.table-mobile-content
= link_to_project(package.project)
.table-section.section-20
.table-mobile-header{ role: "rowheader" }= _("Version")
.table-mobile-content
= package.version
.table-section.section-10
.table-mobile-header{ role: "rowheader" }= _("Type")
.table-mobile-content
= package.package_type
.table-section.section-20
.table-mobile-header{ role: "rowheader" }= _("Created")
.table-mobile-content
= time_ago_with_tooltip(package.created_at)
= paginate @packages, theme: "gitlab"
- else
.row.empty-state
.col-12
= render 'shared/packages/no_packages'
- if Gitlab.config.dependency_proxy.enabled && @group.feature_available?(:dependency_proxy)
= nav_link(controller: 'groups/dependency_proxies') do
= link_to group_dependency_proxy_path(@group), title: _('Dependency Proxy') do
%span= _('Dependency Proxy')
- if group_packages_nav?
= nav_link(path: group_packages_nav_link_paths) do
= link_to group_packages_path(@group) do
.nav-icon-container
= sprite_icon('package')
%span.nav-item-name.qa-group-settings-item
= _('Packages')
%ul.sidebar-sub-level-items
- if group_packages_list_nav?
= nav_link(controller: 'groups/packages') do
= link_to group_packages_path(@group), title: _('Packages') do
%span= _('List')
- if group_dependency_proxy_nav?
= nav_link(controller: 'groups/dependency_proxies') do
= link_to group_dependency_proxy_path(@group), title: _('Dependency Proxy') do
%span= _('Dependency Proxy')
......@@ -42,10 +42,4 @@
- else
.row.empty-state
.col-12
.svg-content= image_tag 'illustrations/no-packages.svg'
.text-content
%h4.text-center= _('There are no packages yet')
%p
- no_packages_url = help_page_path('administration/packages.html')
- no_packages_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: no_packages_url }
= _('Learn how to %{no_packages_link_start}publish and share your packages%{no_packages_link_end} with GitLab.').html_safe % { no_packages_link_start: no_packages_link_start, no_packages_link_end: '</a>'.html_safe }
= render 'shared/packages/no_packages'
.svg-content= image_tag 'illustrations/no-packages.svg'
.text-content
%h4.text-center= _('There are no packages yet')
%p
- no_packages_url = help_page_path('administration/packages.html')
- no_packages_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: no_packages_url }
= _('Learn how to %{no_packages_link_start}publish and share your packages%{no_packages_link_end} with GitLab.').html_safe % { no_packages_link_start: no_packages_link_start, no_packages_link_end: '</a>'.html_safe }
---
title: Add group packages page
merge_request: 14089
author:
type: added
......@@ -111,6 +111,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
get 'boards(/*extra_params)', as: :legacy_ee_group_boards_redirect, to: legacy_ee_group_boards_redirect
resource :dependency_proxy, only: [:show, :update]
resources :packages, only: [:index]
end
scope(path: 'groups/*group_id') do
......
# frozen_string_literal: true
class Gitlab::Seeder::Packages
def initialize(user, project)
@user = user
@project = project
end
def seed
5.times do |i|
package_name = "@#{@project.full_path}"
version = "1.12.#{i}"
params = JSON.parse(
fixture_json
.gsub('@root/npm-test', package_name)
.gsub('1.0.1', version))
.with_indifferent_access
Packages::CreateNpmPackageService.new(@project, @user, params).execute
end
end
private
def fixture_json
File.read(fixture_path)
end
def fixture_path
Rails.root.join('ee', 'spec', 'fixtures', 'npm', 'payload.json')
end
end
Gitlab::Seeder.quiet do
Project.all.sample(5).each do |project|
Gitlab::Seeder::Packages.new(project.owner, project).seed
end
end
# frozen_string_literal: true
require 'spec_helper'
describe 'Group Packages' do
set(:user) { create(:user) }
set(:group) { create(:group) }
set(:project) { create(:project, group: group) }
before do
sign_in(user)
group.add_maintainer(user)
stub_licensed_features(packages: true)
end
context 'packages feature is not available because of license' do
before do
stub_licensed_features(packages: false)
end
it 'gives 404' do
visit_group_packages
expect(page).to have_gitlab_http_status(404)
end
end
context 'packages feature is disabled by config' do
before do
allow(Gitlab.config.packages).to receive(:enabled).and_return(false)
end
it 'gives 404' do
visit_group_packages
expect(page).to have_gitlab_http_status(404)
end
end
context 'when there are no packages' do
it 'shows no packages message' do
visit_group_packages
expect(page).to have_content 'There are no packages yet'
end
end
context 'when there are packages' do
let!(:package) { create(:maven_package, project: project) }
it 'shows list of packages' do
visit_group_packages
expect(page).to have_content(package.name)
expect(page).to have_content(package.version)
end
end
def visit_group_packages
visit group_packages_path(group)
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Packages::GroupPackagesFinder do
set(:user) { create(:user) }
set(:group) { create(:group) }
set(:project) { create(:project, namespace: group) }
set(:package1) { create(:maven_package, project: project) }
set(:package2) { create(:maven_package, project: project) }
set(:package3) { create(:maven_package) }
set(:another_group) { create(:group) }
before do
group.add_developer(user)
end
describe '#execute' do
context 'group has packages' do
it 'returns group packages' do
finder = described_class.new(user, group)
expect(finder.execute).to match_array([package1, package2])
end
end
context 'group has no packages' do
it 'returns an empty collection' do
finder = described_class.new(user, another_group)
expect(finder.execute).to be_empty
end
end
context 'group is nil' do
it 'returns an empty collection' do
finder = described_class.new(user, nil)
expect(finder.execute).to be_empty
end
end
end
end
{
"_id":"@root/npm-test",
"name":"@root/npm-test",
"description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"dist-tags":{
"latest":"1.0.1"
},
"versions":{
"1.0.1":{
"name":"@root/npm-test",
"version":"1.0.1",
"main":"app.js",
"dependencies":{
"express":"^4.16.4"
},
"dist":{
"shasum":"f572d396fae9206628714fb2ce00f72e94f2258f"
}
}
},
"_attachments":{
"@root/npm-test-1.0.1.tgz":{
"content_type":"application/octet-stream",
"data":"aGVsbG8K",
"length":8
}
},
"id":"10",
"package_name":"@root/npm-test"
}
......@@ -194,22 +194,9 @@ describe API::NpmPackages do
end
def upload_params(package_name)
{
name: package_name,
versions: {
'1.0.1' => {
dist: {
shasum: 'f572d396fae9206628714fb2ce00f72e94f2258f'
}
}
},
'_attachments' => {
"#{package_name}-1.0.1.tgz" => {
'data' => 'aGVsbG8K',
'length' => 8
}
}
}
JSON.parse(
fixture_file('npm/payload.json', dir: 'ee')
.gsub('@root/npm-test', package_name))
end
end
......
......@@ -110,4 +110,12 @@ describe 'Group routing', "routing" do
end
end
end
describe 'packages' do
it 'routes to packages index page' do
allow(Group).to receive(:find_by_full_path).with('gitlabhq', any_args).and_return(true)
expect(get('/groups/gitlabhq/-/packages')).to route_to('groups/packages#index', group_id: 'gitlabhq')
end
end
end
......@@ -7,23 +7,11 @@ describe Packages::CreateNpmPackageService do
let(:version) { '1.0.1'.freeze }
let(:params) do
{
name: package_name,
versions: {
version => {
dist: {
shasum: 'f572d396fae9206628714fb2ce00f72e94f2258f'
}
}
},
'_attachments' => {
"#{package_name}-#{version}.tgz" => {
'content_type' => 'application/octet-stream',
'data' => 'aGVsbG8K',
'length' => 8
}
}
}
JSON.parse(
fixture_file('npm/payload.json', dir: 'ee')
.gsub('@root/npm-test', package_name)
.gsub('1.0.1', version))
.with_indifferent_access
end
shared_examples 'valid package' do
......
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