Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-04-05 21:09:19 +00:00
parent 6d18e2830d
commit da07b341fd
56 changed files with 384 additions and 252 deletions

View File

@ -731,14 +731,8 @@ RSpec/EmptyLineAfterFinalLetItBe:
- ee/spec/services/external_approval_rules/create_service_spec.rb
- ee/spec/services/external_approval_rules/destroy_service_spec.rb
- ee/spec/services/external_approval_rules/update_service_spec.rb
- ee/spec/services/geo/blob_download_service_spec.rb
- ee/spec/services/geo/design_repository_sync_service_spec.rb
- ee/spec/services/geo/event_service_spec.rb
- ee/spec/services/geo/file_registry_removal_service_spec.rb
- ee/spec/services/geo/project_housekeeping_service_spec.rb
- ee/spec/services/gitlab_subscriptions/activate_service_spec.rb
- ee/spec/services/gitlab_subscriptions/apply_trial_service_spec.rb
- ee/spec/services/groups/autocomplete_service_spec.rb
- ee/spec/services/ide/schemas_config_service_spec.rb
- ee/spec/services/incident_management/incidents/upload_metric_service_spec.rb
- ee/spec/services/incident_management/oncall_rotations/edit_service_spec.rb

View File

@ -89,6 +89,11 @@ export default {
required: false,
default: '',
},
endpointUpdateUser: {
type: String,
required: false,
default: '',
},
projectPath: {
type: String,
required: true,
@ -283,6 +288,7 @@ export default {
endpointBatch: this.endpointBatch,
endpointCoverage: this.endpointCoverage,
endpointCodequality: this.endpointCodequality,
endpointUpdateUser: this.endpointUpdateUser,
projectPath: this.projectPath,
dismissEndpoint: this.dismissEndpoint,
showSuggestPopover: this.showSuggestPopover,

View File

@ -74,6 +74,7 @@ export default function initDiffsApp(store) {
endpointBatch: dataset.endpointBatch || '',
endpointCoverage: dataset.endpointCoverage || '',
endpointCodequality: dataset.endpointCodequality || '',
endpointUpdateUser: dataset.updateCurrentUserPath,
projectPath: dataset.projectPath,
helpPagePath: dataset.helpPagePath,
currentUser: JSON.parse(dataset.currentUserData) || {},
@ -116,6 +117,7 @@ export default function initDiffsApp(store) {
endpointBatch: this.endpointBatch,
endpointCoverage: this.endpointCoverage,
endpointCodequality: this.endpointCodequality,
endpointUpdateUser: this.endpointUpdateUser,
currentUser: this.currentUser,
projectPath: this.projectPath,
helpPagePath: this.helpPagePath,

View File

@ -62,6 +62,7 @@ export const setBaseConfig = ({ commit }, options) => {
endpointBatch,
endpointCoverage,
endpointCodequality,
endpointUpdateUser,
projectPath,
dismissEndpoint,
showSuggestPopover,
@ -75,6 +76,7 @@ export const setBaseConfig = ({ commit }, options) => {
endpointBatch,
endpointCoverage,
endpointCodequality,
endpointUpdateUser,
projectPath,
dismissEndpoint,
showSuggestPopover,

View File

@ -23,6 +23,7 @@ export default () => ({
addedLines: null,
removedLines: null,
endpoint: '',
endpointUpdateUser: '',
basePath: '',
commit: null,
startVersion: null, // Null unless a target diff is selected for comparison that is not the "base" diff

View File

@ -34,6 +34,7 @@ export default {
endpointBatch,
endpointCoverage,
endpointCodequality,
endpointUpdateUser,
projectPath,
dismissEndpoint,
showSuggestPopover,
@ -47,6 +48,7 @@ export default {
endpointBatch,
endpointCoverage,
endpointCodequality,
endpointUpdateUser,
projectPath,
dismissEndpoint,
showSuggestPopover,

View File

@ -208,7 +208,7 @@ export const canPushCodeStatus = (state, getters) => {
PUSH_RULE_REJECT_UNSIGNED_COMMITS
];
if (rejectUnsignedCommits) {
if (window.gon?.features?.rejectUnsignedCommitsByGitlab && rejectUnsignedCommits) {
return {
isAllowed: false,
message: MSG_CANNOT_PUSH_UNSIGNED,

View File

@ -10,6 +10,7 @@ class IdeController < ApplicationController
before_action do
push_frontend_feature_flag(:build_service_proxy)
push_frontend_feature_flag(:schema_linting)
push_frontend_feature_flag(:reject_unsigned_commits_by_gitlab, default_enabled: :yaml)
define_index_vars
end

View File

@ -60,14 +60,14 @@ module MergeRequests
ids.first.to_s.downcase == label || usernames.map(&:downcase).include?(label)
end
# Merge Requests without any approval
# Merge requests without any approval
#
# @param [ActiveRecord::Relation] items
def without_approvals(items)
items.without_approvals
end
# Merge Requests with any number of approvals
# Merge requests with any number of approvals
#
# @param [ActiveRecord::Relation] items the activerecord relation
def with_any_approvals(items)
@ -76,14 +76,14 @@ module MergeRequests
])
end
# Merge Requests approved by given usernames
# Merge requests approved by given usernames
#
# @param [ActiveRecord::Relation] items the activerecord relation
def find_approved_by_names(items)
items.approved_by_users_with_usernames(*usernames)
end
# Merge Requests approved by given user IDs
# Merge requests approved by given user IDs
#
# @param [ActiveRecord::Relation] items the activerecord relation
def find_approved_by_ids(items)

View File

@ -5,6 +5,6 @@ module Types
graphql_name 'MergeRequestState'
description 'State of a GitLab merge request'
value 'merged', description: "Merge Request has been merged."
value 'merged', description: "Merge request has been merged."
end
end

View File

@ -83,13 +83,13 @@ module Types
# Merge request field: MRs can be authored, assigned, or assigned-for-review:
field :authored_merge_requests,
resolver: Resolvers::AuthoredMergeRequestsResolver,
description: 'Merge Requests authored by the user.'
description: 'Merge requests authored by the user.'
field :assigned_merge_requests,
resolver: Resolvers::AssignedMergeRequestsResolver,
description: 'Merge Requests assigned to the user.'
description: 'Merge requests assigned to the user.'
field :review_requested_merge_requests,
resolver: Resolvers::ReviewRequestedMergeRequestsResolver,
description: 'Merge Requests assigned to the user for review.'
description: 'Merge requests assigned to the user for review.'
field :snippets,
description: 'Snippets authored by the user.',

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
class BambooService < CiService
include ActionView::Helpers::UrlHelper
include ReactiveService
prop_accessor :bamboo_url, :build_key, :username, :password
@ -31,15 +32,16 @@ class BambooService < CiService
end
def title
s_('BambooService|Atlassian Bamboo CI')
s_('BambooService|Atlassian Bamboo')
end
def description
s_('BambooService|A continuous integration and build server')
s_('BambooService|Use the Atlassian Bamboo CI/CD server with GitLab.')
end
def help
s_('BambooService|You must set up automatic revision labeling and a repository trigger in Bamboo.')
docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/bamboo'), target: '_blank', rel: 'noopener noreferrer'
s_('BambooService|Use Atlassian Bamboo to run CI/CD pipelines. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
def self.to_param
@ -52,19 +54,21 @@ class BambooService < CiService
type: 'text',
name: 'bamboo_url',
title: s_('BambooService|Bamboo URL'),
placeholder: s_('BambooService|Bamboo root URL like https://bamboo.example.com'),
placeholder: s_('https://bamboo.example.com'),
help: s_('BambooService|Bamboo service root URL.'),
required: true
},
{
type: 'text',
name: 'build_key',
placeholder: s_('BambooService|Bamboo build plan key like KEY'),
placeholder: s_('KEY'),
help: s_('BambooService|Bamboo build plan key.'),
required: true
},
{
type: 'text',
name: 'username',
placeholder: s_('BambooService|A user with API access, if applicable')
help: s_('BambooService|The user with API access to the Bamboo server.')
},
{
type: 'password',

View File

@ -31,9 +31,9 @@ class Timelog < ApplicationRecord
def issuable_id_is_present
if issue_id && merge_request_id
errors.add(:base, _('Only Issue ID or Merge Request ID is required'))
errors.add(:base, _('Only Issue ID or merge request ID is required'))
elsif issuable.nil?
errors.add(:base, _('Issue or Merge Request ID is required'))
errors.add(:base, _('Issue or merge request ID is required'))
end
end

View File

@ -38,7 +38,7 @@ module DevOpsReport
),
Card.new(
metric: subject,
title: 'Merge Requests',
title: 'Merge requests',
description: 'per active user',
feature: 'merge_requests',
blog: 'https://8thlight.com/blog/uncle-bob/2013/02/01/The-Humble-Craftsman.html',

View File

@ -2,11 +2,12 @@
module Pages
class MigrateFromLegacyStorageService
def initialize(logger, migration_threads:, batch_size:, ignore_invalid_entries:)
def initialize(logger, migration_threads:, batch_size:, ignore_invalid_entries:, mark_projects_as_not_deployed:)
@logger = logger
@migration_threads = migration_threads
@batch_size = batch_size
@ignore_invalid_entries = ignore_invalid_entries
@mark_projects_as_not_deployed = mark_projects_as_not_deployed
@migrated = 0
@errored = 0
@ -60,7 +61,9 @@ module Pages
def migrate_project(project)
result = nil
time = Benchmark.realtime do
result = ::Pages::MigrateLegacyStorageToDeploymentService.new(project, ignore_invalid_entries: @ignore_invalid_entries).execute
result = ::Pages::MigrateLegacyStorageToDeploymentService.new(project,
ignore_invalid_entries: @ignore_invalid_entries,
mark_projects_as_not_deployed: @mark_projects_as_not_deployed).execute
end
if result[:status] == :success

View File

@ -9,9 +9,10 @@ module Pages
attr_reader :project
def initialize(project, ignore_invalid_entries: false)
def initialize(project, ignore_invalid_entries: false, mark_projects_as_not_deployed: false)
@project = project
@ignore_invalid_entries = ignore_invalid_entries
@mark_projects_as_not_deployed = mark_projects_as_not_deployed
end
def execute
@ -36,10 +37,12 @@ module Pages
archive_path = zip_result[:archive_path]
unless archive_path
return error("Archive not created. Missing public directory in #{@project.pages_path}") unless @mark_projects_as_not_deployed
project.set_first_pages_deployment!(nil)
return success(
message: "Archive not created. Missing public directory in #{project.pages_path} ? Marked project as not deployed")
message: "Archive not created. Missing public directory in #{project.pages_path}? Marked project as not deployed")
end
deployment = nil

View File

@ -18,13 +18,7 @@ module Pages
end
def execute
unless resolve_public_dir
if Feature.enabled?(:pages_migration_mark_as_not_deployed)
return success
end
return error("Can not find valid public dir in #{@input_dir}")
end
return success unless resolve_public_dir
output_file = File.join(real_dir, "@migrated.zip") # '@' to avoid any name collision with groups or projects

View File

@ -1,6 +1,6 @@
- @can_bulk_update = can?(current_user, :admin_merge_request, @group) && @group.feature_available?(:group_bulk_edit)
- page_title _("Merge Requests")
- page_title _("Merge requests")
- if @merge_requests&.size == 0
= render 'shared/empty_states/merge_requests', project_select_button: true

View File

@ -44,7 +44,7 @@
= link_to pluralize(milestone.total_issues_count, _('Issue')), issues_path
- if milestone.merge_requests_enabled?
&middot;
= link_to pluralize(milestone.merge_requests_visible_to_user(current_user).size, _('Merge Request')), merge_requests_path
= link_to pluralize(milestone.merge_requests_visible_to_user(current_user).size, _('Merge request')), merge_requests_path
.float-lg-right.light #{milestone.percent_complete}% complete
.col-sm-2
.milestone-actions.d-flex.justify-content-sm-start.justify-content-md-end

View File

@ -11,7 +11,7 @@
- if milestone.merge_requests_enabled?
%li.nav-item
= link_to '#tab-merge-requests', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'merge_requests', show_project_name: show_project_name) } do
= _('Merge Requests')
= _('Merge requests')
%span.badge.badge-pill= milestone.merge_requests_visible_to_user(current_user).size
%li.nav-item
= link_to '#tab-participants', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'participants') } do

View File

@ -90,7 +90,7 @@
- if show_merge_request_count?(disabled: !merge_requests, compact_mode: compact_mode)
= link_to project_merge_requests_path(project),
class: "d-none d-xl-flex align-items-center icon-wrapper merge-requests has-tooltip",
title: _('Merge Requests'), data: { container: 'body', placement: 'top' } do
title: _('Merge requests'), data: { container: 'body', placement: 'top' } do
= sprite_icon('git-merge', size: 14, css_class: 'gl-mr-2')
= number_with_delimiter(project.open_merge_requests_count)
- if show_issue_count?(disabled: !issues, compact_mode: compact_mode)

View File

@ -8,6 +8,9 @@ module Database
feature_category :database
idempotent!
LEASE_TIMEOUT_MULTIPLIER = 3
MINIMUM_LEASE_TIMEOUT = 10.minutes.freeze
def perform
return unless Feature.enabled?(:execute_batched_migrations_on_schedule, type: :ops) && active_migration
@ -33,14 +36,19 @@ module Database
Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.new.run_migration_job(active_migration)
end
def with_exclusive_lease(timeout)
lease = Gitlab::ExclusiveLease.new(lease_key, timeout: timeout * 2)
def with_exclusive_lease(interval)
timeout = max(interval * LEASE_TIMEOUT_MULTIPLIER, MINIMUM_LEASE_TIMEOUT)
lease = Gitlab::ExclusiveLease.new(lease_key, timeout: timeout)
yield if lease.try_obtain
ensure
lease&.cancel
end
def max(left, right)
left >= right ? left : right
end
def lease_key
self.class.name.demodulize.underscore
end

View File

@ -0,0 +1,6 @@
---
title: Allow users to mark pages projects as not deployed during migration to zip
storage
merge_request: 55862
author:
type: added

View File

@ -0,0 +1,5 @@
---
title: Replace deprecated button on new epic creation form
merge_request: 57874
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Update pot file
merge_request: 58392
author:
type: other

View File

@ -1,8 +1,8 @@
---
name: pages_migration_mark_as_not_deployed
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49473
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/295187
milestone: '13.8'
name: reject_unsigned_commits_by_gitlab
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58453
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326775
milestone: '13.11'
type: development
group: group::release
default_enabled: false
group: group::editor
default_enabled: true

View File

@ -3,9 +3,9 @@
MESSAGE = <<~MESSAGE
## Pipeline Changes
This Merge Request contains changes to the pipeline configuration for the GitLab project.
This merge request contains changes to the pipeline configuration for the GitLab project.
Please consider the effect of the changes in this Merge Request on the following:
Please consider the effect of the changes in this merge request on the following:
- Effects on different [pipeline types](https://docs.gitlab.com/ee/development/pipelines.html#pipelines-for-merge-requests)
- Effects on non-canonical projects:
- `gitlab-foss`

View File

@ -6543,8 +6543,8 @@ Representation of a GitLab user.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `assignedMergeRequests` | [`MergeRequestConnection`](#mergerequestconnection) | Merge Requests assigned to the user. |
| `authoredMergeRequests` | [`MergeRequestConnection`](#mergerequestconnection) | Merge Requests authored by the user. |
| `assignedMergeRequests` | [`MergeRequestConnection`](#mergerequestconnection) | Merge requests assigned to the user. |
| `authoredMergeRequests` | [`MergeRequestConnection`](#mergerequestconnection) | Merge requests authored by the user. |
| `avatarUrl` | [`String`](#string) | URL of the user's avatar. |
| `bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
| `callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. |
@ -6556,7 +6556,7 @@ Representation of a GitLab user.
| `name` | [`String!`](#string) | Human-readable name of the user. |
| `projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. |
| `publicEmail` | [`String`](#string) | User's public email. |
| `reviewRequestedMergeRequests` | [`MergeRequestConnection`](#mergerequestconnection) | Merge Requests assigned to the user for review. |
| `reviewRequestedMergeRequests` | [`MergeRequestConnection`](#mergerequestconnection) | Merge requests assigned to the user for review. |
| `snippets` | [`SnippetConnection`](#snippetconnection) | Snippets authored by the user. |
| `starredProjects` | [`ProjectConnection`](#projectconnection) | Projects starred by the user. |
| `state` | [`UserState!`](#userstate) | State of the user. |
@ -7833,7 +7833,7 @@ State of a GitLab merge request.
| `all` | All available. |
| `closed` | In closed state. |
| `locked` | Discussion has been locked. |
| `merged` | Merge Request has been merged. |
| `merged` | Merge request has been merged. |
| `opened` | In open state. |
### `MergeStrategyEnum`

View File

@ -15,9 +15,11 @@ This document now describes the new Vulnerabilities API that provides access to
[Vulnerabilities](https://gitlab.com/groups/gitlab-org/-/epics/634).
WARNING:
This API is in an alpha stage and considered unstable.
This API is in the process of being deprecated and considered unstable.
The response payload may be subject to change or breakage
across GitLab releases.
across GitLab releases. Please use the
[GraphQL API](graphql/reference/index.md#vulnerabilities)
instead.
Every API call to vulnerabilities must be [authenticated](README.md#authentication).

View File

@ -67,8 +67,9 @@ be enabled for a single project, and is not ready for production use:
> - Not recommended for production use.
> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#anchor-to-section). **(FREE SELF)**
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
This in-development feature might not be available for your use. There can be
[risks when enabling features still in development](<replace with path to>/user/feature_flags.md#risks-when-enabling-features-still-in-development).
Refer to this feature's version history for more details.
(...Regular content goes here...)
@ -126,8 +127,9 @@ use:
> - Recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#anchor-to-section). **(FREE SELF)**
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
There can be
[risks when disabling released features](<replace with path to>/user/feature_flags.md#risks-when-disabling-released-features).
Refer to this feature's version history for more details.
(...Regular content goes here...)
@ -182,8 +184,9 @@ cannot be enabled for a single project, and is ready for production use:
> - Recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#anchor-to-section). **(FREE SELF)**
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
There can be
[risks when disabling released features](<replace with path to>/user/feature_flags.md#risks-when-disabling-released-features).
Refer to this feature's version history for more details.
(...Regular content goes here...)
@ -255,8 +258,9 @@ be enabled by project, and is ready for production use:
> - Recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#anchor-to-section). **(FREE SELF)**
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
There can be
[risks when disabling released features](<replace with path to>/user/feature_flags.md#risks-when-disabling-released-features).
Refer to this feature's version history for more details.
(...Regular content goes here...)

View File

@ -256,7 +256,7 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
- In Vue:
Use the [`GlSprintf`](https://gitlab-org.gitlab.io/gitlab-ui/?path=/docs/utilities-sprintf--sentence-with-link) component if:
- you need to include child components in the translation string.
- you need to include HTML in your translation string.
- you are using `sprintf` and need to pass `false` as the third argument to
@ -699,7 +699,7 @@ bin/rake gettext:regenerate
This command updates `locale/gitlab.pot` file with the newly externalized
strings and remove any strings that aren't used anymore. You should check this
file in. Once the changes are on master, they are picked up by
file in. Once the changes are on the default branch, they are picked up by
[CrowdIn](https://translate.gitlab.com) and be presented for
translation.

View File

@ -42,10 +42,11 @@ page](https://translate.gitlab.com/project/gitlab-ee/settings#integration).
## Merging translations
When all translations are found good and pipelines pass the
translations can be merged into the master branch. When merging the translations,
make sure to check the **Remove source branch** checkbox, so CrowdIn recreates the
`master-i18n` from master after the new translation was merged.
After all translations are determined to be appropriate and the pipelines pass,
you can merge the translations into the default branch. When merging translations,
be sure to select the **Remove source branch** check box, which causes CrowdIn
to recreate the `master-i18n` from the default branch after merging the new
translation.
We are discussing [automating this entire process](https://gitlab.com/gitlab-org/gitlab/-/issues/19896).
@ -59,7 +60,7 @@ and delete the
[`master-18n`](https://gitlab.com/gitlab-org/gitlab/-/branches/all?utf8=✓&search=master-i18n).
This might be needed when the merge request contains failures that
have been fixed on master.
have been fixed on the default branch.
## Recreate the GitLab integration in CrowdIn

View File

@ -104,6 +104,15 @@ describe('Component', () => {
Remember that the performance of each test depends on the environment.
### Test-specific stylesheets
To help facilitate RSpec integration tests we have two test-specific stylesheets. These can be used to do things like disable animations to improve test speed, or to make elements visible when they need to be targeted by Capybara click events:
- `app/assets/stylesheets/disable_animations.scss`
- `app/assets/stylesheets/test_environment.scss`
Because the test environment should match the production environment as much as possible, use these minimally and only add to them when necessary.
## What and how to test
Before jumping into more gritty details about Jest-specific workflows like mocks and spies, we should briefly cover what to test with Jest.

View File

@ -18,9 +18,9 @@ may be unavailable to you.
In this case, you'll see a warning like this in the feature documentation:
WARNING:
This feature might not be available to you. Review the **version history** note
on this page for details.
This in-development feature might not be available for your use. There can be
[risks when enabling features still in development](#risks-when-enabling-features-still-in-development).
Refer to this feature's version history for more details.
In the version history note, you'll find information on the state of the
feature flag, including whether the feature is on ("enabled by default") or
@ -41,3 +41,17 @@ although changing a feature's default state isn't recommended.
If you're a GitLab.com user and the feature is disabled, be aware that GitLab may
be working on the feature for potential release in the future.
## Risks when enabling features still in development
Features that are disabled by default may change or be removed without notice in a future version of GitLab.
Data corruption, stability degradation, or performance degradation might occur if
you enable a feature that's disabled by default. Problems caused by using a default
disabled feature aren't covered by GitLab support, unless you were directed by GitLab
to enable the feature.
## Risks when disabling released features
In most cases, the feature flag code is removed in a future version of GitLab.
If and when that occurs, from that point onward you can't keep the feature in a disabled state.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -50,19 +50,13 @@ Once [Group Single Sign-On](index.md) has been configured, we can:
The SAML application that was created during [Single sign-on](index.md) setup for [Azure](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/view-applications-portal) now needs to be set up for SCIM.
1. Check the configuration for your GitLab SAML app and ensure that **Name identifier value** (NameID) points to `user.objectid` or another unique identifier. This matches the `extern_uid` used on GitLab.
![Name identifier value mapping](img/scim_name_identifier_mapping.png)
1. Set up automatic provisioning and administrative credentials by following the
[Provisioning users and groups to applications that support SCIM](https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#provisioning-users-and-groups-to-applications-that-support-scim) section in Azure's SCIM setup documentation.
[Azure's SCIM setup documentation](https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#provisioning-users-and-groups-to-applications-that-support-scim).
During this configuration, note the following:
- The `Tenant URL` and `secret token` are the ones retrieved in the
[previous step](#gitlab-configuration).
- Should there be any problems with the availability of GitLab or similar
errors, the notification email set gets those.
- It is recommended to set a notification email and check the **Send an email notification when a failure occurs** checkbox.
- For mappings, we will only leave `Synchronize Azure Active Directory Users to AppName` enabled.
@ -70,42 +64,30 @@ You can then test the connection by clicking on **Test Connection**. If the conn
#### Configure attribute mapping
1. Click on `Synchronize Azure Active Directory Users to AppName` to configure the attribute mapping.
1. Click **Delete** next to the `mail` mapping.
1. Map `userPrincipalName` to `emails[type eq "work"].value` and change its **Matching precedence** to `2`.
1. Map `mailNickname` to `userName`.
1. Determine how GitLab uniquely identifies users.
Follow [Azure documentation to configure the attribute mapping](https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/customize-application-attributes).
- Use `objectId` unless users already have SAML linked for your group.
- If you already have users with SAML linked then use the `Name ID` value from the [SAML configuration](#azure). Using a different value may cause duplicate users and prevent users from accessing the GitLab group.
The following table below provides an attribute mapping known to work with GitLab. If
your SAML configuration differs from [the recommended SAML settings](index.md#azure-setup-notes),
modify the corresponding `customappsso` settings accordingly. If a mapping is not listed in the
table, use the Azure defaults.
1. Create a new mapping:
1. Click **Add New Mapping**.
1. Set:
- **Source attribute** to the unique identifier determined above, typically `objectId`.
- **Target attribute** to `externalId`.
- **Match objects using this attribute** to `Yes`.
- **Matching precedence** to `1`.
| Azure Active Directory Attribute | customappsso Attribute | Matching precedence |
| -------------------------------- | ---------------------- | -------------------- |
| `objectId` | `externalId` | 1 |
| `userPrincipalName` | `emails[type eq "work"].value` | |
| `mailNickname` | `userName` | |
1. Click the `userPrincipalName` mapping and change **Match objects using this attribute** to `No`.
1. Save your changes. For reference, you can view [an example configuration in the troubleshooting reference](../../../administration/troubleshooting/group_saml_scim.md#azure-active-directory).
NOTE:
If you used a unique identifier **other than** `objectId`, be sure to map it to `externalId`.
For guidance, you can view [an example configuration in the troubleshooting reference](../../../administration/troubleshooting/group_saml_scim.md#azure-active-directory).
1. Below the mapping list click on **Show advanced options > Edit attribute list for AppName**.
1. Ensure the `id` is the primary and required field, and `externalId` is also required.
NOTE:
`username` should neither be primary nor required as we don't support
that field on GitLab SCIM yet.
1. Save all the screens and, in the **Provisioning** step, set
the `Provisioning Status` to `On`.
![Provisioning status toggle switch](img/scim_provisioning_status.png)
1. Save all changes.
1. In the **Provisioning** step, set the `Provisioning Status` to `On`.
NOTE:
You can control what is actually synced by selecting the `Scope`. For example,

View File

@ -15,33 +15,33 @@ include a centralized, proprietary version control system similar to Git.
The following list illustrates the main differences between Perforce Helix and
Git:
1. In general the biggest difference is that Perforce branching is heavyweight
compared to Git's lightweight branching. When you create a branch in Perforce,
it creates an integration record in their proprietary database for every file
in the branch, regardless how many were actually changed. Whereas Git was
implemented with a different architecture so that a single SHA acts as a pointer
to the state of the whole repository after the changes, making it very easy to branch.
This is what made feature branching workflows so easy to adopt with Git.
1. Also, context switching between branches is much easier in Git. If your manager
said 'You need to stop work on that new feature and fix this security
vulnerability' you can do so very easily in Git.
1. Having a complete copy of the project and its history on your local machine
means every transaction is very fast and Git provides that. You can branch/merge
and experiment in isolation, then clean up your mess before sharing your new
cool stuff with everyone.
1. Git also made code review simple because you could share your changes without
merging them to master, whereas Perforce had to implement a Shelving feature on
the server so others could review changes before merging.
- In general, the biggest difference is that Perforce branching is heavyweight
compared to Git's lightweight branching. When you create a branch in Perforce,
it creates an integration record in their proprietary database for every file
in the branch, regardless how many were actually changed. With Git, however,
a single SHA acts as a pointer to the state of the whole repository after the
changes, which can be helpful when adopting feature branching workflows.
- Context switching between branches is less complex in Git. If your manager
says, 'You need to stop work on that new feature and fix this security
vulnerability,' Git can help you do this.
- Having a complete copy of the project and its history on your local computer
means every transaction is very fast, and Git provides that. You can branch
or merge, and experiment in isolation, and then clean up before sharing your
changes with others.
- Git makes code review less complex, because you can share your changes without
merging them to the default branch. This is compared to Perforce, which had to
implement a Shelving feature on the server so others could review changes
before merging.
## Why migrate
Perforce Helix can be difficult to manage both from a user and an administrator
perspective. Migrating to Git/GitLab there is:
- **No licensing costs**, Git is GPL while Perforce Helix is proprietary.
- **Shorter learning curve**, Git has a big community and a vast number of
- **No licensing costs**: Git is GPL while Perforce Helix is proprietary.
- **Shorter learning curve**: Git has a big community and a vast number of
tutorials to get you started.
- **Integration with modern tools**, migrating to Git and GitLab you can have
- **Integration with modern tools**: By migrating to Git and GitLab, you can have
an open source end-to-end software development platform with built-in version
control, issue tracking, code review, CI/CD, and more.

View File

@ -4,11 +4,11 @@ group: Ecosystem
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Atlassian Bamboo CI Service **(FREE)**
# Atlassian Bamboo Service **(FREE)**
GitLab provides integration with Atlassian Bamboo for continuous integration.
When configured, pushes to a project trigger a build in Bamboo automatically.
Merge requests also display CI status showing whether the build is pending,
Merge requests also display CI/CD status showing whether the build is pending,
failed, or completed successfully. It also provides a link to the Bamboo build
page for more information.
@ -20,21 +20,21 @@ need to be configured in a Bamboo build plan before GitLab can integrate.
### Complete these steps in Bamboo
1. Navigate to a Bamboo build plan and choose 'Configure plan' from the 'Actions'
1. Navigate to a Bamboo build plan and choose **Configure plan** from the **Actions**
dropdown.
1. Select the 'Triggers' tab.
1. Click 'Add trigger'.
1. Enter a description such as 'GitLab trigger'
1. Choose 'Repository triggers the build when changes are committed'
1. Check one or more repositories checkboxes
1. Enter the GitLab IP address in the 'Trigger IP addresses' box. This is a
1. Select the **Triggers** tab.
1. Click **Add trigger**.
1. Enter a description such as **GitLab trigger**.
1. Choose **Repository triggers the build when changes are committed**.
1. Select the checkbox for one or more repositories.
1. Enter the GitLab IP address in the **Trigger IP addresses** box. This is a
list of IP addresses that are allowed to trigger Bamboo builds.
1. Save the trigger.
1. In the left pane, select a build stage. If you have multiple build stages
you want to select the last stage that contains the Git checkout task.
1. Select the 'Miscellaneous' tab.
1. Under 'Pattern Match Labeling' put `${bamboo.repository.revision.number}`
in the 'Labels' box.
1. Select the **Miscellaneous** tab.
1. Under **Pattern Match Labeling** put `${bamboo.repository.revision.number}`
in the **Labels** box.
1. Save
Bamboo is now ready to accept triggers from GitLab. Next, set up the Bamboo
@ -44,18 +44,18 @@ service in GitLab.
1. Navigate to the project you want to configure to trigger builds.
1. Navigate to the [Integrations page](overview.md#accessing-integrations)
1. Click 'Atlassian Bamboo CI'
1. Click **Atlassian Bamboo**.
1. Ensure that the **Active** toggle is enabled.
1. Enter the base URL of your Bamboo server. `https://bamboo.example.com`
1. Enter the build key from your Bamboo build plan. Build keys are typically made
up from the Project Key and Plan Key that are set on project/plan creation and
separated with a dash (`-`), for example **PROJ-PLAN**. This is a short, all
separated with a dash (`-`), for example **PROJ-PLAN**. This is a short, all
uppercase identifier that is unique. When viewing a plan in Bamboo, the
build key is also shown in the browser URL, for example `https://bamboo.example.com/browse/PROJ-PLAN`.
1. If necessary, enter username and password for a Bamboo user that has
access to trigger the build plan. Leave these fields blank if you do not require
authentication.
1. Save or optionally click 'Test Settings'. Please note that 'Test Settings'
1. Save or optionally click **Test Settings**. Please note that **Test Settings**
actually triggers a build in Bamboo.
## Troubleshooting
@ -63,7 +63,7 @@ service in GitLab.
### Builds not triggered
If builds are not triggered, ensure you entered the right GitLab IP address in
Bamboo under 'Trigger IP addresses'. Also check [service hook logs](overview.md#troubleshooting-integrations) for request failures.
Bamboo under **Trigger IP addresses**. Also check [service hook logs](overview.md#troubleshooting-integrations) for request failures.
### Advanced Atlassian Bamboo features not available in GitLab UI

View File

@ -2,7 +2,7 @@
module Banzai
module Filter
# Issues, Merge Requests, Snippets, Commits and Commit Ranges share
# Issues, merge requests, Snippets, Commits and Commit Ranges share
# similar functionality in reference filtering.
class AbstractReferenceFilter < ReferenceFilter
include CrossProjectReference

View File

@ -7,8 +7,8 @@
## CONTRIBUTING ##
##################################
##
## If you change this file in a Merge Request, please also create
## a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests
## If you change this file in a merge request, please also create
## a merge request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests
##
###################################
## configuration ##

View File

@ -11,8 +11,8 @@
## CONTRIBUTING ##
##################################
##
## If you change this file in a Merge Request, please also create
## a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests
## If you change this file in a merge request, please also create
## a merge request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests
##
###################################
## configuration ##

View File

@ -11,7 +11,8 @@ namespace :gitlab do
result = ::Pages::MigrateFromLegacyStorageService.new(logger,
migration_threads: migration_threads,
batch_size: batch_size,
ignore_invalid_entries: ignore_invalid_entries).execute
ignore_invalid_entries: ignore_invalid_entries,
mark_projects_as_not_deployed: mark_projects_as_not_deployed).execute
logger.info("A total of #{result[:migrated] + result[:errored]} projects were processed.")
logger.info("- The #{result[:migrated]} projects migrated successfully")
@ -51,5 +52,11 @@ namespace :gitlab do
ENV.fetch('PAGES_MIGRATION_IGNORE_INVALID_ENTRIES', 'false')
)
end
def mark_projects_as_not_deployed
Gitlab::Utils.to_boolean(
ENV.fetch('PAGES_MIGRATION_MARK_PROJECTS_AS_NOT_DEPLOYED', 'false')
)
end
end
end

View File

@ -4714,25 +4714,25 @@ msgstr ""
msgid "Balsamiq file could not be loaded."
msgstr ""
msgid "BambooService|A continuous integration and build server"
msgstr ""
msgid "BambooService|A user with API access, if applicable"
msgstr ""
msgid "BambooService|Atlassian Bamboo CI"
msgid "BambooService|Atlassian Bamboo"
msgstr ""
msgid "BambooService|Bamboo URL"
msgstr ""
msgid "BambooService|Bamboo build plan key like KEY"
msgid "BambooService|Bamboo build plan key."
msgstr ""
msgid "BambooService|Bamboo root URL like https://bamboo.example.com"
msgid "BambooService|Bamboo service root URL."
msgstr ""
msgid "BambooService|You must set up automatic revision labeling and a repository trigger in Bamboo."
msgid "BambooService|The user with API access to the Bamboo server."
msgstr ""
msgid "BambooService|Use Atlassian Bamboo to run CI/CD pipelines. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}"
msgstr ""
msgid "BambooService|Use the Atlassian Bamboo CI/CD server with GitLab."
msgstr ""
msgid "Based on"
@ -17282,7 +17282,7 @@ msgstr ""
msgid "Issue label"
msgstr ""
msgid "Issue or Merge Request ID is required"
msgid "Issue or merge request ID is required"
msgstr ""
msgid "Issue published on status page."
@ -17849,6 +17849,9 @@ msgstr ""
msgid "K8s pod health"
msgstr ""
msgid "KEY"
msgstr ""
msgid "Keep artifacts from most recent successful jobs"
msgstr ""
@ -21776,7 +21779,7 @@ msgstr ""
msgid "Only 1 appearances row can exist"
msgstr ""
msgid "Only Issue ID or Merge Request ID is required"
msgid "Only Issue ID or merge request ID is required"
msgstr ""
msgid "Only Project Members"
@ -36284,6 +36287,9 @@ msgstr ""
msgid "http://www.example.com"
msgstr ""
msgid "https://bamboo.example.com"
msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""

View File

@ -30,7 +30,7 @@ RSpec.describe 'Dashboard > Milestones' do
expect(current_path).to eq dashboard_milestones_path
expect(page).to have_content(milestone.title)
expect(page).to have_content(group.name)
expect(first('.milestone')).to have_content('Merge Requests')
expect(first('.milestone')).to have_content('Merge requests')
end
describe 'new milestones dropdown', :js do

View File

@ -133,7 +133,7 @@ RSpec.describe 'Group milestones' do
href: project_issues_path(project, milestone_title: 'v1.0')
)
expect(page).to have_link(
'0 Merge Requests',
'0 Merge requests',
href: project_merge_requests_path(project, milestone_title: 'v1.0')
)
expect(page).to have_link(
@ -145,7 +145,7 @@ RSpec.describe 'Group milestones' do
href: issues_group_path(group, milestone_title: 'GL-113')
)
expect(page).to have_link(
'0 Merge Requests',
'0 Merge requests',
href: merge_requests_group_path(group, milestone_title: 'GL-113')
)
end
@ -179,7 +179,7 @@ RSpec.describe 'Group milestones' do
it 'renders the merge requests tab' do
within('.js-milestone-tabs') do
click_link('Merge Requests')
click_link('Merge requests')
end
within('#tab-merge-requests') do

View File

@ -98,7 +98,7 @@ RSpec.describe "User views milestone" do
visit(project_milestone_path(project, milestone))
within('.js-milestone-tabs') do
click_link('Merge Requests')
click_link('Merge requests')
end
wait_for_requests
@ -116,7 +116,7 @@ RSpec.describe "User views milestone" do
visit(group_milestone_path(group, group_milestone))
within('.js-milestone-tabs') do
click_link('Merge Requests')
click_link('Merge requests')
end
expect(page.find('#tab-merge-requests')).to have_text(project.name)

View File

@ -18,7 +18,7 @@ RSpec.describe "User views milestones" do
expect(page).to have_content(milestone.title)
.and have_content(milestone.expires_at)
.and have_content("Issues")
.and have_content("Merge Requests")
.and have_content("Merge requests")
end
context "with issues", :js do
@ -80,7 +80,6 @@ RSpec.describe "User views milestones with no MR" do
expect(page).to have_content(milestone.title)
.and have_content(milestone.expires_at)
.and have_content("Issues")
.and have_no_content("Merge Requests")
end
it "opens milestone" do

View File

@ -10,7 +10,7 @@ RSpec.describe 'User activates Atlassian Bamboo CI' do
end
it 'activates service', :js do
visit_project_integration('Atlassian Bamboo CI')
visit_project_integration('Atlassian Bamboo')
fill_in('Bamboo URL', with: 'http://bamboo.example.com')
fill_in('Build key', with: 'KEY')
fill_in('Username', with: 'user')
@ -18,10 +18,10 @@ RSpec.describe 'User activates Atlassian Bamboo CI' do
click_test_then_save_integration(expect_test_to_fail: false)
expect(page).to have_content('Atlassian Bamboo CI settings saved and active.')
expect(page).to have_content('Atlassian Bamboo settings saved and active.')
# Password field should not be filled in.
click_link('Atlassian Bamboo CI')
click_link('Atlassian Bamboo')
expect(find_field('Enter new password').value).to be_blank
expect(page).to have_content('Leave blank to use your current password')

View File

@ -7,15 +7,17 @@ import diffFileMockData from '../mock_data/diff_file';
describe('DiffsStoreMutations', () => {
describe('SET_BASE_CONFIG', () => {
it('should set endpoint and project path', () => {
it.each`
prop | value
${'endpoint'} | ${'/diffs/endpoint'}
${'projectPath'} | ${'/root/project'}
${'endpointUpdateUser'} | ${'/user/preferences'}
`('should set the $prop property into state', ({ prop, value }) => {
const state = {};
const endpoint = '/diffs/endpoint';
const projectPath = '/root/project';
mutations[types.SET_BASE_CONFIG](state, { endpoint, projectPath });
mutations[types.SET_BASE_CONFIG](state, { [prop]: value });
expect(state.endpoint).toEqual(endpoint);
expect(state.projectPath).toEqual(projectPath);
expect(state[prop]).toEqual(value);
});
});

View File

@ -24,12 +24,22 @@ const TEST_FORK_PATH = '/test/fork/path';
describe('IDE store getters', () => {
let localState;
let localStore;
let origGon;
beforeEach(() => {
origGon = window.gon;
// Feature flag is defaulted to on in prod
window.gon = { features: { rejectUnsignedCommitsByGitlab: true } };
localStore = createStore();
localState = localStore.state;
});
afterEach(() => {
window.gon = origGon;
});
describe('activeFile', () => {
it('returns the current active file', () => {
localState.openFiles.push(file());
@ -500,9 +510,25 @@ describe('IDE store getters', () => {
},
},
],
[
'when can push code, but cannot push unsigned commits, with reject_unsigned_commits_by_gitlab feature off',
{
input: {
pushCode: true,
rejectUnsignedCommits: true,
features: { rejectUnsignedCommitsByGitlab: false },
},
output: {
isAllowed: true,
message: '',
messageShort: '',
},
},
],
])('%s', (testName, { input, output }) => {
const { forkInfo, rejectUnsignedCommits, pushCode } = input;
const { forkInfo, rejectUnsignedCommits, pushCode, features = {} } = input;
Object.assign(window.gon.features, features);
localState.links = { forkInfo };
localState.projects[TEST_PROJECT_ID] = {
pushRules: {

View File

@ -3,7 +3,9 @@
require 'spec_helper'
RSpec.describe Pages::MigrateFromLegacyStorageService do
let(:service) { described_class.new(Rails.logger, migration_threads: 3, batch_size: 10, ignore_invalid_entries: false) }
let(:batch_size) { 10 }
let(:mark_projects_as_not_deployed) { false }
let(:service) { described_class.new(Rails.logger, migration_threads: 3, batch_size: batch_size, ignore_invalid_entries: false, mark_projects_as_not_deployed: mark_projects_as_not_deployed) }
it 'does not try to migrate pages if pages are not deployed' do
expect(::Pages::MigrateLegacyStorageToDeploymentService).not_to receive(:new)
@ -11,33 +13,35 @@ RSpec.describe Pages::MigrateFromLegacyStorageService do
expect(service.execute).to eq(migrated: 0, errored: 0)
end
it 'uses multiple threads' do
projects = create_list(:project, 20)
projects.each do |project|
project.mark_pages_as_deployed
context 'when there is work for multiple threads' do
let(:batch_size) { 2 } # override to force usage of multiple threads
FileUtils.mkdir_p File.join(project.pages_path, "public")
File.open(File.join(project.pages_path, "public/index.html"), "w") do |f|
f.write("Hello!")
it 'uses multiple threads' do
projects = create_list(:project, 20)
projects.each do |project|
project.mark_pages_as_deployed
FileUtils.mkdir_p File.join(project.pages_path, "public")
File.open(File.join(project.pages_path, "public/index.html"), "w") do |f|
f.write("Hello!")
end
end
threads = Concurrent::Set.new
expect(service).to receive(:migrate_project).exactly(20).times.and_wrap_original do |m, *args|
threads.add(Thread.current)
# sleep to be 100% certain that once thread can't consume all the queue
# it works without it, but I want to avoid making this test flaky
sleep(0.01)
m.call(*args)
end
expect(service.execute).to eq(migrated: 20, errored: 0)
expect(threads.length).to eq(3)
end
service = described_class.new(Rails.logger, migration_threads: 3, batch_size: 2, ignore_invalid_entries: false)
threads = Concurrent::Set.new
expect(service).to receive(:migrate_project).exactly(20).times.and_wrap_original do |m, *args|
threads.add(Thread.current)
# sleep to be 100% certain that once thread can't consume all the queue
# it works without it, but I want to avoid making this test flaky
sleep(0.01)
m.call(*args)
end
expect(service.execute).to eq(migrated: 20, errored: 0)
expect(threads.length).to eq(3)
end
context 'when pages are marked as deployed' do
@ -48,12 +52,24 @@ RSpec.describe Pages::MigrateFromLegacyStorageService do
end
context 'when pages directory does not exist' do
it 'counts project as migrated' do
expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false) do |service|
context 'when mark_projects_as_not_deployed is set' do
let(:mark_projects_as_not_deployed) { true }
it 'counts project as migrated' do
expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false, mark_projects_as_not_deployed: true) do |service|
expect(service).to receive(:execute).and_call_original
end
expect(service.execute).to eq(migrated: 1, errored: 0)
end
end
it 'counts project as errored' do
expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false, mark_projects_as_not_deployed: false) do |service|
expect(service).to receive(:execute).and_call_original
end
expect(service.execute).to eq(migrated: 1, errored: 0)
expect(service.execute).to eq(migrated: 0, errored: 1)
end
end
@ -66,7 +82,7 @@ RSpec.describe Pages::MigrateFromLegacyStorageService do
end
it 'migrates pages projects without deployments' do
expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false) do |service|
expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false, mark_projects_as_not_deployed: false) do |service|
expect(service).to receive(:execute).and_call_original
end

View File

@ -11,47 +11,47 @@ RSpec.describe Pages::MigrateLegacyStorageToDeploymentService do
expect(zip_service).to receive(:execute).and_call_original
end
expect(described_class.new(project, ignore_invalid_entries: true).execute[:status]).to eq(:success)
expect(described_class.new(project, ignore_invalid_entries: true).execute[:status]).to eq(:error)
end
it 'marks pages as not deployed if public directory is absent' do
project.mark_pages_as_deployed
context 'when mark_projects_as_not_deployed is passed' do
let(:service) { described_class.new(project, mark_projects_as_not_deployed: true) }
expect(project.pages_metadatum.reload.deployed).to eq(true)
it 'marks pages as not deployed if public directory is absent and invalid entries are ignored' do
project.mark_pages_as_deployed
expect(project.pages_metadatum.reload.deployed).to eq(true)
expect(service.execute).to(
eq(status: :success,
message: "Archive not created. Missing public directory in #{project.pages_path} ? Marked project as not deployed")
)
expect(service.execute).to(
eq(status: :success,
message: "Archive not created. Missing public directory in #{project.pages_path}? Marked project as not deployed")
)
expect(project.pages_metadatum.reload.deployed).to eq(false)
expect(project.pages_metadatum.reload.deployed).to eq(false)
end
it 'does not mark pages as not deployed if public directory is absent but pages_deployment exists' do
deployment = create(:pages_deployment, project: project)
project.update_pages_deployment!(deployment)
project.mark_pages_as_deployed
expect(project.pages_metadatum.reload.deployed).to eq(true)
expect(service.execute).to(
eq(status: :success,
message: "Archive not created. Missing public directory in #{project.pages_path}? Marked project as not deployed")
)
expect(project.pages_metadatum.reload.deployed).to eq(true)
end
end
it 'does not mark pages as not deployed if public directory is absent but pages_deployment exists' do
deployment = create(:pages_deployment, project: project)
project.update_pages_deployment!(deployment)
project.mark_pages_as_deployed
expect(project.pages_metadatum.reload.deployed).to eq(true)
expect(service.execute).to(
eq(status: :success,
message: "Archive not created. Missing public directory in #{project.pages_path} ? Marked project as not deployed")
)
expect(project.pages_metadatum.reload.deployed).to eq(true)
end
it 'does not mark pages as not deployed if public directory is absent but feature is disabled' do
stub_feature_flags(pages_migration_mark_as_not_deployed: false)
it 'does not mark pages as not deployed if public directory is absent but invalid entries are not ignored' do
project.mark_pages_as_deployed
expect(project.pages_metadatum.reload.deployed).to eq(true)
expect(service.execute).to(
eq(status: :error,
message: "Can't create zip archive: Can not find valid public dir in #{project.pages_path}")
message: "Archive not created. Missing public directory in #{project.pages_path}")
)
expect(project.pages_metadatum.reload.deployed).to eq(true)

View File

@ -33,15 +33,6 @@ RSpec.describe Pages::ZipDirectoryService do
expect(archive).to be_nil
expect(entries_count).to be_nil
end
it 'returns error if pages_migration_mark_as_not_deployed is disabled' do
stub_feature_flags(pages_migration_mark_as_not_deployed: false)
expect(status).to eq(:error)
expect(message).to eq("Can not find valid public dir in #{service_directory}")
expect(archive).to be_nil
expect(entries_count).to be_nil
end
end
context "when work direcotry doesn't exist" do

View File

@ -14,7 +14,8 @@ RSpec.describe 'gitlab:pages' do
expect_next_instance_of(::Pages::MigrateFromLegacyStorageService, anything,
migration_threads: 3,
batch_size: 10,
ignore_invalid_entries: false) do |service|
ignore_invalid_entries: false,
mark_projects_as_not_deployed: false) do |service|
expect(service).to receive(:execute).and_call_original
end
@ -27,7 +28,8 @@ RSpec.describe 'gitlab:pages' do
expect_next_instance_of(::Pages::MigrateFromLegacyStorageService, anything,
migration_threads: 5,
batch_size: 10,
ignore_invalid_entries: false) do |service|
ignore_invalid_entries: false,
mark_projects_as_not_deployed: false) do |service|
expect(service).to receive(:execute).and_call_original
end
@ -40,7 +42,8 @@ RSpec.describe 'gitlab:pages' do
expect_next_instance_of(::Pages::MigrateFromLegacyStorageService, anything,
migration_threads: 3,
batch_size: 100,
ignore_invalid_entries: false) do |service|
ignore_invalid_entries: false,
mark_projects_as_not_deployed: false) do |service|
expect(service).to receive(:execute).and_call_original
end
@ -53,7 +56,22 @@ RSpec.describe 'gitlab:pages' do
expect_next_instance_of(::Pages::MigrateFromLegacyStorageService, anything,
migration_threads: 3,
batch_size: 10,
ignore_invalid_entries: true) do |service|
ignore_invalid_entries: true,
mark_projects_as_not_deployed: false) do |service|
expect(service).to receive(:execute).and_call_original
end
subject
end
it 'uses PAGES_MIGRATION_MARK_PROJECTS_AS_NOT_DEPLOYED environment variable' do
stub_env('PAGES_MIGRATION_MARK_PROJECTS_AS_NOT_DEPLOYED', 'true')
expect_next_instance_of(::Pages::MigrateFromLegacyStorageService, anything,
migration_threads: 3,
batch_size: 10,
ignore_invalid_entries: false,
mark_projects_as_not_deployed: true) do |service|
expect(service).to receive(:execute).and_call_original
end

View File

@ -36,8 +36,10 @@ RSpec.describe Database::BatchedBackgroundMigrationWorker, '#perform', :clean_gi
end
context 'when active migrations exist' do
let(:job_interval) { 5.minutes }
let(:lease_timeout) { 15.minutes }
let(:lease_key) { 'batched_background_migration_worker' }
let(:migration) { build(:batched_background_migration, :active, interval: 2.minutes) }
let(:migration) { build(:batched_background_migration, :active, interval: job_interval) }
before do
allow(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:active_migration)
@ -49,7 +51,7 @@ RSpec.describe Database::BatchedBackgroundMigrationWorker, '#perform', :clean_gi
context 'when the reloaded migration is no longer active' do
it 'does not run the migration' do
expect_to_obtain_exclusive_lease(lease_key, timeout: 4.minutes)
expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
expect(migration).to receive(:reload)
expect(migration).to receive(:active?).and_return(false)
@ -62,7 +64,7 @@ RSpec.describe Database::BatchedBackgroundMigrationWorker, '#perform', :clean_gi
context 'when the interval has not elapsed' do
it 'does not run the migration' do
expect_to_obtain_exclusive_lease(lease_key, timeout: 4.minutes)
expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
expect(migration).to receive(:interval_elapsed?).and_return(false)
@ -74,7 +76,24 @@ RSpec.describe Database::BatchedBackgroundMigrationWorker, '#perform', :clean_gi
context 'when the reloaded migration is still active and the interval has elapsed' do
it 'runs the migration' do
expect_to_obtain_exclusive_lease(lease_key, timeout: 4.minutes)
expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
expect_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |instance|
expect(instance).to receive(:run_migration_job).with(migration)
end
expect(worker).to receive(:run_active_migration).and_call_original
worker.perform
end
end
context 'when the calculated timeout is less than the minimum allowed' do
let(:minimum_timeout) { described_class::MINIMUM_LEASE_TIMEOUT }
let(:job_interval) { 2.minutes }
it 'sets the lease timeout to the minimum value' do
expect_to_obtain_exclusive_lease(lease_key, timeout: minimum_timeout)
expect_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |instance|
expect(instance).to receive(:run_migration_job).with(migration)
@ -87,7 +106,7 @@ RSpec.describe Database::BatchedBackgroundMigrationWorker, '#perform', :clean_gi
end
it 'always cleans up the exclusive lease' do
lease = stub_exclusive_lease_taken(lease_key, timeout: 4.minutes)
lease = stub_exclusive_lease_taken(lease_key, timeout: lease_timeout)
expect(lease).to receive(:try_obtain).and_return(true)