Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-20 15:09:26 +00:00
parent 24f32a55ee
commit 991c66333d
32 changed files with 299 additions and 177 deletions

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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

View File

@ -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'

View File

@ -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'

View File

@ -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

View File

@ -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)

View File

@ -243,6 +243,7 @@ export default {
:description="label.description"
size="sm"
:scoped="showScopedLabel(label)"
target="#"
@click="filterByLabel(label)"
/>
</template>

View File

@ -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>

View File

@ -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)"
>

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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))

View File

@ -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.')

View File

@ -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.')

View File

@ -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.

View File

@ -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
```

View File

@ -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

View File

@ -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:

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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 ""

View File

@ -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);
});
});
});

View File

@ -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', () => {

View File

@ -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

View File

@ -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

View File

@ -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 }