Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
24f32a55ee
commit
991c66333d
|
@ -90,7 +90,7 @@ Layout/FirstArrayElementIndentation:
|
|||
- 'ee/spec/lib/gitlab/ci/templates/Jobs/load_performance_testing_gitlab_ci_yaml_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/ci/yaml_processor_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/epics/epic_node_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_block_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_links_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/loaders/bulk_epic_aggregate_loader_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_builds_metric_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_ci_builds_metric_spec.rb'
|
||||
|
|
|
@ -501,7 +501,7 @@ RSpec/ContextWording:
|
|||
- 'ee/spec/lib/gitlab/gl_repository/repo_type_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/epics/epic_node_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/epics/lazy_epic_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_block_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_links_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/security_orchestration_policies/lazy_dast_profile_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/vulnerabilities/lazy_user_notes_count_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/vulnerability_statistics/lazy_aggregate_spec.rb'
|
||||
|
|
|
@ -46,7 +46,7 @@ RSpec/ExpectInHook:
|
|||
- 'ee/spec/lib/gitlab/geo_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/git_access_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/epics/lazy_epic_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_block_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_links_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/mirror_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/sitemaps/generator_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/subscription_portal/clients/graphql_spec.rb'
|
||||
|
|
|
@ -82,7 +82,7 @@ RSpec/VerifiedDoubles:
|
|||
- ee/spec/lib/gitlab/geo/replicator_spec.rb
|
||||
- ee/spec/lib/gitlab/geo_spec.rb
|
||||
- ee/spec/lib/gitlab/git_access_spec.rb
|
||||
- ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_block_aggregate_spec.rb
|
||||
- ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_links_aggregate_spec.rb
|
||||
- ee/spec/lib/gitlab/import_export/group/relation_factory_spec.rb
|
||||
- ee/spec/lib/gitlab/middleware/ip_restrictor_spec.rb
|
||||
- ee/spec/lib/gitlab/patch/legacy_database_config_spec.rb
|
||||
|
|
|
@ -716,7 +716,7 @@ Style/IfUnlessModifier:
|
|||
- 'ee/lib/gitlab/geo/replication/blob_downloader.rb'
|
||||
- 'ee/lib/gitlab/geo/replicator.rb'
|
||||
- 'ee/lib/gitlab/graphql/aggregations/epics/lazy_epic_aggregate.rb'
|
||||
- 'ee/lib/gitlab/graphql/aggregations/issues/lazy_block_aggregate.rb'
|
||||
- 'ee/lib/gitlab/graphql/aggregations/issues/lazy_links_aggregate.rb'
|
||||
- 'ee/lib/gitlab/graphql/aggregations/security_orchestration_policies/lazy_dast_profile_aggregate.rb'
|
||||
- 'ee/lib/gitlab/graphql/aggregations/vulnerabilities/lazy_user_notes_count_aggregate.rb'
|
||||
- 'ee/lib/gitlab/graphql/aggregations/vulnerability_statistics/lazy_aggregate.rb'
|
||||
|
|
|
@ -133,7 +133,7 @@ Style/SymbolProc:
|
|||
- 'ee/spec/helpers/ee/registrations_helper_spec.rb'
|
||||
- 'ee/spec/lib/ee/gitlab/search_results_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/elastic/document_reference_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_block_aggregate_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_links_aggregate_spec.rb'
|
||||
- 'ee/spec/models/ee/iterations/cadence_spec.rb'
|
||||
- 'ee/spec/services/groups/participants_service_spec.rb'
|
||||
- 'ee/spec/support/helpers/subscription_portal_helpers.rb'
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -344,7 +344,7 @@ gem 'prometheus-client-mmap', '~> 0.15.0', require: 'prometheus/client'
|
|||
gem 'warning', '~> 1.2.0'
|
||||
|
||||
group :development do
|
||||
gem 'lefthook', '~> 0.8.0', require: false
|
||||
gem 'lefthook', '~> 1.0.0', require: false
|
||||
gem 'rubocop'
|
||||
gem 'solargraph', '~> 0.44.3', require: false
|
||||
|
||||
|
|
|
@ -724,7 +724,7 @@ GEM
|
|||
rest-client (~> 2.0)
|
||||
launchy (2.5.0)
|
||||
addressable (~> 2.7)
|
||||
lefthook (0.8.0)
|
||||
lefthook (1.0.0)
|
||||
letter_opener (1.7.0)
|
||||
launchy (~> 2.2)
|
||||
letter_opener_web (2.0.0)
|
||||
|
@ -1586,7 +1586,7 @@ DEPENDENCIES
|
|||
knapsack (~> 1.21.1)
|
||||
kramdown (~> 2.3.1)
|
||||
kubeclient (~> 4.9.2)
|
||||
lefthook (~> 0.8.0)
|
||||
lefthook (~> 1.0.0)
|
||||
letter_opener_web (~> 2.0.0)
|
||||
licensee (~> 9.14.1)
|
||||
lockbox (~> 0.6.2)
|
||||
|
|
|
@ -243,6 +243,7 @@ export default {
|
|||
:description="label.description"
|
||||
size="sm"
|
||||
:scoped="showScopedLabel(label)"
|
||||
target="#"
|
||||
@click="filterByLabel(label)"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -254,7 +254,6 @@ export default {
|
|||
</section-layout>
|
||||
</gl-tab>
|
||||
<gl-tab
|
||||
v-if="securityTrainingEnabled"
|
||||
data-testid="vulnerability-management-tab"
|
||||
:title="$options.i18n.vulnerabilityManagement"
|
||||
query-param-value="vulnerability-management"
|
||||
|
@ -271,7 +270,7 @@ export default {
|
|||
</p>
|
||||
</template>
|
||||
<template #features>
|
||||
<training-provider-list />
|
||||
<training-provider-list :security-training-enabled="securityTrainingEnabled" />
|
||||
</template>
|
||||
</section-layout>
|
||||
</gl-tab>
|
||||
|
|
|
@ -39,6 +39,7 @@ const i18n = {
|
|||
primaryTrainingDescription: s__(
|
||||
'SecurityTraining|Training from this partner takes precedence when more than one training partner is enabled.',
|
||||
),
|
||||
unavailableText: s__('SecurityConfiguration|Available with Ultimate'),
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -73,6 +74,13 @@ export default {
|
|||
},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
securityTrainingEnabled: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
errorMessage: '',
|
||||
|
@ -232,12 +240,13 @@ export default {
|
|||
</div>
|
||||
<ul v-else class="gl-list-style-none gl-m-0 gl-p-0">
|
||||
<li v-for="provider in securityTrainingProviders" :key="provider.id" class="gl-mb-6">
|
||||
<gl-card>
|
||||
<gl-card :body-class="{ 'gl-bg-gray-10': !securityTrainingEnabled }">
|
||||
<div class="gl-display-flex">
|
||||
<gl-toggle
|
||||
:value="provider.isEnabled"
|
||||
:label="__('Training mode')"
|
||||
label-position="hidden"
|
||||
:disabled="!securityTrainingEnabled"
|
||||
@change="toggleProvider(provider)"
|
||||
/>
|
||||
<div v-if="$options.TEMP_PROVIDER_LOGOS[provider.name]" class="gl-ml-4">
|
||||
|
@ -249,7 +258,18 @@ export default {
|
|||
></div>
|
||||
</div>
|
||||
<div class="gl-ml-3">
|
||||
<h3 class="gl-font-lg gl-m-0 gl-mb-2">{{ provider.name }}</h3>
|
||||
<div class="gl-display-flex gl-justify-content-space-between">
|
||||
<h3 class="gl-font-lg gl-m-0 gl-mb-2">
|
||||
{{ provider.name }}
|
||||
</h3>
|
||||
<span
|
||||
v-if="!securityTrainingEnabled"
|
||||
data-testid="unavailable-text"
|
||||
class="gl-text-gray-600"
|
||||
>
|
||||
{{ $options.i18n.unavailableText }}
|
||||
</span>
|
||||
</div>
|
||||
<p>
|
||||
{{ provider.description }}
|
||||
<gl-link
|
||||
|
@ -263,7 +283,7 @@ export default {
|
|||
</p>
|
||||
<gl-form-radio
|
||||
:checked="primaryProviderId"
|
||||
:disabled="!provider.isEnabled"
|
||||
:disabled="!securityTrainingEnabled || !provider.isEnabled"
|
||||
:value="provider.id"
|
||||
@change="setPrimaryProvider(provider)"
|
||||
>
|
||||
|
|
|
@ -139,8 +139,8 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="md-suggestion-header border-bottom-0 mt-2">
|
||||
<div class="js-suggestion-diff-header font-weight-bold">
|
||||
<div class="md-suggestion-header border-bottom-0 gl-mt-3">
|
||||
<div class="js-suggestion-diff-header gl-font-weight-bold">
|
||||
{{ __('Suggested change') }}
|
||||
<a v-if="helpPagePath" :href="helpPagePath" :aria-label="__('Help')" class="js-help-btn">
|
||||
<gl-icon name="question-o" css-classes="link-highlight" />
|
||||
|
@ -151,13 +151,13 @@ export default {
|
|||
</gl-badge>
|
||||
<div
|
||||
v-else-if="isApplying"
|
||||
class="d-flex align-items-center text-secondary"
|
||||
class="gl-display-flex gl-align-items-center text-secondary"
|
||||
data-qa-selector="applying_badge"
|
||||
>
|
||||
<gl-loading-icon size="sm" class="d-flex-center mr-2" />
|
||||
<gl-loading-icon size="sm" class="gl-align-items-center gl-justify-content-center gl-mr-3" />
|
||||
<span>{{ applyingSuggestionsMessage }}</span>
|
||||
</div>
|
||||
<div v-else-if="isLoggedIn" class="d-flex align-items-center">
|
||||
<div v-else-if="isLoggedIn" class="gl-display-flex gl-align-items-center">
|
||||
<div v-if="isBatched">
|
||||
<gl-button
|
||||
class="btn-inverted js-remove-from-batch-btn btn-grouped"
|
||||
|
|
|
@ -70,7 +70,7 @@ $column-right-gradient: linear-gradient(to right, $gradient-dark-gray 0%, $gradi
|
|||
|
||||
.timeline-header-blank,
|
||||
.timeline-header-item {
|
||||
@include float-left;
|
||||
@include gl-float-left;
|
||||
height: $header-item-height;
|
||||
border-bottom: $border-style;
|
||||
background-color: var(--white, $white);
|
||||
|
@ -150,7 +150,7 @@ $column-right-gradient: linear-gradient(to right, $gradient-dark-gray 0%, $gradi
|
|||
|
||||
.details-cell,
|
||||
.timeline-cell {
|
||||
@include float-left;
|
||||
@include gl-float-left;
|
||||
height: $item-height;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,13 +39,13 @@ module Git
|
|||
def enqueue_update_mrs
|
||||
return if params[:merge_request_branches]&.exclude?(branch_name)
|
||||
|
||||
# TODO: pass params[:push_options] to worker
|
||||
UpdateMergeRequestsWorker.perform_async(
|
||||
project.id,
|
||||
current_user.id,
|
||||
oldrev,
|
||||
newrev,
|
||||
ref
|
||||
ref,
|
||||
params.slice(:push_options).deep_stringify_keys
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -190,8 +190,11 @@ module MergeRequests
|
|||
|
||||
def create_pipeline_for(merge_request, user, async: false)
|
||||
if async
|
||||
# TODO: pass push_options to worker
|
||||
MergeRequests::CreatePipelineWorker.perform_async(project.id, user.id, merge_request.id)
|
||||
MergeRequests::CreatePipelineWorker.perform_async(
|
||||
project.id,
|
||||
user.id,
|
||||
merge_request.id,
|
||||
params.slice(:push_options).deep_stringify_keys)
|
||||
else
|
||||
MergeRequests::CreatePipelineService
|
||||
.new(project: project, current_user: user, params: params.slice(:push_options))
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
- if @domain.remove_at
|
||||
%p
|
||||
Unless you verify your domain by
|
||||
%strong= @domain.remove_at.strftime('%F %T,')
|
||||
it will be removed from your GitLab project.
|
||||
- else
|
||||
%p
|
||||
If you no longer wish to use this domain with GitLab Pages, please remove it
|
||||
from your GitLab project and delete any related DNS records.
|
||||
%p
|
||||
- if @domain.remove_at
|
||||
= s_('Notify|Unless you verify your domain by %{time_start}%{time}%{time_end} it will be removed from your GitLab project.').html_safe % { time_start: '<strong>'.html_safe, time_end: '</strong>'.html_safe, time: @domain.remove_at.strftime('%F %T,') }
|
||||
- else
|
||||
= s_('Notify|If you no longer wish to use this domain with GitLab Pages, please remove it from your GitLab project and delete any related DNS records.')
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
.col-12
|
||||
.svg-content
|
||||
= image_tag 'illustrations/snippets_empty.svg', data: { qa_selector: 'svg_content' }
|
||||
.text-content.text-center.pt-0
|
||||
.text-content.gl-text-center.gl-pt-0
|
||||
- if current_user
|
||||
%h4
|
||||
= s_('SnippetsEmptyState|Code snippets')
|
||||
%p.mb-0
|
||||
%p.gl-mb-0
|
||||
= s_('SnippetsEmptyState|Store, share, and embed small pieces of code and text.')
|
||||
.mt-2<
|
||||
.gl-mt-3<
|
||||
- if button_path
|
||||
= link_to s_('SnippetsEmptyState|New snippet'), button_path, class: 'btn gl-button btn-confirm', title: s_('SnippetsEmptyState|New snippet'), id: 'new_snippet_link', data: { qa_selector: 'create_first_snippet_link' }
|
||||
= link_to s_('SnippetsEmptyState|Documentation'), help_page_path('user/snippets.md'), class: 'btn gl-button btn-default', title: s_('SnippetsEmptyState|Documentation')
|
||||
- else
|
||||
%h4.text-center= s_('SnippetsEmptyState|There are no snippets to show.')
|
||||
%h4.gl-text-center= s_('SnippetsEmptyState|There are no snippets to show.')
|
||||
|
|
|
@ -123,7 +123,7 @@ The following are required to run Geo:
|
|||
- PostgreSQL 13 is not supported for Geo, see [epic 3832](https://gitlab.com/groups/gitlab-org/-/epics/3832)
|
||||
- Git 2.9 or later
|
||||
- Git-lfs 2.4.2 or later on the user side when using LFS
|
||||
- All sites must run the same GitLab version.
|
||||
- All sites must run [the same GitLab and PostgreSQL versions](setup/database.md#postgresql-replication).
|
||||
|
||||
Additionally, check the GitLab [minimum requirements](../../install/requirements.md),
|
||||
and we recommend you use the latest version of GitLab for a better experience.
|
||||
|
|
|
@ -52,8 +52,9 @@ The following guide assumes that:
|
|||
which includes the [`pg_basebackup` tool](https://www.postgresql.org/docs/12/app-pgbasebackup.html).
|
||||
- You have a **primary** node already set up (the GitLab server you are
|
||||
replicating from), running Omnibus' PostgreSQL (or equivalent version), and
|
||||
you have a new **secondary** server set up with the same versions of the OS,
|
||||
PostgreSQL, and GitLab on all nodes.
|
||||
you have a new **secondary** server set up with the same
|
||||
[versions of PostgreSQL](../index.md#requirements-for-running-geo),
|
||||
OS, and GitLab on all nodes.
|
||||
|
||||
WARNING:
|
||||
Geo works with streaming replication. Logical replication is not supported at this time.
|
||||
|
@ -478,7 +479,7 @@ data before running `pg_basebackup`.
|
|||
```shell
|
||||
gitlab-ctl replicate-geo-database \
|
||||
--slot-name=<secondary_node_name> \
|
||||
--host=<primary_node_ip>
|
||||
--host=<primary_node_ip> \
|
||||
--sslmode=verify-ca
|
||||
```
|
||||
|
||||
|
|
|
@ -10,6 +10,11 @@ This document is relevant if you are using a PostgreSQL instance that is *not
|
|||
managed by Omnibus*. This includes cloud-managed instances like Amazon RDS, or
|
||||
manually installed and configured PostgreSQL instances.
|
||||
|
||||
Ensure that you are using one of the PostgreSQL versions that
|
||||
[Omnibus ships with](../../package_information/postgresql_versions.md)
|
||||
to [avoid version mismatches](../index.md#requirements-for-running-geo)
|
||||
in case a Geo site has to be rebuilt.
|
||||
|
||||
NOTE:
|
||||
We strongly recommend running Omnibus-managed instances as they are actively
|
||||
developed and tested. We aim to be compatible with most external
|
||||
|
|
|
@ -25,12 +25,11 @@ The following lists the currently supported OSs and their possible EOL dates.
|
|||
| OpenSUSE 15.3 | GitLab CE / GitLab EE 14.5.0 | x86_64, aarch64 | [OpenSUSE Install Docs](https://about.gitlab.com/install/#opensuse-leap-15-3) | Nov 2022 | <https://en.opensuse.org/Lifetime> |
|
||||
| RHEL 8 | GitLab CE / GitLab EE 12.8.1 | x86_64, arm64 | [Use CentOS Install Docs](https://about.gitlab.com/install/#centos-7) | May 2024 | [RHEL Details](https://access.redhat.com/support/policy/updates/errata/#Life_Cycle_Dates) |
|
||||
| SLES 12 | GitLab EE 9.0.0 | x86_64 | [Use OpenSUSE Install Docs](https://about.gitlab.com/install/#opensuse-leap-15-3) | Oct 2027 | <https://www.suse.com/lifecycle/> |
|
||||
|
||||
| Oracle Linux | GitLab CE / GitLab EE 8.14.0 | x86_64 | [Use CentOS Install Docs](https://about.gitlab.com/install/#centos-7) | Jul 2024 | <https://www.oracle.com/a/ocom/docs/elsp-lifetime-069338.pdf> |
|
||||
| Scientific Linux | GitLab CE / GitLab EE 8.14.0 | x86_64 | [Use CentOS Install Docs](https://about.gitlab.com/install/#centos-7) | June 2024 | <https://scientificlinux.org/downloads/sl-versions/sl7/> |
|
||||
| Ubuntu 18.04 | GitLab CE / GitLab EE 10.7.0 | amd64 | [Ubuntu Install Docs](https://about.gitlab.com/install/#ubuntu) | April 2023 | <https://wiki.ubuntu.com/Releases> |
|
||||
| Ubuntu 20.04 | GitLab CE / GitLab EE 13.2.0 | amd64, arm64 | [Ubuntu Install Docs](https://about.gitlab.com/install/#ubuntu) | April 2025 | <https://wiki.ubuntu.com/Releases> |
|
||||
| Amazon Linux 2 | GitLab CE / GitLab EE 14.9.0 | amd64, arm64 | [Amazon Linux 2 Instal Docsl](https://about.gitlab.com/install/#amazonlinux-2) | June 2023 | <https://aws.amazon.com/amazon-linux-2/faqs/> |
|
||||
| Amazon Linux 2 | GitLab CE / GitLab EE 14.9.0 | amd64, arm64 | [Amazon Linux 2 Install Docs](https://about.gitlab.com/install/#amazonlinux-2) | June 2023 | <https://aws.amazon.com/amazon-linux-2/faqs/> |
|
||||
| Raspberry Pi OS (Buster) (formerly known as Raspbian Buster) | GitLab CE 12.2.0 | armhf | [Raspberry Pi Install Docs](https://about.gitlab.com/install/#raspberry-pi-os) | 2024 | [Raspberry Pi Details](https://www.raspberrypi.com/news/new-old-functionality-with-raspberry-pi-os-legacy/) |
|
||||
|
||||
NOTE:
|
||||
|
|
|
@ -1275,11 +1275,16 @@ project = Project.find_by_full_path('<group/project>')
|
|||
Geo::RepositorySyncService.new(project).execute
|
||||
```
|
||||
|
||||
### Blob types newer than uploads/artifacts/LFS
|
||||
### Blob types
|
||||
|
||||
- `Packages::PackageFile`
|
||||
- `Terraform::StateVersion`
|
||||
- `Ci::JobArtifact`
|
||||
- `Ci::PipelineArtifact`
|
||||
- `LfsObject`
|
||||
- `MergeRequestDiff`
|
||||
- `Packages::PackageFile`
|
||||
- `PagesDeployment`
|
||||
- `Terraform::StateVersion`
|
||||
- `Upload`
|
||||
|
||||
`Packages::PackageFile` is used in the following examples, but things generally work the same for the other Blob types.
|
||||
|
||||
|
|
|
@ -110,8 +110,7 @@ https://gitlab.domain.tld/api/v4/jobs/request: Post https://gitlab.domain.tld/ap
|
|||
x509: certificate signed by unknown authority
|
||||
```
|
||||
|
||||
If you encounter a similar problem, add your certificate to `/etc/gitlab-runner/certs`,
|
||||
and the restart the runner by running `gitlab-runner restart`.
|
||||
Follow the details in [Self-signed certificates or custom Certification Authorities for GitLab Runner](https://docs.gitlab.com/runner/configuration/tls-self-signed.html).
|
||||
|
||||
## Mirroring a remote GitLab repository that uses a self-signed SSL certificate
|
||||
|
||||
|
|
|
@ -427,6 +427,8 @@ following command to get address of current Redis primary
|
|||
|
||||
#### In the Redis secondary nodes
|
||||
|
||||
1. Set `gitlab_rails['rake_cache_clear'] = false` in `gitlab.rb` if you haven't already. If not, you might receive the error `Redis::CommandError: READONLY You can't write against a read only replica.` during the reconfigure post installation of new package.
|
||||
|
||||
1. Install package for new version.
|
||||
|
||||
1. Run `sudo gitlab-ctl reconfigure`, if a reconfigure is not run as part of
|
||||
|
|
|
@ -49,7 +49,7 @@ If you have multiple GitLab projects that contain Kubernetes manifests:
|
|||
|
||||
## Authorize the agent
|
||||
|
||||
You must authorize the agent to access the project where you keep your Kubernetes manifests.
|
||||
If you have multiple GitLab projects, you must authorize the agent to access the project where you keep your Kubernetes manifests.
|
||||
You can authorize the agent to access individual projects, or authorize a group or subgroup,
|
||||
so all projects within have access. For added security, you can also
|
||||
[use impersonation](#use-impersonation-to-restrict-project-and-group-access).
|
||||
|
@ -60,7 +60,7 @@ so all projects within have access. For added security, you can also
|
|||
|
||||
To authorize the agent to access the GitLab project where you keep Kubernetes manifests:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find the project that contains the agent configuration file (`config.yaml`).
|
||||
1. On the top bar, select **Menu > Projects** and find the project that contains the [agent configuration file](install/index.md#create-an-agent-configuration-file) (`config.yaml`).
|
||||
1. Edit the `config.yaml` file. Under the `ci_access` keyword, add the `projects` attribute.
|
||||
1. For the `id`, add the path:
|
||||
|
||||
|
@ -83,7 +83,7 @@ Choose the context to run `kubectl` commands from your CI/CD scripts.
|
|||
|
||||
To authorize the agent to access all of the GitLab projects in a group or subgroup:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find the project that contains the agent configuration file (`config.yaml`).
|
||||
1. On the top bar, select **Menu > Projects** and find the project that contains the [agent configuration file](install/index.md#create-an-agent-configuration-file) (`config.yaml`).
|
||||
1. Edit the `config.yaml` file. Under the `ci_access` keyword, add the `groups` attribute.
|
||||
1. For the `id`, add the path:
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ Any time you commit updates to your Kubernetes manifests, the agent updates the
|
|||
|
||||
## GitOps configuration reference
|
||||
|
||||
The following snippet shows an example of the possible keys and values for the GitOps section of an agent configuration file.
|
||||
The following snippet shows an example of the possible keys and values for the GitOps section of an [agent configuration file](install/index.md#create-an-agent-configuration-file) (`config.yaml`).
|
||||
|
||||
```yaml
|
||||
gitops:
|
||||
|
|
|
@ -26158,6 +26158,9 @@ msgstr ""
|
|||
msgid "Notify|Author: %{author_name}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Notify|If you no longer wish to use this domain with GitLab Pages, please remove it from your GitLab project and delete any related DNS records."
|
||||
msgstr ""
|
||||
|
||||
msgid "Notify|Issue was %{issue_status} by %{updated_by}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -26185,6 +26188,9 @@ msgstr ""
|
|||
msgid "Notify|This issue is due on: %{issue_due_date}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Notify|Unless you verify your domain by %{time_start}%{time}%{time_end} it will be removed from your GitLab project."
|
||||
msgstr ""
|
||||
|
||||
msgid "Notify|You don't have access to the project."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -442,42 +442,33 @@ describe('App component', () => {
|
|||
});
|
||||
|
||||
describe('Vulnerability management', () => {
|
||||
it('does not show tab if security training is disabled', () => {
|
||||
const props = { securityTrainingEnabled: true };
|
||||
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
securityTrainingEnabled: false,
|
||||
...props,
|
||||
});
|
||||
|
||||
expect(findVulnerabilityManagementTab().exists()).toBe(false);
|
||||
});
|
||||
|
||||
describe('security training enabled', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
});
|
||||
});
|
||||
it('shows the tab', () => {
|
||||
expect(findVulnerabilityManagementTab().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('shows the tab if security training is enabled', () => {
|
||||
expect(findVulnerabilityManagementTab().exists()).toBe(true);
|
||||
});
|
||||
it('renders TrainingProviderList component', () => {
|
||||
expect(findTrainingProviderList().props()).toMatchObject(props);
|
||||
});
|
||||
|
||||
it('renders TrainingProviderList component', () => {
|
||||
expect(findTrainingProviderList().exists()).toBe(true);
|
||||
});
|
||||
it('renders security training description', () => {
|
||||
expect(findVulnerabilityManagementTab().text()).toContain(i18n.securityTrainingDescription);
|
||||
});
|
||||
|
||||
it('renders security training description', () => {
|
||||
expect(findVulnerabilityManagementTab().text()).toContain(i18n.securityTrainingDescription);
|
||||
});
|
||||
it('renders link to help docs', () => {
|
||||
const trainingLink = findVulnerabilityManagementTab().findComponent(GlLink);
|
||||
|
||||
it('renders link to help docs', () => {
|
||||
const trainingLink = findVulnerabilityManagementTab().findComponent(GlLink);
|
||||
|
||||
expect(trainingLink.text()).toBe('Learn more about vulnerability training');
|
||||
expect(trainingLink.attributes('href')).toBe(vulnerabilityTrainingDocsPath);
|
||||
});
|
||||
expect(trainingLink.text()).toBe('Learn more about vulnerability training');
|
||||
expect(trainingLink.attributes('href')).toBe(vulnerabilityTrainingDocsPath);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -76,7 +76,7 @@ describe('TrainingProviderList component', () => {
|
|||
apolloProvider = createMockApollo(mergedHandlers);
|
||||
};
|
||||
|
||||
const createComponent = () => {
|
||||
const createComponent = (props = {}) => {
|
||||
wrapper = shallowMountExtended(TrainingProviderList, {
|
||||
provide: {
|
||||
projectFullPath: testProjectPath,
|
||||
|
@ -84,6 +84,10 @@ describe('TrainingProviderList component', () => {
|
|||
directives: {
|
||||
GlTooltip: createMockDirective(),
|
||||
},
|
||||
propsData: {
|
||||
securityTrainingEnabled: true,
|
||||
...props,
|
||||
},
|
||||
apolloProvider,
|
||||
});
|
||||
};
|
||||
|
@ -99,6 +103,7 @@ describe('TrainingProviderList component', () => {
|
|||
const findLoader = () => wrapper.findComponent(GlSkeletonLoader);
|
||||
const findErrorAlert = () => wrapper.findComponent(GlAlert);
|
||||
const findLogos = () => wrapper.findAllByTestId('provider-logo');
|
||||
const findUnavailableTexts = () => wrapper.findAllByTestId('unavailable-text');
|
||||
|
||||
const toggleFirstProvider = () => findFirstToggle().vm.$emit('change', testProviderIds[0]);
|
||||
|
||||
|
@ -351,6 +356,41 @@ describe('TrainingProviderList component', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('non ultimate users', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
securityTrainingEnabled: false,
|
||||
});
|
||||
await waitForQueryToBeLoaded();
|
||||
});
|
||||
|
||||
it('displays unavailable text', () => {
|
||||
findUnavailableTexts().wrappers.forEach((unavailableText) => {
|
||||
expect(unavailableText.text()).toBe(TrainingProviderList.i18n.unavailableText);
|
||||
});
|
||||
});
|
||||
|
||||
it('has disabled state for toggle', () => {
|
||||
findToggles().wrappers.forEach((toggle) => {
|
||||
expect(toggle.props('disabled')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('has disabled state for radio', () => {
|
||||
findPrimaryProviderRadios().wrappers.forEach((radio) => {
|
||||
expect(radio.attributes('disabled')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('adds backgrounds color', () => {
|
||||
findCards().wrappers.forEach((card) => {
|
||||
expect(card.props('bodyClass')).toMatchObject({
|
||||
'gl-bg-gray-10': true,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('primary provider settings', () => {
|
||||
|
|
|
@ -19,11 +19,13 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
project.add_maintainer(user)
|
||||
end
|
||||
|
||||
describe 'Push branches' do
|
||||
subject do
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref, push_options: push_options)
|
||||
end
|
||||
subject(:execute_service) do
|
||||
described_class
|
||||
.new(project, user, change: { oldrev: oldrev, newrev: newrev, ref: ref }, push_options: push_options)
|
||||
.execute
|
||||
end
|
||||
|
||||
describe 'Push branches' do
|
||||
context 'new branch' do
|
||||
let(:oldrev) { blankrev }
|
||||
|
||||
|
@ -72,8 +74,6 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
end
|
||||
|
||||
describe "Pipelines" do
|
||||
subject { execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref) }
|
||||
|
||||
before do
|
||||
stub_ci_pipeline_to_return_yaml_file
|
||||
end
|
||||
|
@ -117,7 +117,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
end
|
||||
|
||||
context 'with push options' do
|
||||
let(:push_options) { ['mr.create'] }
|
||||
let(:push_options) { { 'mr' => { 'create' => true } } }
|
||||
|
||||
it 'sanitizes push options' do
|
||||
allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
|
||||
|
@ -148,27 +148,34 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
end
|
||||
|
||||
describe "Updates merge requests" do
|
||||
let(:oldrev) { blankrev }
|
||||
|
||||
it "when pushing a new branch for the first time" do
|
||||
expect(UpdateMergeRequestsWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, user.id, blankrev, newrev, ref)
|
||||
.with(project.id, user.id, blankrev, newrev, ref, { 'push_options' => nil })
|
||||
.ordered
|
||||
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
describe "Updates git attributes" do
|
||||
context "for default branch" do
|
||||
it "calls the copy attributes method for the first push to the default branch" do
|
||||
expect(project.repository).to receive(:copy_gitattributes).with('master')
|
||||
context "when first push" do
|
||||
let(:oldrev) { blankrev }
|
||||
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
|
||||
it "calls the copy attributes method for the first push to the default branch" do
|
||||
expect(project.repository).to receive(:copy_gitattributes).with('master')
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
it "calls the copy attributes method for changes to the default branch" do
|
||||
expect(project.repository).to receive(:copy_gitattributes).with(ref)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -181,49 +188,53 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
it "does not call copy attributes method" do
|
||||
expect(project.repository).not_to receive(:copy_gitattributes)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Webhooks" do
|
||||
context "execute webhooks" do
|
||||
before do
|
||||
create(:project_hook, push_events: true, project: project)
|
||||
end
|
||||
before do
|
||||
create(:project_hook, push_events: true, project: project)
|
||||
end
|
||||
|
||||
it "when pushing a branch for the first time" do
|
||||
context "when pushing a branch for the first time" do
|
||||
let(:oldrev) { blankrev }
|
||||
|
||||
it "executes webhooks" do
|
||||
expect(project).to receive(:execute_hooks)
|
||||
expect(project.default_branch).to eq("master")
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
|
||||
|
||||
subject
|
||||
|
||||
expect(project.protected_branches).not_to be_empty
|
||||
expect(project.protected_branches.first.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::MAINTAINER])
|
||||
expect(project.protected_branches.first.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::MAINTAINER])
|
||||
end
|
||||
|
||||
it "when pushing a branch for the first time with default branch protection disabled" do
|
||||
it "with default branch protection disabled" do
|
||||
expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_NONE)
|
||||
|
||||
expect(project).to receive(:execute_hooks)
|
||||
expect(project.default_branch).to eq("master")
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
expect(project.protected_branches).to be_empty
|
||||
end
|
||||
|
||||
it "when pushing a branch for the first time with default branch protection set to 'developers can push'" do
|
||||
it "with default branch protection set to 'developers can push'" do
|
||||
expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_DEV_CAN_PUSH)
|
||||
|
||||
expect(project).to receive(:execute_hooks)
|
||||
expect(project.default_branch).to eq("master")
|
||||
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(project.protected_branches).not_to be_empty
|
||||
expect(project.protected_branches.last.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
|
||||
expect(project.protected_branches.last.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::MAINTAINER])
|
||||
end
|
||||
|
||||
it "when pushing a branch for the first time with an existing branch permission configured" do
|
||||
it "with an existing branch permission configured" do
|
||||
expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_DEV_CAN_PUSH)
|
||||
|
||||
create(:protected_branch, :no_one_can_push, :developers_can_merge, project: project, name: 'master')
|
||||
|
@ -231,27 +242,29 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
expect(project.default_branch).to eq("master")
|
||||
expect(ProtectedBranches::CreateService).not_to receive(:new)
|
||||
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(project.protected_branches).not_to be_empty
|
||||
expect(project.protected_branches.last.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::NO_ACCESS])
|
||||
expect(project.protected_branches.last.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
|
||||
end
|
||||
|
||||
it "when pushing a branch for the first time with default branch protection set to 'developers can merge'" do
|
||||
it "with default branch protection set to 'developers can merge'" do
|
||||
expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_DEV_CAN_MERGE)
|
||||
|
||||
expect(project).to receive(:execute_hooks)
|
||||
expect(project.default_branch).to eq("master")
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
expect(project.protected_branches).not_to be_empty
|
||||
expect(project.protected_branches.first.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::MAINTAINER])
|
||||
expect(project.protected_branches.first.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
|
||||
end
|
||||
end
|
||||
|
||||
it "when pushing new commits to existing branch" do
|
||||
context "when pushing new commits to existing branch" do
|
||||
it "executes webhooks" do
|
||||
expect(project).to receive(:execute_hooks)
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -281,7 +294,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
it "creates a note if a pushed commit mentions an issue", :sidekiq_might_not_need_inline do
|
||||
expect(SystemNoteService).to receive(:cross_reference).with(issue, commit, commit_author)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
|
||||
it "only creates a cross-reference note if one doesn't already exist" do
|
||||
|
@ -289,7 +302,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
|
||||
expect(SystemNoteService).not_to receive(:cross_reference).with(issue, commit, commit_author)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
|
||||
it "defaults to the pushing user if the commit's author is not known", :sidekiq_inline, :use_clean_rails_redis_caching do
|
||||
|
@ -299,16 +312,21 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
)
|
||||
expect(SystemNoteService).to receive(:cross_reference).with(issue, commit, user)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
|
||||
it "finds references in the first push to a non-default branch", :sidekiq_might_not_need_inline do
|
||||
allow(project.repository).to receive(:commits_between).with(blankrev, newrev).and_return([])
|
||||
allow(project.repository).to receive(:commits_between).with("master", newrev).and_return([commit])
|
||||
context "when first push on a non-default branch" do
|
||||
let(:oldrev) { blankrev }
|
||||
let(:ref) { 'refs/heads/other' }
|
||||
|
||||
expect(SystemNoteService).to receive(:cross_reference).with(issue, commit, commit_author)
|
||||
it "finds references", :sidekiq_might_not_need_inline do
|
||||
allow(project.repository).to receive(:commits_between).with(blankrev, newrev).and_return([])
|
||||
allow(project.repository).to receive(:commits_between).with("master", newrev).and_return([commit])
|
||||
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: 'refs/heads/other')
|
||||
expect(SystemNoteService).to receive(:cross_reference).with(issue, commit, commit_author)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -338,14 +356,14 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
|
||||
context "while saving the 'first_mentioned_in_commit_at' metric for an issue" do
|
||||
it 'sets the metric for referenced issues', :sidekiq_inline, :use_clean_rails_redis_caching do
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(issue.reload.metrics.first_mentioned_in_commit_at).to be_like_time(commit_time)
|
||||
end
|
||||
|
||||
it 'does not set the metric for non-referenced issues' do
|
||||
non_referenced_issue = create(:issue, project: project)
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(non_referenced_issue.reload.metrics.first_mentioned_in_commit_at).to be_nil
|
||||
end
|
||||
|
@ -376,19 +394,21 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
end
|
||||
|
||||
context "to default branches" do
|
||||
let(:user) { commit_author }
|
||||
|
||||
it "closes issues", :sidekiq_might_not_need_inline do
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
expect(Issue.find(issue.id)).to be_closed
|
||||
end
|
||||
|
||||
it "adds a note indicating that the issue is now closed", :sidekiq_might_not_need_inline do
|
||||
expect(SystemNoteService).to receive(:change_status).with(issue, project, commit_author, "closed", closing_commit)
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
|
||||
it "doesn't create additional cross-reference notes" do
|
||||
expect(SystemNoteService).not_to receive(:cross_reference)
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -400,11 +420,11 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
|
||||
it "creates cross-reference notes", :sidekiq_inline, :use_clean_rails_redis_caching do
|
||||
expect(SystemNoteService).to receive(:cross_reference).with(issue, closing_commit, commit_author)
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
|
||||
it "doesn't close issues" do
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
expect(Issue.find(issue.id)).to be_opened
|
||||
end
|
||||
end
|
||||
|
@ -441,7 +461,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
let(:message) { "this is some work.\n\nrelated to JIRA-1" }
|
||||
|
||||
it "initiates one api call to jira server to mention the issue", :sidekiq_inline, :use_clean_rails_redis_caching do
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(WebMock).to have_requested(:post, jira_api_comment_url('JIRA-1')).with(
|
||||
body: /mentioned this issue in/
|
||||
|
@ -468,37 +488,43 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
end
|
||||
|
||||
context "using right markdown", :sidekiq_might_not_need_inline do
|
||||
let(:user) { commit_author }
|
||||
|
||||
it "initiates one api call to jira server to close the issue" do
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(WebMock).to have_requested(:post, jira_api_transition_url('JIRA-1')).once
|
||||
end
|
||||
|
||||
it "initiates one api call to jira server to comment on the issue" do
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(WebMock).to have_requested(:post, jira_api_comment_url('JIRA-1')).with(
|
||||
body: comment_body
|
||||
).once
|
||||
expect(WebMock)
|
||||
.to have_requested(:post, jira_api_comment_url('JIRA-1'))
|
||||
.with(body: comment_body)
|
||||
.once
|
||||
end
|
||||
end
|
||||
|
||||
context "using internal issue reference" do
|
||||
let(:user) { commit_author }
|
||||
|
||||
context 'when internal issues are disabled' do
|
||||
before do
|
||||
project.issues_enabled = false
|
||||
project.save!
|
||||
end
|
||||
|
||||
let(:message) { "this is some work.\n\ncloses #1" }
|
||||
|
||||
it "does not initiates one api call to jira server to close the issue" do
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(WebMock).not_to have_requested(:post, jira_api_transition_url('JIRA-1'))
|
||||
end
|
||||
|
||||
it "does not initiates one api call to jira server to comment on the issue" do
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(WebMock).not_to have_requested(:post, jira_api_comment_url('JIRA-1')).with(
|
||||
body: comment_body
|
||||
|
@ -511,13 +537,13 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
let(:message) { "this is some work.\n\ncloses JIRA-1 \n\n closes #{issue.to_reference}" }
|
||||
|
||||
it "initiates one api call to jira server to close the jira issue" do
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(WebMock).to have_requested(:post, jira_api_transition_url('JIRA-1')).once
|
||||
end
|
||||
|
||||
it "initiates one api call to jira server to comment on the jira issue" do
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
|
||||
expect(WebMock).to have_requested(:post, jira_api_comment_url('JIRA-1')).with(
|
||||
body: comment_body
|
||||
|
@ -525,14 +551,14 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
end
|
||||
|
||||
it "closes the internal issue" do
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
expect(issue.reload).to be_closed
|
||||
end
|
||||
|
||||
it "adds a note indicating that the issue is now closed" do
|
||||
expect(SystemNoteService).to receive(:change_status)
|
||||
.with(issue, project, commit_author, "closed", closing_commit)
|
||||
execute_service(project, commit_author, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -542,7 +568,8 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
|
||||
describe "empty project" do
|
||||
let(:project) { create(:project_empty_repo) }
|
||||
let(:new_ref) { 'refs/heads/feature' }
|
||||
let(:ref) { 'refs/heads/feature' }
|
||||
let(:oldrev) { blankrev }
|
||||
|
||||
before do
|
||||
allow(project).to receive(:default_branch).and_return('feature')
|
||||
|
@ -550,7 +577,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
end
|
||||
|
||||
it 'push to first branch updates HEAD' do
|
||||
execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: new_ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -561,7 +588,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
it 'does nothing' do
|
||||
expect(::Environments::StopService).not_to receive(:new)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -569,7 +596,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
it 'does nothing' do
|
||||
expect(::Environments::StopService).not_to receive(:new)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -583,7 +610,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
expect(stop_service).to receive(:execute_for_branch).with(branch)
|
||||
end
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -595,7 +622,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
it 'does nothing' do
|
||||
expect(::Ci::RefDeleteUnlockArtifactsWorker).not_to receive(:perform_async)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -603,7 +630,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
it 'does nothing' do
|
||||
expect(::Ci::RefDeleteUnlockArtifactsWorker).not_to receive(:perform_async)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -614,7 +641,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
expect(::Ci::RefDeleteUnlockArtifactsWorker)
|
||||
.to receive(:perform_async).with(project.id, user.id, "refs/heads/#{branch}")
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -636,7 +663,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
expect(hooks_service).to receive(:execute)
|
||||
end
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -646,38 +673,24 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
it 'does nothing' do
|
||||
expect(::Git::BranchHooksService).not_to receive(:new)
|
||||
|
||||
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def execute_service(project, user, change, push_options = {})
|
||||
service = described_class.new(project, user, change: change, push_options: push_options)
|
||||
service.execute
|
||||
service
|
||||
end
|
||||
|
||||
context 'Jira Connect hooks' do
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
|
||||
let(:branch_to_sync) { nil }
|
||||
let(:commits_to_sync) { [] }
|
||||
let(:params) do
|
||||
{ change: { oldrev: oldrev, newrev: newrev, ref: ref } }
|
||||
end
|
||||
|
||||
subject do
|
||||
described_class.new(project, user, params)
|
||||
end
|
||||
|
||||
shared_examples 'enqueues Jira sync worker' do
|
||||
specify :aggregate_failures do
|
||||
Sidekiq::Testing.fake! do
|
||||
expect(JiraConnect::SyncBranchWorker).to receive(:perform_async)
|
||||
.with(project.id, branch_to_sync, commits_to_sync, kind_of(Numeric))
|
||||
.and_call_original
|
||||
expect(JiraConnect::SyncBranchWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, branch_to_sync, commits_to_sync, kind_of(Numeric))
|
||||
.and_call_original
|
||||
|
||||
expect { subject.execute }.to change(JiraConnect::SyncBranchWorker.jobs, :size).by(1)
|
||||
expect { subject }.to change(JiraConnect::SyncBranchWorker.jobs, :size).by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -685,7 +698,7 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
shared_examples 'does not enqueue Jira sync worker' do
|
||||
specify do
|
||||
Sidekiq::Testing.fake! do
|
||||
expect { subject.execute }.not_to change(JiraConnect::SyncBranchWorker.jobs, :size)
|
||||
expect { subject }.not_to change(JiraConnect::SyncBranchWorker.jobs, :size)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -723,12 +736,12 @@ RSpec.describe Git::BranchPushService, services: true do
|
|||
end
|
||||
|
||||
describe 'project target platforms detection' do
|
||||
subject(:execute) { execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref) }
|
||||
let(:oldrev) { blankrev }
|
||||
|
||||
it 'calls enqueue_record_project_target_platforms on the project' do
|
||||
expect(project).to receive(:enqueue_record_project_target_platforms)
|
||||
|
||||
execute
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -243,14 +243,37 @@ RSpec.describe Git::ProcessRefChangesService do
|
|||
end
|
||||
|
||||
it 'schedules job for existing merge requests' do
|
||||
expect(UpdateMergeRequestsWorker).to receive(:perform_async)
|
||||
.with(project.id, user.id, Gitlab::Git::BLANK_SHA, '789012', "#{ref_prefix}/create1").ordered
|
||||
expect(UpdateMergeRequestsWorker).to receive(:perform_async)
|
||||
.with(project.id, user.id, Gitlab::Git::BLANK_SHA, '789013', "#{ref_prefix}/create2").ordered
|
||||
expect(UpdateMergeRequestsWorker).to receive(:perform_async)
|
||||
.with(project.id, user.id, '789015', '789016', "#{ref_prefix}/changed1").ordered
|
||||
expect(UpdateMergeRequestsWorker).to receive(:perform_async)
|
||||
.with(project.id, user.id, '789020', Gitlab::Git::BLANK_SHA, "#{ref_prefix}/removed2").ordered
|
||||
expect(UpdateMergeRequestsWorker).to receive(:perform_async).with(
|
||||
project.id,
|
||||
user.id,
|
||||
Gitlab::Git::BLANK_SHA,
|
||||
'789012',
|
||||
"#{ref_prefix}/create1",
|
||||
{ 'push_options' => nil }).ordered
|
||||
|
||||
expect(UpdateMergeRequestsWorker).to receive(:perform_async).with(
|
||||
project.id,
|
||||
user.id,
|
||||
Gitlab::Git::BLANK_SHA,
|
||||
'789013',
|
||||
"#{ref_prefix}/create2",
|
||||
{ 'push_options' => nil }).ordered
|
||||
|
||||
expect(UpdateMergeRequestsWorker).to receive(:perform_async).with(
|
||||
project.id,
|
||||
user.id,
|
||||
'789015',
|
||||
'789016',
|
||||
"#{ref_prefix}/changed1",
|
||||
{ 'push_options' => nil }).ordered
|
||||
|
||||
expect(UpdateMergeRequestsWorker).to receive(:perform_async).with(
|
||||
project.id,
|
||||
user.id,
|
||||
'789020',
|
||||
Gitlab::Git::BLANK_SHA,
|
||||
"#{ref_prefix}/removed2",
|
||||
{ 'push_options' => nil }).ordered
|
||||
|
||||
subject.execute
|
||||
end
|
||||
|
|
|
@ -243,6 +243,25 @@ RSpec.describe MergeRequests::RefreshService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when ci.skip push_options are passed' do
|
||||
let(:params) { { push_options: { ci: { skip: true } } } }
|
||||
let(:service_instance) { service.new(project: project, current_user: @user, params: params) }
|
||||
|
||||
subject { service_instance.execute(@oldrev, @newrev, ref) }
|
||||
|
||||
it 'creates a skipped detached merge request pipeline with commits' do
|
||||
expect { subject }
|
||||
.to change { @merge_request.pipelines_for_merge_request.count }.by(1)
|
||||
.and change { @another_merge_request.pipelines_for_merge_request.count }.by(0)
|
||||
|
||||
expect(@merge_request.has_commits?).to be_truthy
|
||||
expect(@another_merge_request.has_commits?).to be_falsy
|
||||
|
||||
pipeline = @merge_request.pipelines_for_merge_request.last
|
||||
expect(pipeline).to be_skipped
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not create detached merge request pipeline for forked project' do
|
||||
expect { subject }
|
||||
.not_to change { @fork_merge_request.pipelines_for_merge_request.count }
|
||||
|
|
Loading…
Reference in New Issue