Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
2494b608a4
commit
aa542224bb
|
|
@ -1,5 +1,12 @@
|
|||
Please view this file on the master branch, on stable branches it's out of date.
|
||||
|
||||
## 12.4.2
|
||||
|
||||
### Fixed (1 change)
|
||||
|
||||
- Fix feature flag check for productivity analytics. !19025
|
||||
|
||||
|
||||
## 12.4.1
|
||||
|
||||
### Security (6 changes)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable func-names, consistent-return, camelcase, class-methods-use-this */
|
||||
/* eslint-disable consistent-return, camelcase, class-methods-use-this */
|
||||
|
||||
// Zen Mode (full screen) textarea
|
||||
//
|
||||
|
|
@ -47,26 +47,16 @@ export default class ZenMode {
|
|||
e.preventDefault();
|
||||
return $(e.currentTarget).trigger('zen_mode:leave');
|
||||
});
|
||||
$(document).on(
|
||||
'zen_mode:enter',
|
||||
(function(_this) {
|
||||
return function(e) {
|
||||
return _this.enter(
|
||||
$(e.target)
|
||||
.closest('.md-area')
|
||||
.find('.zen-backdrop'),
|
||||
);
|
||||
};
|
||||
})(this),
|
||||
);
|
||||
$(document).on(
|
||||
'zen_mode:leave',
|
||||
(function(_this) {
|
||||
return function() {
|
||||
return _this.exit();
|
||||
};
|
||||
})(this),
|
||||
);
|
||||
$(document).on('zen_mode:enter', e => {
|
||||
this.enter(
|
||||
$(e.target)
|
||||
.closest('.md-area')
|
||||
.find('.zen-backdrop'),
|
||||
);
|
||||
});
|
||||
$(document).on('zen_mode:leave', () => {
|
||||
this.exit();
|
||||
});
|
||||
$(document).on('keydown', e => {
|
||||
// Esc
|
||||
if (e.keyCode === 27) {
|
||||
|
|
|
|||
|
|
@ -99,3 +99,13 @@
|
|||
color: $gl-text-color-disabled;
|
||||
}
|
||||
}
|
||||
|
||||
.group-variable-list {
|
||||
color: $gray-700;
|
||||
|
||||
.table-section:not(:first-child) {
|
||||
@include media-breakpoint-down(sm) {
|
||||
border-top: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ $status-box-line-height: 26px;
|
|||
margin-bottom: $gl-padding-4;
|
||||
}
|
||||
|
||||
.milestone-progress {
|
||||
.milestone-progress,
|
||||
.milestone-release-links {
|
||||
a {
|
||||
color: $blue-600;
|
||||
}
|
||||
|
|
@ -238,10 +239,6 @@ $status-box-line-height: 26px;
|
|||
}
|
||||
}
|
||||
|
||||
.milestone-range {
|
||||
color: $gl-text-color-tertiary;
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
.milestone-banner-text,
|
||||
.milestone-banner-link {
|
||||
|
|
|
|||
|
|
@ -1,34 +1,38 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ContainerRepositoriesFinder
|
||||
# id: group or project id
|
||||
# container_type: :group or :project
|
||||
def initialize(id:, container_type:)
|
||||
@id = id
|
||||
@type = container_type.to_sym
|
||||
VALID_SUBJECTS = [Group, Project].freeze
|
||||
|
||||
def initialize(user:, subject:)
|
||||
@user = user
|
||||
@subject = subject
|
||||
end
|
||||
|
||||
def execute
|
||||
if project_type?
|
||||
project.container_repositories
|
||||
else
|
||||
group.container_repositories
|
||||
end
|
||||
raise ArgumentError, "invalid subject_type" unless valid_subject_type?
|
||||
return unless authorized?
|
||||
|
||||
return project_repositories if @subject.is_a?(Project)
|
||||
return group_repositories if @subject.is_a?(Group)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :id, :type
|
||||
|
||||
def project_type?
|
||||
type == :project
|
||||
def valid_subject_type?
|
||||
VALID_SUBJECTS.include?(@subject.class)
|
||||
end
|
||||
|
||||
def project
|
||||
Project.find(id)
|
||||
def project_repositories
|
||||
return unless @subject.container_registry_enabled
|
||||
|
||||
@subject.container_repositories
|
||||
end
|
||||
|
||||
def group
|
||||
Group.find(id)
|
||||
def group_repositories
|
||||
ContainerRepository.for_group_and_its_subgroups(@subject)
|
||||
end
|
||||
|
||||
def authorized?
|
||||
Ability.allowed?(@user, :read_container_image, @subject)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -170,6 +170,15 @@ module MilestonesHelper
|
|||
content.join('<br />').html_safe
|
||||
end
|
||||
|
||||
def recent_releases_with_counts(milestone)
|
||||
total_count = milestone.releases.size
|
||||
return [[], 0, 0] if total_count == 0
|
||||
|
||||
recent_releases = milestone.releases.recent.to_a
|
||||
more_count = total_count - recent_releases.size
|
||||
[recent_releases, total_count, more_count]
|
||||
end
|
||||
|
||||
def milestone_tooltip_due_date(milestone)
|
||||
if milestone.due_date
|
||||
"#{milestone.due_date.to_s(:medium)} (#{remaining_days_in_words(milestone.due_date, milestone.start_date)})"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ class ContainerRepository < ApplicationRecord
|
|||
|
||||
scope :ordered, -> { order(:name) }
|
||||
scope :with_api_entity_associations, -> { preload(project: [:route, { namespace: :route }]) }
|
||||
scope :for_group_and_its_subgroups, ->(group) do
|
||||
where(project_id: Project.for_group_and_its_subgroups(group).with_container_registry.select(:id))
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ServiceClass
|
||||
def registry
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class GlobalMilestone
|
|||
|
||||
delegate :title, :state, :due_date, :start_date, :participants, :project,
|
||||
:group, :expires_at, :closed?, :iid, :group_milestone?, :safe_title,
|
||||
:milestoneish_id, :resource_parent, to: :milestone
|
||||
:milestoneish_id, :resource_parent, :releases, to: :milestone
|
||||
|
||||
def to_hash
|
||||
{
|
||||
|
|
|
|||
|
|
@ -395,6 +395,7 @@ class Project < ApplicationRecord
|
|||
scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') }
|
||||
scope :with_statistics, -> { includes(:statistics) }
|
||||
scope :with_shared_runners, -> { where(shared_runners_enabled: true) }
|
||||
scope :with_container_registry, -> { where(container_registry_enabled: true) }
|
||||
scope :inside_path, ->(path) do
|
||||
# We need routes alias rs for JOIN so it does not conflict with
|
||||
# includes(:route) which we use in ProjectsFinder.
|
||||
|
|
|
|||
|
|
@ -28,12 +28,16 @@ class Release < ApplicationRecord
|
|||
|
||||
scope :sorted, -> { order(released_at: :desc) }
|
||||
scope :preloaded, -> { includes(project: :namespace) }
|
||||
scope :with_project_and_namespace, -> { includes(project: :namespace) }
|
||||
scope :recent, -> { sorted.limit(MAX_NUMBER_TO_DISPLAY) }
|
||||
|
||||
delegate :repository, to: :project
|
||||
|
||||
after_commit :create_evidence!, on: :create
|
||||
after_commit :notify_new_release, on: :create
|
||||
|
||||
MAX_NUMBER_TO_DISPLAY = 3
|
||||
|
||||
def to_param
|
||||
CGI.escape(tag)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
= _("These variables are configured in the parent group settings, and will be active in the current project in addition to the project variables.")
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
%h5
|
||||
= _('Group variables (inherited)')
|
||||
|
||||
%p
|
||||
= render "ci/group_variables/content"
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
- variables = @project.group.self_and_ancestors.map(&:variables).flatten
|
||||
|
||||
.row
|
||||
.col-lg-12
|
||||
.group-variable-list
|
||||
= render 'ci/group_variables/variable_header'
|
||||
- variables.each do |variable|
|
||||
.group-variable-row.d-flex.w-100.border-bottom.pt-2.pb-2
|
||||
.table-section.section-40.append-right-10.key
|
||||
= variable.key
|
||||
.table-section.section-40.append-right-10
|
||||
%a.group-origin-link{ href: group_settings_ci_cd_path(variable.group) }
|
||||
= variable.group.name
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
.group-variable-keys.d-flex.w-100.align-items-center.pb-2.border-bottom
|
||||
.bold.table-section.section-40.append-right-10
|
||||
= s_('Key')
|
||||
.bold.table-section.section-40.append-right-10
|
||||
= s_('Origin')
|
||||
|
|
@ -24,3 +24,8 @@
|
|||
= n_('Hide value', 'Hide values', @variables.size)
|
||||
- else
|
||||
= n_('Reveal value', 'Reveal values', @variables.size)
|
||||
- if !@group && @project.group
|
||||
.settings-header.border-top.prepend-top-20
|
||||
= render 'ci/group_variables/header'
|
||||
.settings-content.pr-0
|
||||
= render 'ci/group_variables/index'
|
||||
|
|
|
|||
|
|
@ -12,8 +12,20 @@
|
|||
|
||||
- if @project || milestone.is_a?(GlobalMilestone) || milestone.group_milestone?
|
||||
- if milestone.due_date || milestone.start_date
|
||||
.milestone-range.append-bottom-5
|
||||
.text-tertiary.append-bottom-5
|
||||
= milestone_date_range(milestone)
|
||||
- recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
|
||||
- unless total_count.zero?
|
||||
.text-tertiary.append-bottom-5.milestone-release-links
|
||||
= icon('rocket')
|
||||
= n_('Release', 'Releases', total_count)
|
||||
- recent_releases.each do |release|
|
||||
= link_to release.name, project_releases_path(release.project, anchor: release.tag)
|
||||
- unless release == recent_releases.last
|
||||
•
|
||||
- if total_count > recent_releases.count
|
||||
•
|
||||
= link_to n_('%{count} more release', '%{count} more releases', more_count) % { count: more_count }, project_releases_path(milestone.project)
|
||||
%div
|
||||
= render('shared/milestone_expired', milestone: milestone)
|
||||
- if milestone.group_milestone?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Show inherited group variables in project view
|
||||
merge_request: 18759
|
||||
author:
|
||||
type: added
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add links to associated releases on the Milestones page
|
||||
merge_request: 16558
|
||||
author:
|
||||
type: added
|
||||
|
|
@ -467,6 +467,13 @@ production: &base
|
|||
# enabled: true
|
||||
# primary_api_url: http://localhost:5000/ # internal address to the primary registry, will be used by GitLab to directly communicate with primary registry API
|
||||
|
||||
## Feature Flag https://docs.gitlab.com/ee/user/project/operations/feature_flags.html
|
||||
feature_flags:
|
||||
unleash:
|
||||
# enabled: false
|
||||
# url: https://gitlab.com/api/v4/feature_flags/unleash/<project_id>
|
||||
# app_name: gitlab.com # Environment name of your GitLab instance
|
||||
# instance_id: INSTANCE_ID
|
||||
|
||||
#
|
||||
# 2. GitLab CI settings
|
||||
|
|
|
|||
|
|
@ -308,6 +308,13 @@ Gitlab.ee do
|
|||
Settings.geo.registry_replication['enabled'] ||= false
|
||||
end
|
||||
|
||||
#
|
||||
# Unleash
|
||||
#
|
||||
Settings['feature_flags'] ||= Settingslogic.new({})
|
||||
Settings.feature_flags['unleash'] ||= Settingslogic.new({})
|
||||
Settings.feature_flags.unleash['enabled'] = false if Settings.feature_flags.unleash['enabled'].nil?
|
||||
|
||||
#
|
||||
# External merge request diffs
|
||||
#
|
||||
|
|
|
|||
|
|
@ -357,7 +357,12 @@ Group-level variables can be added by:
|
|||
1. Inputing variable types, keys, and values in the **Variables** section.
|
||||
Any variables of [subgroups](../../user/group/subgroups/index.md) will be inherited recursively.
|
||||
|
||||
Once you set them, they will be available for all subsequent pipelines.
|
||||
Once you set them, they will be available for all subsequent pipelines. Any group-level user defined variables can be viewed in projects by:
|
||||
|
||||
1. Navigating to the project's **Settings > CI/CD** page.
|
||||
1. Expanding the **Variables** section.
|
||||
|
||||

|
||||
|
||||
## Priority of environment variables
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
|
|
@ -23,7 +23,7 @@ module API
|
|||
end
|
||||
get ':id/registry/repositories' do
|
||||
repositories = ContainerRepositoriesFinder.new(
|
||||
id: user_group.id, container_type: :group
|
||||
user: current_user, subject: user_group
|
||||
).execute
|
||||
|
||||
present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ module API
|
|||
end
|
||||
get ':id/registry/repositories' do
|
||||
repositories = ContainerRepositoriesFinder.new(
|
||||
id: user_project.id, container_type: :project
|
||||
user: current_user, subject: user_project
|
||||
).execute
|
||||
|
||||
present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags]
|
||||
|
|
|
|||
|
|
@ -210,6 +210,11 @@ msgstr ""
|
|||
msgid "%{count} more assignees"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{count} more release"
|
||||
msgid_plural "%{count} more releases"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "%{count} of %{required} approvals from %{name}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -8336,6 +8341,9 @@ msgstr ""
|
|||
msgid "Group pipeline minutes were successfully reset."
|
||||
msgstr ""
|
||||
|
||||
msgid "Group variables (inherited)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Group was successfully updated."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9537,6 +9545,9 @@ msgstr ""
|
|||
msgid "June"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key (PEM)"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -11601,6 +11612,9 @@ msgstr ""
|
|||
msgid "Or you can choose one of the suggested colors below"
|
||||
msgstr ""
|
||||
|
||||
msgid "Origin"
|
||||
msgstr ""
|
||||
|
||||
msgid "Other Labels"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13794,7 +13808,9 @@ msgid "Related merge requests"
|
|||
msgstr ""
|
||||
|
||||
msgid "Release"
|
||||
msgstr ""
|
||||
msgid_plural "Releases"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Release notes"
|
||||
msgstr ""
|
||||
|
|
@ -16933,6 +16949,9 @@ msgstr ""
|
|||
msgid "These existing issues have a similar title. It might be better to comment there instead of creating another similar issue."
|
||||
msgstr ""
|
||||
|
||||
msgid "These variables are configured in the parent group settings, and will be active in the current project in addition to the project variables."
|
||||
msgstr ""
|
||||
|
||||
msgid "They can be managed using the %{link}."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -34,4 +34,31 @@ describe "User views milestones" do
|
|||
.and have_content(closed_issue.title)
|
||||
end
|
||||
end
|
||||
|
||||
context "with associated releases" do
|
||||
set(:first_release) { create(:release, project: project, name: "The first release", milestones: [milestone], released_at: Time.zone.parse('2019-10-07')) }
|
||||
|
||||
context "with a single associated release" do
|
||||
it "shows the associated release" do
|
||||
expect(page).to have_content("Release #{first_release.name}")
|
||||
expect(page).to have_link(first_release.name, href: project_releases_path(project, anchor: first_release.tag))
|
||||
end
|
||||
end
|
||||
|
||||
context "with lots of associated releases" do
|
||||
set(:second_release) { create(:release, project: project, name: "The second release", milestones: [milestone], released_at: first_release.released_at + 1.day) }
|
||||
set(:third_release) { create(:release, project: project, name: "The third release", milestones: [milestone], released_at: second_release.released_at + 1.day) }
|
||||
set(:fourth_release) { create(:release, project: project, name: "The fourth release", milestones: [milestone], released_at: third_release.released_at + 1.day) }
|
||||
set(:fifth_release) { create(:release, project: project, name: "The fifth release", milestones: [milestone], released_at: fourth_release.released_at + 1.day) }
|
||||
|
||||
it "shows the associated releases and the truncation text" do
|
||||
expect(page).to have_content("Releases #{fifth_release.name} • #{fourth_release.name} • #{third_release.name} • 2 more releases")
|
||||
|
||||
expect(page).to have_link(fifth_release.name, href: project_releases_path(project, anchor: fifth_release.tag))
|
||||
expect(page).to have_link(fourth_release.name, href: project_releases_path(project, anchor: fourth_release.tag))
|
||||
expect(page).to have_link(third_release.name, href: project_releases_path(project, anchor: third_release.tag))
|
||||
expect(page).to have_link("2 more releases", href: project_releases_path(project))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'Project group variables', :js do
|
||||
let(:user) { create(:user) }
|
||||
let(:group) { create(:group) }
|
||||
let(:subgroup) { create(:group, parent: group) }
|
||||
let(:subgroup_nested) { create(:group, parent: subgroup) }
|
||||
let(:project) { create(:project, group: group) }
|
||||
let(:project2) { create(:project, group: subgroup) }
|
||||
let(:project3) { create(:project, group: subgroup_nested) }
|
||||
let(:key1) { 'test_key' }
|
||||
let(:key2) { 'test_key2' }
|
||||
let(:key3) { 'test_key3' }
|
||||
let!(:ci_variable) { create(:ci_group_variable, group: group, key: key1) }
|
||||
let!(:ci_variable2) { create(:ci_group_variable, group: subgroup, key: key2) }
|
||||
let!(:ci_variable3) { create(:ci_group_variable, group: subgroup_nested, key: key3) }
|
||||
let(:project_path) { project_settings_ci_cd_path(project) }
|
||||
let(:project2_path) { project_settings_ci_cd_path(project2) }
|
||||
let(:project3_path) { project_settings_ci_cd_path(project3) }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
project.add_maintainer(user)
|
||||
group.add_owner(user)
|
||||
end
|
||||
|
||||
it 'project in group shows inherited vars from ancestor group' do
|
||||
visit project_path
|
||||
expect(page).to have_content(key1)
|
||||
expect(page).to have_content(group.name)
|
||||
end
|
||||
|
||||
it 'project in subgroup shows inherited vars from all ancestor groups' do
|
||||
visit project2_path
|
||||
expect(page).to have_content(key1)
|
||||
expect(page).to have_content(key2)
|
||||
expect(page).to have_content(group.name)
|
||||
expect(page).to have_content(subgroup.name)
|
||||
end
|
||||
|
||||
it 'project in nested subgroup shows inherited vars from all ancestor groups' do
|
||||
visit project3_path
|
||||
expect(page).to have_content(key1)
|
||||
expect(page).to have_content(key2)
|
||||
expect(page).to have_content(key3)
|
||||
expect(page).to have_content(group.name)
|
||||
expect(page).to have_content(subgroup.name)
|
||||
expect(page).to have_content(subgroup_nested.name)
|
||||
end
|
||||
|
||||
it 'project origin keys link to ancestor groups ci_cd settings' do
|
||||
visit project_path
|
||||
find('.group-origin-link').click
|
||||
page.within('.js-ci-variable-list-section .js-row:nth-child(2)') do
|
||||
expect(find('.js-ci-variable-input-key').value).to eq(key1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,42 +3,50 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ContainerRepositoriesFinder do
|
||||
let_it_be(:reporter) { create(:user) }
|
||||
let_it_be(:guest) { create(:user) }
|
||||
|
||||
let(:group) { create(:group) }
|
||||
let(:project) { create(:project, group: group) }
|
||||
let(:project_repository) { create(:container_repository, project: project) }
|
||||
|
||||
before do
|
||||
group.add_reporter(reporter)
|
||||
project.add_reporter(reporter)
|
||||
end
|
||||
|
||||
describe '#execute' do
|
||||
let(:id) { nil }
|
||||
context 'with authorized user' do
|
||||
subject { described_class.new(user: reporter, subject: subject_object).execute }
|
||||
|
||||
subject { described_class.new(id: id, container_type: container_type).execute }
|
||||
context 'when subject_type is group' do
|
||||
let(:subject_object) { group }
|
||||
let(:other_project) { create(:project, group: group) }
|
||||
|
||||
context 'when container_type is group' do
|
||||
let(:other_project) { create(:project, group: group) }
|
||||
let(:other_repository) do
|
||||
create(:container_repository, name: 'test_repository2', project: other_project)
|
||||
end
|
||||
|
||||
let(:other_repository) do
|
||||
create(:container_repository, name: 'test_repository2', project: other_project)
|
||||
it { is_expected.to match_array([project_repository, other_repository]) }
|
||||
end
|
||||
|
||||
let(:container_type) { :group }
|
||||
let(:id) { group.id }
|
||||
context 'when subject_type is project' do
|
||||
let(:subject_object) { project }
|
||||
|
||||
it { is_expected.to match_array([project_repository, other_repository]) }
|
||||
end
|
||||
|
||||
context 'when container_type is project' do
|
||||
let(:container_type) { :project }
|
||||
let(:id) { project.id }
|
||||
|
||||
it { is_expected.to match_array([project_repository]) }
|
||||
end
|
||||
|
||||
context 'with invalid id' do
|
||||
let(:container_type) { :project }
|
||||
let(:id) { 123456789 }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject.execute }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
it { is_expected.to match_array([project_repository]) }
|
||||
end
|
||||
|
||||
context 'with invalid subject_type' do
|
||||
let(:subject_object) { "invalid type" }
|
||||
|
||||
it { expect { subject }.to raise_exception('invalid subject_type') }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with unauthorized user' do
|
||||
subject { described_class.new(user: guest, subject: group).execute }
|
||||
|
||||
it { is_expected.to be nil }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -235,4 +235,36 @@ describe ContainerRepository do
|
|||
expect(repository).not_to be_persisted
|
||||
end
|
||||
end
|
||||
|
||||
describe '.for_group_and_its_subgroups' do
|
||||
subject { described_class.for_group_and_its_subgroups(test_group) }
|
||||
|
||||
context 'in a group' do
|
||||
let(:test_group) { group }
|
||||
|
||||
it { is_expected.to contain_exactly(repository) }
|
||||
end
|
||||
|
||||
context 'with a subgroup' do
|
||||
let(:test_group) { create(:group) }
|
||||
let(:another_project) { create(:project, path: 'test', group: test_group) }
|
||||
|
||||
let(:another_repository) do
|
||||
create(:container_repository, name: 'my_image', project: another_project)
|
||||
end
|
||||
|
||||
before do
|
||||
group.parent = test_group
|
||||
group.save
|
||||
end
|
||||
|
||||
it { is_expected.to contain_exactly(repository, another_repository) }
|
||||
end
|
||||
|
||||
context 'group without container_repositories' do
|
||||
let(:test_group) { create(:group) }
|
||||
|
||||
it { is_expected.to eq([]) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe API::GroupContainerRepositories do
|
||||
set(:group) { create(:group, :private) }
|
||||
set(:project) { create(:project, :private, group: group) }
|
||||
let(:reporter) { create(:user) }
|
||||
let(:guest) { create(:user) }
|
||||
let_it_be(:group) { create(:group, :private) }
|
||||
let_it_be(:project) { create(:project, :private, group: group) }
|
||||
let_it_be(:reporter) { create(:user) }
|
||||
let_it_be(:guest) { create(:user) }
|
||||
|
||||
let(:root_repository) { create(:container_repository, :root, project: project) }
|
||||
let(:test_repository) { create(:container_repository, project: project) }
|
||||
|
|
|
|||
Loading…
Reference in New Issue