Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-28 18:07:56 +00:00
parent b213b675ec
commit 1b6c8b34c1
44 changed files with 846 additions and 251 deletions

View File

@ -2,11 +2,11 @@
# project here: https://gitlab.com/gitlab-org/gitlab/-/project_members
# As described in https://docs.gitlab.com/ee/user/project/code_owners.html
[Backend]
^[Backend]
*.rb @gitlab-org/maintainers/rails-backend
*.rake @gitlab-org/maintainers/rails-backend
[Frontend]
^[Frontend]
*.scss @annabeldunstone @gitlab-org/maintainers/frontend
*.js @gitlab-org/maintainers/frontend
/app/assets/ @gitlab-org/maintainers/frontend
@ -16,7 +16,7 @@
/spec/frontend_integration/ @gitlab-org/maintainers/frontend
/ee/spec/frontend_integration/ @gitlab-org/maintainers/frontend
[Database]
^[Database]
/db/ @gitlab-org/maintainers/database
/ee/db/ @gitlab-org/maintainers/database
/lib/gitlab/background_migration/ @gitlab-org/maintainers/database
@ -28,7 +28,7 @@
/ee/app/finders/ @gitlab-org/maintainers/database
/rubocop/rubocop-migrations.yml @gitlab-org/maintainers/database
[Engineering Productivity]
^[Engineering Productivity]
/.gitlab-ci.yml @gl-quality/eng-prod
/.gitlab/ci/ @gl-quality/eng-prod
/.gitlab/ci/docs.gitlab-ci.yml @gl-quality/eng-prod @gl-docsteam
@ -43,33 +43,33 @@ Dangerfile @gl-quality/eng-prod
/scripts/review_apps/seed-dast-test-data.sh @dappelt @ngeorge1 @gl-quality/eng-prod
.editorconfig @gl-quality/eng-prod
[Backend Static Code Analysis]
^[Backend Static Code Analysis]
.rubocop*.yml @dstull @splattael @gl-quality/eng-prod
.rubocop_todo.yml @dstull @splattael @gl-quality/eng-prod
.rubocop_todo/ @dstull @splattael @gl-quality/eng-prod
/rubocop/ @dstull @splattael @gl-quality/eng-prod
/spec/rubocop/ @dstull @splattael @gl-quality/eng-prod
[End-to-end]
^[End-to-end]
/qa/ @gl-quality
[LDAP]
^[LDAP]
/ee/lib/ee/gitlab/auth/ldap/ @dblessing @mkozono
/lib/gitlab/auth/ldap/ @dblessing @mkozono
[Templates]
^[Templates]
/lib/gitlab/ci/templates/ @gitlab-org/maintainers/cicd-templates
/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @DylanGriffith @mayra-cabrera @tkuah
/lib/gitlab/ci/templates/Security/ @gonzoyumo @twoodham @sethgitlab @thiagocsf
/lib/gitlab/ci/templates/Security/Container-Scanning.*.yml @gitlab-org/protect/container-security-backend
[Project Alias]
^[Project Alias]
/ee/app/models/project_alias.rb @patrickbajao
/ee/lib/api/project_aliases.rb @patrickbajao
# Secure & Threat Management ownership delineation
# https://about.gitlab.com/handbook/engineering/development/threat-management/delineate-secure-threat-management.html#technical-boundaries
[Threat Insights]
^[Threat Insights]
/app/finders/security/ @gitlab-org/secure/threat-insights-backend-team
/app/models/vulnerability.rb @gitlab-org/secure/threat-insights-backend-team
/ee/app/finders/security/ @gitlab-org/secure/threat-insights-backend-team
@ -83,7 +83,7 @@ Dangerfile @gl-quality/eng-prod
/ee/spec/policies/vulnerability*.rb @gitlab-org/secure/threat-insights-backend-team
/ee/spec/presenters/projects/security/ @gitlab-org/secure/threat-insights-backend-team
[Secure]
^[Secure]
/ee/lib/gitlab/ci/parsers/license_compliance/ @gitlab-org/secure/composition-analysis-be
/ee/lib/gitlab/ci/parsers/security/ @gitlab-org/secure/composition-analysis-be @gitlab-org/secure/dynamic-analysis-be @gitlab-org/secure/static-analysis-be @gitlab-org/secure/fuzzing-be
/ee/lib/gitlab/ci/reports/coverage_fuzzing/ @gitlab-org/secure/fuzzing-be
@ -92,7 +92,7 @@ Dangerfile @gl-quality/eng-prod
/ee/lib/gitlab/ci/reports/security/ @gitlab-org/secure/composition-analysis-be @gitlab-org/secure/dynamic-analysis-be @gitlab-org/secure/static-analysis-be @gitlab-org/secure/fuzzing-be
/ee/app/services/app_sec/dast/ @gitlab-org/secure/dynamic-analysis-be
[Container Security]
^[Container Security]
/ee/app/views/projects/threat_monitoring/** @gitlab-org/protect/container-security-frontend
/ee/app/views/projects/security/policies/** @gitlab-org/protect/container-security-frontend
/ee/spec/views/projects/security/policies/** @gitlab-org/protect/container-security-frontend
@ -127,13 +127,13 @@ Dangerfile @gl-quality/eng-prod
/ee/lib/gitlab/usage_data_counters/network_policy_counter.rb @gitlab-org/protect/container-security-backend
/ee/spec/lib/gitlab/usage_data_counters/network_policy_counter_spec.rb @gitlab-org/protect/container-security-backend
[Code Owners]
^[Code Owners]
/ee/lib/gitlab/code_owners.rb @reprazent @kerrizor @garyh
/ee/lib/gitlab/code_owners/ @reprazent @kerrizor @garyh
/ee/spec/lib/gitlab/code_owners/ @reprazent @kerrizor @garyh
/doc/user/project/code_owners.md @reprazent @kerrizor @garyh
[Merge Requests]
^[Merge Requests]
/app/controllers/projects/merge_requests/ @garyh @patrickbajao @marc_shaw @kerrizor
/app/models/merge_request.rb @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
/app/services/merge_requests/ @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
@ -165,13 +165,13 @@ Dangerfile @gl-quality/eng-prod
/spec/frontend/batch_comments/ @viktomas @jboyson @iamphill @thomasrandolph
[Product Intelligence]
^[Product Intelligence]
/ee/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers
/ee/lib/ee/gitlab/usage_data.rb @gitlab-org/growth/product-intelligence/engineers
/lib/gitlab/usage_data.rb @gitlab-org/growth/product_intelligence/engineers
/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers
[Growth Experiments]
^[Growth Experiments]
/app/experiments/ @gitlab-org/growth/experiment-devs
/app/models/experiment.rb @gitlab-org/growth/experiment-devs
/app/models/experiment_subject.rb @gitlab-org/growth/experiment-devs
@ -186,16 +186,16 @@ Dangerfile @gl-quality/eng-prod
/lib/gitlab/experimentation_logger.rb @gitlab-org/growth/experiment-devs
/ee/spec/requests/api/experiments_spec.rb @gitlab-org/growth/experiment-devs
[Legal]
^[Legal]
/config/dependency_decisions.yml @gitlab-org/legal-reviewers
[Workhorse]
^[Workhorse]
/workhorse/ @jacobvosmaer-gitlab @nick.thomas @nolith @patrickbajao
[Application Security]
^[Application Security]
/lib/gitlab/content_security_policy/ @gitlab-com/gl-security/appsec
[Gitaly]
^[Gitaly]
lib/gitlab/git_access.rb @proglottis @toon @zj-gitlab
lib/gitlab/git_access_*.rb @proglottis @toon @zj-gitlab
ee/lib/ee/gitlab/git_access.rb @proglottis @toon @zj-gitlab
@ -203,13 +203,13 @@ ee/lib/ee/gitlab/git_access_*.rb @proglottis @toon @zj-gitlab
ee/lib/ee/gitlab/checks/** @proglottis @toon @zj-gitlab
lib/gitlab/checks/** @proglottis @toon @zj-gitlab
[Documentation Directories]
^[Documentation Directories]
.markdownlint.yml @marcel.amirault @eread @aqualls @cnorris
/doc/.markdownlint @marcel.amirault @eread @aqualls @cnorris
/doc/ @gl-docsteam
/doc/.vale/ @marcel.amirault @eread @aqualls @cnorris
[Documentation Pages]
^[Documentation Pages]
/doc/administration/application_settings_cache.md @marcel.amirault
/doc/administration/audit_event_streaming.md @eread
/doc/administration/audit_events.md @eread

View File

@ -1,4 +1,7 @@
<script>
import { s__ } from '~/locale';
import { ENVIRONMENTS_SCOPE } from '../constants';
export default {
name: 'EnvironmentsEmptyState',
props: {
@ -6,6 +9,25 @@ export default {
type: String,
required: true,
},
scope: {
type: String,
required: true,
},
},
computed: {
title() {
return this.$options.i18n.title[this.scope];
},
},
i18n: {
title: {
[ENVIRONMENTS_SCOPE.AVAILABLE]: s__("Environments|You don't have any environments."),
[ENVIRONMENTS_SCOPE.STOPPED]: s__("Environments|You don't have any stopped environments."),
},
content: s__(
'Environments|Environments are places where code gets deployed, such as staging or production.',
),
link: s__('Environments|How do I create an environment?'),
},
};
</script>
@ -13,14 +35,11 @@ export default {
<div class="empty-state">
<div class="text-content">
<h4 class="js-blank-state-title">
{{ s__("Environments|You don't have any environments right now") }}
{{ title }}
</h4>
<p>
{{
s__(`Environments|Environments are places where
code gets deployed, such as staging or production.`)
}}
<a :href="helpPath"> {{ s__('Environments|More information') }} </a>
{{ $options.i18n.content }}
<a :href="helpPath"> {{ $options.i18n.link }} </a>
</p>
</div>
</div>

View File

@ -253,7 +253,7 @@ export default {
@change="resetPolling"
/>
</template>
<empty-state v-else :help-path="helpPagePath" />
<empty-state v-else :help-path="helpPagePath" :scope="scope" />
<gl-pagination
align="center"
:total-items="totalItems"

View File

@ -56,12 +56,12 @@ export const DAST_CONFIG_HELP_PATH = helpPagePath('user/application_security/das
anchor: 'enable-dast',
});
export const DAST_PROFILES_NAME = __('DAST Scans');
export const DAST_PROFILES_NAME = __('DAST profiles');
export const DAST_PROFILES_DESCRIPTION = s__(
'SecurityConfiguration|Manage profiles for use by DAST scans.',
);
export const DAST_PROFILES_HELP_PATH = helpPagePath('user/application_security/dast/index');
export const DAST_PROFILES_CONFIG_TEXT = s__('SecurityConfiguration|Manage scans');
export const DAST_PROFILES_CONFIG_TEXT = s__('SecurityConfiguration|Manage profiles');
export const SECRET_DETECTION_NAME = __('Secret Detection');
export const SECRET_DETECTION_DESCRIPTION = __(

View File

@ -23,9 +23,13 @@ module Projects
def show
respond_to do |format|
format.json do
render json: TestSuiteSerializer
.new(project: project, current_user: @current_user)
.represent(test_suite, details: true)
if Feature.enabled?(:ci_test_report_artifacts_expired, project, default_enabled: :yaml) && pipeline.has_expired_test_reports?
render json: { errors: 'Test report artifacts have expired' }, status: :not_found
else
render json: TestSuiteSerializer
.new(project: project, current_user: @current_user)
.represent(test_suite, details: true)
end
end
end
end

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class LoggedOutMarketingHeaderExperiment < ApplicationExperiment
# These default behaviors are overriden in ApplicationHelper and header
# template partial
control {}
candidate {}
variant(:trial_focused) {}
end

View File

@ -420,6 +420,14 @@ module ProjectsHelper
project.path_with_namespace
end
def able_to_see_issues?(project, user)
project.issues_enabled? && can?(user, :read_issue, project)
end
def able_to_see_merge_requests?(project, user)
project.merge_requests_enabled? && can?(user, :read_merge_request, project)
end
def fork_button_disabled_tooltip(project)
return unless current_user
@ -627,7 +635,9 @@ module ProjectsHelper
end
def can_show_last_commit_in_list?(project)
can?(current_user, :read_cross_project) && project.commit
can?(current_user, :read_cross_project) &&
can?(current_user, :read_commit_status, project) &&
project.commit
end
def pages_https_only_disabled?

View File

@ -1285,6 +1285,12 @@ module Ci
end
end
def has_expired_test_reports?
strong_memoize(:artifacts_expired) do
!has_reports?(::Ci::JobArtifact.test_reports.not_expired)
end
end
private
def add_message(severity, content)

View File

@ -4,5 +4,4 @@
%section{ data: { hide_projects: 'false', group_id: group.id, path: group_path(group) } }
.js-groups-list-holder{ data: { show_schema_markup: 'true'} }
.loading-container.text-center.prepend-top-20
.gl-spinner.gl-spinner-md
= gl_loading_icon(size: 'md', css_class: 'gl-mt-6')

View File

@ -1,8 +1,7 @@
- remove_form_id = local_assigns.fetch(:remove_form_id, nil)
- if group.paid?
.gl-alert.gl-alert-info.gl-mb-5{ data: { testid: 'group-has-linked-subscription-alert' } }
= sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
= render 'shared/global_alert', dismissible: false, alert_class: 'gl-mb-5', alert_data: { testid: 'group-has-linked-subscription-alert' } do
.gl-alert-body
= html_escape(_("This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/index', anchor: 'change-the-linked-namespace')}\">".html_safe, linkEnd: '</a>'.html_safe }

View File

@ -37,8 +37,8 @@
- css_class = (i >= projects_limit) || project.pending_delete? ? 'hide' : nil
= render "shared/projects/project", project: project, skip_namespace: skip_namespace,
avatar: avatar, stars: stars, css_class: css_class, use_creator_avatar: use_creator_avatar,
forks: project.forking_enabled?, show_last_commit_as_description: show_last_commit_as_description, user: user,
merge_requests: project.merge_requests_enabled?, issues: project.issues_enabled?,
forks: project.forking_enabled?, show_last_commit_as_description: show_last_commit_as_description,
user: user, merge_requests: able_to_see_merge_requests?(project, user), issues: able_to_see_issues?(project, user),
pipeline_status: pipeline_status, compact_mode: compact_mode
= paginate_collection(projects, remote: remote) unless skip_pagination
- else

View File

@ -69,18 +69,19 @@ module Gitlab
require_dependency Rails.root.join('lib/gitlab/middleware/handle_malformed_strings')
require_dependency Rails.root.join('lib/gitlab/middleware/rack_multipart_tempfile_factory')
require_dependency Rails.root.join('lib/gitlab/runtime')
require_dependency Rails.root.join('lib/gitlab/patch/legacy_database_config')
require_dependency Rails.root.join('lib/gitlab/patch/database_config')
require_dependency Rails.root.join('lib/gitlab/exceptions_app')
config.exceptions_app = Gitlab::ExceptionsApp.new(Rails.public_path)
# To be removed in 15.0
# This preload is needed to convert legacy `database.yml`
# from `production: adapter: postgresql`
# into a `production: main: adapter: postgresql`
unless Gitlab::Utils.to_boolean(ENV['SKIP_DATABASE_CONFIG_VALIDATION'], default: false)
config.class.prepend(::Gitlab::Patch::LegacyDatabaseConfig)
end
# This preload is required to:
#
# 1. Convert legacy `database.yml`;
# 2. Include Geo post-deployment migrations settings;
#
# TODO: In 15.0, this preload can be wrapped in a Gitlab.ee block
# since we don't need to convert legacy `database.yml` anymore.
config.class.prepend(::Gitlab::Patch::DatabaseConfig)
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers

View File

@ -0,0 +1,8 @@
---
name: ci_test_report_artifacts_expired
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83113
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356773
milestone: '14.10'
type: development
group: group::pipeline insights
default_enabled: false

View File

@ -962,3 +962,7 @@ retarget merge requests pointing to the now-merged branch. To learn more, read
## CDN-based limits on GitLab.com
In addition to application-based limits, GitLab.com is configured to use Cloudflare's standard DDoS protection and Spectrum to protect Git over SSH. Cloudflare terminates client TLS connections but is not application aware and cannot be used for limits tied to users or groups. Cloudflare page rules and rate limits are configured with Terraform. These configurations are [not public](https://about.gitlab.com/handbook/communication/#not-public) because they include security and abuse implementations that detect malicious activities and making them public would undermine those operations.
## Container Repository tag deletion limit
Container repository tags are in the Container Registry and, as such, each tag deletion will trigger network requests to the Container Registry. Because of this, we limit the number of tags that a single API call can delete to 20.

View File

@ -154,7 +154,7 @@ Using checklists improves quality in software engineering. This checklist is a s
##### Quality
See the [test engineering process](https://about.gitlab.com/handbook/engineering/quality/test-engineering/) for further quality guidelines.
See the [test engineering process](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/test-engineering/) for further quality guidelines.
1. I have self-reviewed this MR per [code review guidelines](code_review.md).
1. For the code that this change impacts, I believe that the automated tests ([Testing Guide](testing_guide/index.md)) validate functionality that is highly important to users (including consideration of [all test levels](testing_guide/testing_levels.md)).

View File

@ -49,7 +49,7 @@ Check these aspects both when _designing_ and _reviewing_ UI changes.
### Visual design
Check visual design properties using your browser's _elements inspector_ ([Chrome](https://developer.chrome.com/docs/devtools/css/),
[Firefox](https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Open_the_Inspector)).
[Firefox](https://firefox-source-docs.mozilla.org/devtools-user/page_inspector/how_to/open_the_inspector/index.html)).
- Use recommended [colors](https://design.gitlab.com/product-foundations/colors/)
and [typography](https://design.gitlab.com/product-foundations/type-fundamentals/).
@ -66,7 +66,7 @@ Check visual design properties using your browser's _elements inspector_ ([Chrom
Check states using your browser's _styles inspector_ to toggle CSS pseudo-classes
like `:hover` and others ([Chrome](https://developer.chrome.com/docs/devtools/css/reference/#pseudo-class),
[Firefox](https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_and_edit_CSS#viewing_common_pseudo-classes)).
[Firefox](https://firefox-source-docs.mozilla.org/devtools-user/page_inspector/how_to/examine_and_edit_css/index.html#viewing-common-pseudo-classes)).
- Account for all applicable states ([error](https://design.gitlab.com/content/error-messages),
rest, loading, focus, hover, selected, disabled).
@ -78,7 +78,7 @@ like `:hover` and others ([Chrome](https://developer.chrome.com/docs/devtools/cs
### Responsive
Check responsive behavior using your browser's _responsive mode_ ([Chrome](https://developer.chrome.com/docs/devtools/device-mode/#viewport),
[Firefox](https://developer.mozilla.org/en-US/docs/Tools/Responsive_Design_Mode)).
[Firefox](https://firefox-source-docs.mozilla.org/devtools-user/responsive_design_mode/index.html)).
- Account for resizing, collapsing, moving, or wrapping of elements across
all breakpoints (even if larger viewports are prioritized).

View File

@ -144,7 +144,7 @@ document from the Kubernetes team also has some great points regarding this.
### Commit messages guidelines
Commit messages should follow the guidelines below, for reasons explained by Chris Beams in [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/):
Commit messages should follow the guidelines below, for reasons explained by Chris Beams in [How to Write a Git Commit Message](https://cbea.ms/git-commit/):
- The commit subject and body must be separated by a blank line.
- The commit subject must start with a capital letter.
@ -203,7 +203,7 @@ Example commit message template that can be used on your machine that embodies t
# Do not use Emojis
# Use the body to explain what and why vs. how
# Can use multiple lines with "-" for bullet points in body
# For more information: https://chris.beams.io/posts/git-commit/
# For more information: https://cbea.ms/git-commit/
# --------------------
```
@ -287,7 +287,7 @@ requirements.
1. Confirmed to be working in staging before implementing the change in production, where possible.
1. Confirmed to be working in the production with no new [Sentry](https://about.gitlab.com/handbook/engineering/monitoring/#sentry) errors after the contribution is deployed.
1. Confirmed that the [rollout plan](https://about.gitlab.com/handbook/engineering/development/processes/rollout-plans) has been completed.
1. Confirmed that the [rollout plan](https://about.gitlab.com/handbook/engineering/development/processes/rollout-plans/) has been completed.
1. If there is a performance risk in the change, I have analyzed the performance of the system before and after the change.
1. *If the merge request uses feature flags, per-project or per-group enablement, and a staged rollout:*
- Confirmed to be working on GitLab projects.

View File

@ -71,7 +71,7 @@ GitLab Docs is built with a combination of external:
- [Schema.org](https://schema.org/)
- [Google Analytics](https://marketingplatform.google.com/about/analytics/)
- [Google Tag Manager](https://developers.google.com/tag-manager/)
- [Google Tag Manager](https://developers.google.com/tag-platform/tag-manager)
## Global navigation

View File

@ -746,7 +746,7 @@ We include guidance for links in these categories:
- Use inline link Markdown markup `[Text](https://example.com)`.
It's easier to read, review, and maintain. Do not use `[Text][identifier]` reference-style links.
- Use [meaningful anchor text](https://www.futurehosting.com/blog/links-should-have-meaningful-anchor-text-heres-why/).
- Use meaningful anchor text.
For example, instead of writing something like `Read more about merge requests [here](LINK)`,
write `Read more about [merge requests](LINK)`.

View File

@ -189,7 +189,7 @@ English language. Vale's configuration is stored in the
[`.vale.ini`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.vale.ini) file located in the root
directory of projects.
Vale supports creating [custom tests](https://errata-ai.github.io/vale/styles/) that extend any of
Vale supports creating [custom tests](https://docs.errata.ai/vale/styles) that extend any of
several types of checks, which we store in the `.linting/vale/styles/gitlab` directory in the
documentation directory of projects.

View File

@ -21,7 +21,12 @@ info: To determine the technical writer assigned to the Stage/Group associated w
When developing locally, there are times when you need your instance to act like the SaaS version of the product.
In those instances, you can simulate SaaS by exporting an environment variable as seen below:
`export GITLAB_SIMULATE_SAAS=1`
```shell
export GITLAB_SIMULATE_SAAS=1
```
There are many ways to pass an environment variable to your local GitLab instance.
For example, you can create a `env.runit` file in the root of your GDK with the above snippet.
## Act as CE when unlicensed

View File

@ -786,7 +786,7 @@ The reasoning behind this is that in some languages words change depending on co
in Japanese は is added to the subject of a sentence and を to the object. This is impossible to
translate correctly if you extract individual words from the sentence.
When in doubt, try to follow the best practices described in this [Mozilla Developer documentation](https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_content_best_practices#Splitting).
When in doubt, try to follow the best practices described in this [Mozilla Developer documentation](https://mozilla-l10n.github.io/documentation/localization/dev_best_practices.html#splitting-and-composing-sentences).
### Always pass string literals to the translation helpers

View File

@ -28,4 +28,4 @@ For results about an investigation conducted into an unexpected drop in Service
### Troubleshooting data warehouse layer
Reach out to the [Data team](https://about.gitlab.com/handbook/business-technology/data-team) to ask about current state of data warehouse. On their handbook page there is a [section with contact details](https://about.gitlab.com/handbook/business-technology/data-team/#how-to-connect-with-us).
Reach out to the [Data team](https://about.gitlab.com/handbook/business-technology/data-team/) to ask about current state of data warehouse. On their handbook page there is a [section with contact details](https://about.gitlab.com/handbook/business-technology/data-team/#how-to-connect-with-us).

View File

@ -28,7 +28,7 @@ While on CloudWatch dashboard set time range to last 4 weeks, to get better pict
Drop occurring at application layer can be symptom of some issue, but it might be also a result of normal application lifecycle, intended changes done to product intelligence or experiments tracking
or even a result of a public holiday in some regions of the world with a larger user-base. To verify if there is an underlying problem to solve, you can check following things:
1. Check `about.gitlab.com` website traffic on [Google Analytics](https://analytics.google.com/) to verify if some public holiday might impact overall use of GitLab system
1. Check `about.gitlab.com` website traffic on [Google Analytics](https://analytics.google.com/analytics/web/) to verify if some public holiday might impact overall use of GitLab system
1. You may require to open an access request for Google Analytics access first eg: [access request internal issue](https://gitlab.com/gitlab-com/team-member-epics/access-requests/-/issues/1772)
1. Plot `select date(dvce_created_tstamp) , event , count(*) from legacy.snowplow_unnested_events_90 where dvce_created_tstamp > '2021-06-15' and dvce_created_tstamp < '2021-07-10' group by 1 , 2 order by 1 , 2` in SiSense to see what type of events was responsible for drop
1. Plot `select date(dvce_created_tstamp) ,se_category , count(*) from legacy.snowplow_unnested_events_90 where dvce_created_tstamp > '2021-06-15' and dvce_created_tstamp < '2021-07-31' and event = 'struct' group by 1 , 2 order by 1, 2` what events recorded the biggest drops in suspected category
@ -47,4 +47,4 @@ Already conducted investigations:
### Troubleshooting data warehouse layer
Reach out to [Data team](https://about.gitlab.com/handbook/business-technology/data-team) to ask about current state of data warehouse. On their handbook page there is a [section with contact details](https://about.gitlab.com/handbook/business-technology/data-team/#how-to-connect-with-us)
Reach out to [Data team](https://about.gitlab.com/handbook/business-technology/data-team/) to ask about current state of data warehouse. On their handbook page there is a [section with contact details](https://about.gitlab.com/handbook/business-technology/data-team/#how-to-connect-with-us)

View File

@ -375,6 +375,30 @@ For example, for installations from source:
sudo -u git -H bundle exec rake gitlab:backup:create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1
```
#### Incremental repository backups
> Introduced in GitLab 14.9 [with a flag](../administration/feature_flags.md) named `incremental_repository_backup`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `incremental_repository_backup`.
On GitLab.com, this feature is not available.
This feature is not ready for production use.
Incremental backups can be faster than full backups because they only pack changes since the last backup into the backup
bundle for each repository. There must be an existing backup to create an incremental backup from and this backup will be overwritten. You can use the `BACKUP=timestamp_of_backup` option to choose which backup will be used.
To create an incremental backup, run:
```shell
sudo gitlab-backup create INCREMENTAL=yes
```
Incremental backups can also be created from [an untarred backup](#skipping-tar-creation) by using `SKIP=tar`:
```shell
sudo gitlab-backup create INCREMENTAL=yes SKIP=tar
```
#### Uploading backups to a remote (cloud) storage
You can let the backup script upload (using the [Fog library](http://fog.io/))
@ -1830,22 +1854,3 @@ If you have a specific reason to change the path, it can be configured in Omnibu
1. [Reconfigure GitLab](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect
### Incremental repository backups
> Introduced in GitLab 14.9 [with a flag](../administration/feature_flags.md) named `incremental_repository_backup`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `incremental_repository_backup`.
On GitLab.com, this feature is not available.
This feature is not ready for production use.
Incremental backups can be faster than full backups because they only pack changes since the last backup into the backup
bundle for each repository. Because incremental backups require access to the previous backup, you can't use incremental
backups with tar files.
To create an incremental backup, run:
```shell
sudo gitlab-backup create SKIP=tar INCREMENTAL=yes
```

View File

@ -88,14 +88,14 @@ the merge request list page:
To view a list of merge requests that need your attention:
1. On the top bar, select **Merge requests**. (**{merge-request}**)
1. On the top bar, select **Merge requests** (**{merge-request}**).
1. Select **Attention requests**.
To request attention from another user:
1. Go to the merge request.
1. On the right sidebar, identify the user you want to request attention from.
1. Next to the user's name, select **Request attention**, and the appearance
1. Next to the user's name, select **Request attention** (**{attention}**), and the appearance
of the icon changes:
![Attention request toggle](img/attention_request_sidebar_v14_10.png)
@ -104,13 +104,12 @@ To request attention from another user:
If your attention was requested as an assignee or reviewer, it's removed when you:
- You manually remove the attention request by selecting **Remove attention request** (**{attention-solid}**).
- Manually remove the attention request by selecting **Remove attention request** (**{attention-solid}**).
- Approve the merge request.
- Add a new user as an assignee or reviewer.
- Request the attention of a different assignee or reviewer.
- Remove yourself (or are removed by someone else) as an assignee or reviewer.
- Merge or close the merge request.
- Manually remove the attention request by selecting **Remove attention request**. (**{attention-solid}**)
If you are both the assignee and a reviewer on a merge request, you receive
only one attention request, which is synced across both duties. If the

View File

@ -117,12 +117,19 @@ There are multiple ways to create a branch from the GitLab web interface.
### Create a new branch from an issue
> The **Create merge request** button [changed](https://gitlab.com/gitlab-org/gitlab/-/issues/349566) to open the merge request creation form in GitLab 14.8.
If your development workflow requires an issue for every merge
request, you can create a branch directly from the issue to speed the process up.
The new branch, and later its merge request, are marked as related to this issue.
Once merged, the merge request closes the issue.
You can see a **Create merge request** dropdown below the issue description.
NOTE:
In GitLab 14.8 and later, selecting **Create merge request**
[redirects to the merge request creation form](https://gitlab.com/gitlab-org/gitlab/-/issues/349566)
instead of immediately creating the merge request.
The **Create merge request** button doesn't display if:
- A branch with the same name already exists.

View File

@ -88,7 +88,7 @@ If you have the correct version, you can proceed to configure Git.
Configure Git to use your key for signing:
```shell
signingkey = $( gpgsm --list-secret-keys | egrep '(key usage|ID)' | grep -B 1 digitalSignature | awk '/ID/ {print $2}' )
signingkey=$( gpgsm --list-secret-keys | egrep '(key usage|ID)' | grep -B 1 digitalSignature | awk '/ID/ {print $2}' )
git config --global user.signingkey $signingkey
git config --global gpg.format x509
```

View File

@ -19,7 +19,9 @@ module Backup
@progress = progress
force = ENV['force'] == 'yes'
incremental = Gitlab::Utils.to_boolean(ENV['INCREMENTAL'], default: false)
@incremental = Feature.feature_flags_available? &&
Feature.enabled?(:incremental_repository_backup, default_enabled: :yaml) &&
Gitlab::Utils.to_boolean(ENV['INCREMENTAL'], default: false)
@definitions = definitions || {
'db' => TaskDefinition.new(
@ -30,8 +32,7 @@ module Backup
'repositories' => TaskDefinition.new(
destination_path: 'repositories',
destination_optional: true,
task: Repositories.new(progress,
strategy: repository_backup_strategy(incremental))
task: Repositories.new(progress, strategy: repository_backup_strategy)
),
'uploads' => TaskDefinition.new(
destination_path: 'uploads.tar.gz',
@ -69,6 +70,12 @@ module Backup
end
def create
if incremental?
unpack
read_backup_information
verify_backup_version
end
@definitions.keys.each do |task_name|
run_create_task(task_name)
end
@ -87,7 +94,7 @@ module Backup
puts_time "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \
"and are not included in this backup. You will need these files to restore a backup.\n" \
"Please back them up manually.".color(:red)
puts_time "Backup task is done."
puts_time "Backup #{backup_id} is done."
end
def run_create_task(task_name)
@ -169,6 +176,10 @@ module Backup
private
def incremental?
@incremental
end
def read_backup_information
@backup_information ||= YAML.load_file(File.join(backup_path, MANIFEST_NAME))
end
@ -338,8 +349,15 @@ module Backup
puts_time 'Found more than one backup:'
# print list of available backups
puts_time " " + available_timestamps.join("\n ")
puts_time 'Please specify which one you want to restore:'
puts_time 'rake gitlab:backup:restore BACKUP=timestamp_of_backup'
if incremental?
puts_time 'Please specify which one you want to create an incremental backup for:'
puts_time 'rake gitlab:backup:create INCREMENTAL=true BACKUP=timestamp_of_backup'
else
puts_time 'Please specify which one you want to restore:'
puts_time 'rake gitlab:backup:restore BACKUP=timestamp_of_backup'
end
exit 1
end
@ -437,11 +455,15 @@ module Backup
end
def tar_file
@tar_file ||= if ENV['BACKUP'].present?
File.basename(ENV['BACKUP']) + FILE_NAME_SUFFIX
else
"#{backup_information[:backup_created_at].strftime('%s_%Y_%m_%d_')}#{backup_information[:gitlab_version]}#{FILE_NAME_SUFFIX}"
end
@tar_file ||= "#{backup_id}#{FILE_NAME_SUFFIX}"
end
def backup_id
@backup_id ||= if ENV['BACKUP'].present?
File.basename(ENV['BACKUP'])
else
"#{backup_information[:backup_created_at].strftime('%s_%Y_%m_%d_')}#{backup_information[:gitlab_version]}"
end
end
def create_attributes
@ -477,10 +499,10 @@ module Backup
Gitlab.config.backup.upload.connection&.provider&.downcase == 'google'
end
def repository_backup_strategy(incremental)
def repository_backup_strategy
max_concurrency = ENV['GITLAB_BACKUP_MAX_CONCURRENCY'].presence
max_storage_concurrency = ENV['GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY'].presence
Backup::GitalyBackup.new(progress, incremental: incremental, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency)
Backup::GitalyBackup.new(progress, incremental: incremental?, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency)
end
def puts_time(msg)

View File

@ -28,7 +28,7 @@
module Gitlab
module Patch
module LegacyDatabaseConfig
module DatabaseConfig
extend ActiveSupport::Concern
prepended do
@ -73,23 +73,34 @@ module Gitlab
@uses_legacy_database_config = false # rubocop:disable Gitlab/ModuleWithInstanceVariables
super.to_h do |env, configs|
# This check is taken from Rails where the transformation
# of a flat database.yml is done into `primary:`
# https://github.com/rails/rails/blob/v6.1.4/activerecord/lib/active_record/database_configurations.rb#L169
if configs.is_a?(Hash) && !configs.all? { |_, v| v.is_a?(Hash) }
configs = { "main" => configs }
# TODO: To be removed in 15.0. See https://gitlab.com/gitlab-org/gitlab/-/issues/338182
# This preload is needed to convert legacy `database.yml`
# from `production: adapter: postgresql`
# into a `production: main: adapter: postgresql`
unless Gitlab::Utils.to_boolean(ENV['SKIP_DATABASE_CONFIG_VALIDATION'], default: false)
# This check is taken from Rails where the transformation
# of a flat database.yml is done into `primary:`
# https://github.com/rails/rails/blob/v6.1.4/activerecord/lib/active_record/database_configurations.rb#L169
if configs.is_a?(Hash) && !configs.all? { |_, v| v.is_a?(Hash) }
configs = { "main" => configs }
@uses_legacy_database_config = true # rubocop:disable Gitlab/ModuleWithInstanceVariables
@uses_legacy_database_config = true # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
end
if Gitlab.ee? && File.exist?(Rails.root.join("config/database_geo.yml"))
migrations_paths = ["ee/db/geo/migrate"]
migrations_paths << "ee/db/geo/post_migrate" unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS']
if Gitlab.ee?
if !configs.key?("geo") && File.exist?(Rails.root.join("config/database_geo.yml"))
configs["geo"] = Rails.application.config_for(:database_geo).stringify_keys
end
configs["geo"] =
Rails.application.config_for(:database_geo)
.merge(migrations_paths: migrations_paths, schema_migrations_path: "ee/db/geo/schema_migrations")
.stringify_keys
if configs.key?("geo")
migrations_paths = Array(configs["geo"]["migrations_paths"])
migrations_paths << "ee/db/geo/migrate" if migrations_paths.empty?
migrations_paths << "ee/db/geo/post_migrate" unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS']
configs["geo"]["migrations_paths"] = migrations_paths.uniq
configs["geo"]["schema_migrations_path"] = "ee/db/geo/schema_migrations" if configs["geo"]["schema_migrations_path"].blank?
end
end
[env, configs]

View File

@ -84,16 +84,38 @@ namespace :gitlab do
desc 'GitLab | DB | Configures the database by running migrate, or by loading the schema and seeding if needed'
task configure: :environment do
# Check if we have existing db tables
# The schema_migrations table will still exist if drop_tables was called
if ActiveRecord::Base.connection.tables.count > 1
Rake::Task['db:migrate'].invoke
databases_with_tasks = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
databases_loaded = []
if databases_with_tasks.size == 1
next unless databases_with_tasks.first.name == 'main'
connection = Gitlab::Database.database_base_models['main'].connection
databases_loaded << configure_database(connection)
else
# Add post-migrate paths to ensure we mark all migrations as up
Gitlab::Database.add_post_migrate_path_to_rails(force: true)
Rake::Task['db:structure:load'].invoke
Rake::Task['db:seed_fu'].invoke
Gitlab::Database.database_base_models.each do |name, model|
next unless databases_with_tasks.any? { |db_with_tasks| db_with_tasks.name == name }
databases_loaded << configure_database(model.connection, database_name: name)
end
end
Rake::Task['db:seed_fu'].invoke if databases_loaded.present? && databases_loaded.all?
end
def configure_database(connection, database_name: nil)
database_name = ":#{database_name}" if database_name
load_database = connection.tables.count <= 1
if load_database
Gitlab::Database.add_post_migrate_path_to_rails(force: true)
Rake::Task["db:schema:load#{database_name}"].invoke
else
Rake::Task["db:migrate#{database_name}"].invoke
end
load_database
end
desc 'GitLab | DB | Run database migrations and print `unattended_migrations_completed` if action taken'

View File

@ -28,11 +28,14 @@ namespace :gitlab do
projects = Project.where(id: ids)
Projects::BuildArtifactsSizeRefresh.enqueue_refresh(projects)
# Take a short break to allow replication to catch up
Kernel.sleep(1)
imported += projects.size
missing += ids.size - projects.size
puts "#{imported}/#{project_ids.size} (missing projects: #{missing})"
end
puts 'Done.'.green
puts 'Done.'
else
puts 'Project IDs must be listed in the CSV under the header PROJECT_ID'.red
end

View File

@ -11226,10 +11226,10 @@ msgstr ""
msgid "DAST Configuration"
msgstr ""
msgid "DAST Scans"
msgid "DAST profile not found: %{name}"
msgstr ""
msgid "DAST profile not found: %{name}"
msgid "DAST profiles"
msgstr ""
msgid "DNS"
@ -11376,6 +11376,9 @@ msgstr ""
msgid "DastProfiles|Could not update the site profile. Please try again."
msgstr ""
msgid "DastProfiles|DAST profile library"
msgstr ""
msgid "DastProfiles|Debug messages"
msgstr ""
@ -11430,9 +11433,6 @@ msgstr ""
msgid "DastProfiles|Include debug messages in the DAST console output."
msgstr ""
msgid "DastProfiles|Manage DAST scans"
msgstr ""
msgid "DastProfiles|Manage profiles"
msgstr ""
@ -14242,6 +14242,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
msgid "Environments|How do I create an environment?"
msgstr ""
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
@ -14257,9 +14260,6 @@ msgstr ""
msgid "Environments|Logs from %{start} to %{end}."
msgstr ""
msgid "Environments|More information"
msgstr ""
msgid "Environments|New environment"
msgstr ""
@ -14341,7 +14341,10 @@ msgstr ""
msgid "Environments|Updated"
msgstr ""
msgid "Environments|You don't have any environments right now"
msgid "Environments|You don't have any environments."
msgstr ""
msgid "Environments|You don't have any stopped environments."
msgstr ""
msgid "Environments|by %{avatar}"
@ -33039,10 +33042,10 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
msgid "SecurityConfiguration|Manage profiles"
msgstr ""
msgid "SecurityConfiguration|Manage scans"
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
msgstr ""
msgid "SecurityConfiguration|More scan types, including Container Scanning, DAST, Dependency Scanning, Fuzzing, and Licence Compliance"

View File

@ -40,28 +40,56 @@ RSpec.describe Projects::Pipelines::TestsController do
let(:suite_name) { 'test' }
let(:build_ids) { pipeline.latest_builds.pluck(:id) }
before do
build = main_pipeline.builds.last
build.update_column(:finished_at, 1.day.ago) # Just to be sure we are included in the report window
context 'when artifacts are expired' do
before do
pipeline.job_artifacts.first.update!(expire_at: Date.yesterday)
end
# The JUnit fixture for the given build has 3 failures.
# This service will create 1 test case failure record for each.
Ci::TestFailureHistoryService.new(main_pipeline).execute
it 'renders not_found errors', :aggregate_failures do
get_tests_show_json(build_ids)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['errors']).to eq('Test report artifacts have expired')
end
context 'when ci_test_report_artifacts_expired is disabled' do
before do
stub_feature_flags(ci_test_report_artifacts_expired: false)
end
it 'renders test suite', :aggregate_failures do
get_tests_show_json(build_ids)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq('test')
end
end
end
it 'renders test suite data' do
get_tests_show_json(build_ids)
context 'when artifacts are not expired' do
before do
build = main_pipeline.builds.last
build.update_column(:finished_at, 1.day.ago) # Just to be sure we are included in the report window
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq('test')
# The JUnit fixture for the given build has 3 failures.
# This service will create 1 test case failure record for each.
Ci::TestFailureHistoryService.new(main_pipeline).execute
end
# Each test failure in this pipeline has a matching failure in the default branch
recent_failures = json_response['test_cases'].map { |tc| tc['recent_failures'] }
expect(recent_failures).to eq([
{ 'count' => 1, 'base_branch' => 'master' },
{ 'count' => 1, 'base_branch' => 'master' },
{ 'count' => 1, 'base_branch' => 'master' }
])
it 'renders test suite data', :aggregate_failures do
get_tests_show_json(build_ids)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq('test')
expect(json_response['artifacts_expired']).to be_falsey
# Each test failure in this pipeline has a matching failure in the default branch
recent_failures = json_response['test_cases'].map { |tc| tc['recent_failures'] }
expect(recent_failures).to eq([
{ 'count' => 1, 'base_branch' => 'master' },
{ 'count' => 1, 'base_branch' => 'master' },
{ 'count' => 1, 'base_branch' => 'master' }
])
end
end
end

View File

@ -70,7 +70,7 @@ RSpec.describe 'Environments page', :js do
it 'shows no environments' do
visit_environments(project, scope: 'stopped')
expect(page).to have_content('You don\'t have any environments right now')
expect(page).to have_content(s_('Environments|You don\'t have any stopped environments.'))
end
end
@ -99,7 +99,7 @@ RSpec.describe 'Environments page', :js do
it 'shows no environments' do
visit_environments(project, scope: 'available')
expect(page).to have_content('You don\'t have any environments right now')
expect(page).to have_content(s_('Environments|You don\'t have any environments.'))
end
end
@ -120,7 +120,7 @@ RSpec.describe 'Environments page', :js do
end
it 'does not show environments and counters are set to zero' do
expect(page).to have_content('You don\'t have any environments right now')
expect(page).to have_content(s_('Environments|You don\'t have any environments.'))
expect(page).to have_link("#{_('Available')} 0")
expect(page).to have_link("#{_('Stopped')} 0")

View File

@ -0,0 +1,53 @@
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { s__ } from '~/locale';
import EmptyState from '~/environments/components/empty_state.vue';
import { ENVIRONMENTS_SCOPE } from '~/environments/constants';
const HELP_PATH = '/help';
describe('~/environments/components/empty_state.vue', () => {
let wrapper;
const createWrapper = ({ propsData = {} } = {}) =>
mountExtended(EmptyState, {
propsData: {
scope: ENVIRONMENTS_SCOPE.AVAILABLE,
helpPath: HELP_PATH,
...propsData,
},
});
afterEach(() => {
wrapper.destroy();
});
it('shows an empty state for available environments', () => {
wrapper = createWrapper();
const title = wrapper.findByRole('heading', {
name: s__("Environments|You don't have any environments."),
});
expect(title.exists()).toBe(true);
});
it('shows an empty state for stopped environments', () => {
wrapper = createWrapper({ propsData: { scope: ENVIRONMENTS_SCOPE.STOPPED } });
const title = wrapper.findByRole('heading', {
name: s__("Environments|You don't have any stopped environments."),
});
expect(title.exists()).toBe(true);
});
it('shows a link to the the help path', () => {
wrapper = createWrapper();
const link = wrapper.findByRole('link', {
name: s__('Environments|How do I create an environment?'),
});
expect(link.attributes('href')).toBe(HELP_PATH);
});
});

View File

@ -1,24 +0,0 @@
import { shallowMount } from '@vue/test-utils';
import EmptyState from '~/environments/components/empty_state.vue';
describe('environments empty state', () => {
let vm;
beforeEach(() => {
vm = shallowMount(EmptyState, {
propsData: {
helpPath: 'bar',
},
});
});
afterEach(() => {
vm.destroy();
});
it('renders the empty state', () => {
expect(vm.find('.js-blank-state-title').text()).toEqual(
"You don't have any environments right now",
);
});
});

View File

@ -1000,6 +1000,54 @@ RSpec.describe ProjectsHelper do
end
end
context 'fork security helpers' do
using RSpec::Parameterized::TableSyntax
describe "#able_to_see_merge_requests?" do
subject { helper.able_to_see_merge_requests?(project, user) }
where(:can_read_merge_request, :merge_requests_enabled, :expected) do
false | false | false
true | false | false
false | true | false
true | true | true
end
with_them do
before do
allow(project).to receive(:merge_requests_enabled?).and_return(merge_requests_enabled)
allow(helper).to receive(:can?).with(user, :read_merge_request, project).and_return(can_read_merge_request)
end
it 'returns the correct response' do
expect(subject).to eq(expected)
end
end
end
describe "#able_to_see_issues?" do
subject { helper.able_to_see_issues?(project, user) }
where(:can_read_issues, :issues_enabled, :expected) do
false | false | false
true | false | false
false | true | false
true | true | true
end
with_them do
before do
allow(project).to receive(:issues_enabled?).and_return(issues_enabled)
allow(helper).to receive(:can?).with(user, :read_issue, project).and_return(can_read_issues)
end
it 'returns the correct response' do
expect(subject).to eq(expected)
end
end
end
end
describe '#fork_button_disabled_tooltip' do
using RSpec::Parameterized::TableSyntax

View File

@ -145,6 +145,7 @@ RSpec.describe Backup::Manager do
end
describe '#create' do
let(:incremental_env) { 'false' }
let(:expected_backup_contents) { %w{backup_information.yml task1.tar.gz task2.tar.gz} }
let(:tar_file) { '1546300800_2019_01_01_12.3_gitlab_backup.tar' }
let(:tar_system_options) { { out: [tar_file, 'w', Gitlab.config.backup.archive_permissions] } }
@ -166,6 +167,7 @@ RSpec.describe Backup::Manager do
end
before do
stub_env('INCREMENTAL', incremental_env)
allow(ActiveRecord::Base.connection).to receive(:reconnect!)
allow(Gitlab::BackupLogger).to receive(:info)
allow(Kernel).to receive(:system).and_return(true)
@ -561,6 +563,158 @@ RSpec.describe Backup::Manager do
end
end
end
context 'incremental' do
let(:incremental_env) { 'true' }
let(:gitlab_version) { Gitlab::VERSION }
let(:tar_file) { "1546300800_2019_01_01_#{gitlab_version}_gitlab_backup.tar" }
let(:backup_information) do
{
backup_created_at: Time.zone.parse('2019-01-01'),
gitlab_version: gitlab_version
}
end
context 'when there are no backup files in the directory' do
before do
allow(Dir).to receive(:glob).and_return([])
end
it 'fails the operation and prints an error' do
expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
expect(progress).to have_received(:puts)
.with(a_string_matching('No backups found'))
end
end
context 'when there are two backup files in the directory and BACKUP variable is not set' do
before do
allow(Dir).to receive(:glob).and_return(
[
'1451606400_2016_01_01_1.2.3_gitlab_backup.tar',
'1451520000_2015_12_31_gitlab_backup.tar'
]
)
end
it 'prints the list of available backups' do
expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
expect(progress).to have_received(:puts)
.with(a_string_matching('1451606400_2016_01_01_1.2.3\n 1451520000_2015_12_31'))
end
it 'fails the operation and prints an error' do
expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
expect(progress).to have_received(:puts)
.with(a_string_matching('Found more than one backup'))
end
end
context 'when BACKUP variable is set to a non-existing file' do
before do
allow(Dir).to receive(:glob).and_return(
[
'1451606400_2016_01_01_gitlab_backup.tar'
]
)
allow(File).to receive(:exist?).and_return(false)
stub_env('BACKUP', 'wrong')
end
it 'fails the operation and prints an error' do
expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar')
expect(progress).to have_received(:puts)
.with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist'))
end
end
context 'when BACKUP variable is set to a correct file' do
let(:tar_cmdline) { %w{tar -xf 1451606400_2016_01_01_1.2.3_gitlab_backup.tar} }
before do
allow(Gitlab::BackupLogger).to receive(:info)
allow(Dir).to receive(:glob).and_return(
[
'1451606400_2016_01_01_1.2.3_gitlab_backup.tar'
]
)
allow(File).to receive(:exist?).and_return(true)
allow(Kernel).to receive(:system).and_return(true)
stub_env('BACKUP', '/ignored/path/1451606400_2016_01_01_1.2.3')
end
it 'unpacks the file' do
subject.create # rubocop:disable Rails/SaveBang
expect(Kernel).to have_received(:system).with(*tar_cmdline)
end
context 'tar fails' do
before do
expect(Kernel).to receive(:system).with(*tar_cmdline).and_return(false)
end
it 'logs a failure' do
expect do
subject.create # rubocop:disable Rails/SaveBang
end.to raise_error(SystemExit)
expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Unpacking backup failed')
end
end
context 'on version mismatch' do
let(:backup_information) do
{
backup_created_at: Time.zone.parse('2019-01-01'),
gitlab_version: "not #{gitlab_version}"
}
end
it 'stops the process' do
expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
expect(progress).to have_received(:puts)
.with(a_string_matching('GitLab version mismatch'))
end
end
end
context 'when there is a non-tarred backup in the directory' do
before do
allow(Dir).to receive(:glob).and_return(
[
'backup_information.yml'
]
)
allow(File).to receive(:exist?).and_return(true)
end
it 'selects the non-tarred backup to restore from' do
subject.create # rubocop:disable Rails/SaveBang
expect(progress).to have_received(:puts)
.with(a_string_matching('Non tarred backup found '))
end
context 'on version mismatch' do
let(:backup_information) do
{
backup_created_at: Time.zone.parse('2019-01-01'),
gitlab_version: "not #{gitlab_version}"
}
end
it 'stops the process' do
expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
expect(progress).to have_received(:puts)
.with(a_string_matching('GitLab version mismatch'))
end
end
end
end
end
describe '#restore' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do
RSpec.describe Gitlab::Patch::DatabaseConfig do
it 'module is included' do
expect(Rails::Application::Configuration).to include(described_class)
end

View File

@ -4713,6 +4713,24 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
end
describe '#has_expired_test_reports?' do
subject { pipeline_with_test_report.has_expired_test_reports? }
let(:pipeline_with_test_report) { create(:ci_pipeline, :with_test_reports) }
context 'when artifacts are not expired' do
it { is_expected.to be_falsey }
end
context 'when artifacts are expired' do
before do
pipeline_with_test_report.job_artifacts.first.update!(expire_at: Date.yesterday)
end
it { is_expected.to be_truthy }
end
end
it_behaves_like 'it has loose foreign keys' do
let(:factory_name) { :ci_pipeline }
end

View File

@ -51,7 +51,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
let(:base_models) { { 'main' => main_model, 'ci' => ci_model } }
before do
skip_if_multiple_databases_not_setup
skip_unless_ci_uses_database_tasks
allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
end
@ -133,79 +133,228 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
end
describe 'configure' do
it 'invokes db:migrate when schema has already been loaded' do
allow(ActiveRecord::Base.connection).to receive(:tables).and_return(%w[table1 table2])
expect(Rake::Task['db:migrate']).to receive(:invoke)
expect(Rake::Task['db:structure:load']).not_to receive(:invoke)
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.not_to raise_error
end
it 'invokes db:shema:load and db:seed_fu when schema is not loaded' do
allow(ActiveRecord::Base.connection).to receive(:tables).and_return([])
expect(Rake::Task['db:structure:load']).to receive(:invoke)
expect(Rake::Task['db:seed_fu']).to receive(:invoke)
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.not_to raise_error
end
it 'invokes db:shema:load and db:seed_fu when there is only a single table present' do
allow(ActiveRecord::Base.connection).to receive(:tables).and_return(['default'])
expect(Rake::Task['db:structure:load']).to receive(:invoke)
expect(Rake::Task['db:seed_fu']).to receive(:invoke)
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.not_to raise_error
end
it 'does not invoke any other rake tasks during an error' do
allow(ActiveRecord::Base).to receive(:connection).and_raise(RuntimeError, 'error')
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
expect(Rake::Task['db:structure:load']).not_to receive(:invoke)
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.to raise_error(RuntimeError, 'error')
# unstub connection so that the database cleaner still works
allow(ActiveRecord::Base).to receive(:connection).and_call_original
end
it 'does not invoke seed after a failed schema_load' do
allow(ActiveRecord::Base.connection).to receive(:tables).and_return([])
allow(Rake::Task['db:structure:load']).to receive(:invoke).and_raise(RuntimeError, 'error')
expect(Rake::Task['db:structure:load']).to receive(:invoke)
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.to raise_error(RuntimeError, 'error')
end
context 'SKIP_POST_DEPLOYMENT_MIGRATIONS environment variable set' do
let(:rails_paths) { { 'db' => ['db'], 'db/migrate' => ['db/migrate'] } }
context 'with a single database' do
let(:connection) { Gitlab::Database.database_base_models[:main].connection }
let(:main_config) { double(:config, name: 'main') }
before do
allow(ENV).to receive(:[]).and_call_original
allow(ENV).to receive(:[]).with('SKIP_POST_DEPLOYMENT_MIGRATIONS').and_return true
# Our environment has already been loaded, so we need to pretend like post_migrations were not
allow(Rails.application.config).to receive(:paths).and_return(rails_paths)
allow(ActiveRecord::Migrator).to receive(:migrations_paths).and_return(rails_paths['db/migrate'].dup)
skip_if_multiple_databases_are_setup
end
it 'adds post deployment migrations before schema load if the schema is not already loaded' do
allow(ActiveRecord::Base.connection).to receive(:tables).and_return([])
expect(Gitlab::Database).to receive(:add_post_migrate_path_to_rails).and_call_original
expect(Rake::Task['db:structure:load']).to receive(:invoke)
expect(Rake::Task['db:seed_fu']).to receive(:invoke)
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.not_to raise_error
expect(rails_paths['db/migrate'].include?(File.join(Rails.root, 'db', 'post_migrate'))).to be(true)
context 'when geo is not configured' do
before do
allow(ActiveRecord::Base).to receive_message_chain('configurations.configs_for').and_return([main_config])
end
context 'when the schema is already loaded' do
it 'migrates the database' do
allow(connection).to receive(:tables).and_return(%w[table1 table2])
expect(Rake::Task['db:migrate']).to receive(:invoke)
expect(Rake::Task['db:schema:load']).not_to receive(:invoke)
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
end
end
context 'when the schema is not loaded' do
it 'loads the schema and seeds the database' do
allow(connection).to receive(:tables).and_return([])
expect(Rake::Task['db:schema:load']).to receive(:invoke)
expect(Rake::Task['db:seed_fu']).to receive(:invoke)
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
end
end
context 'when only a single table is present' do
it 'loads the schema and seeds the database' do
allow(connection).to receive(:tables).and_return(['default'])
expect(Rake::Task['db:schema:load']).to receive(:invoke)
expect(Rake::Task['db:seed_fu']).to receive(:invoke)
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
end
end
context 'when loading the schema fails' do
it 'does not seed the database' do
allow(connection).to receive(:tables).and_return([])
expect(Rake::Task['db:schema:load']).to receive(:invoke).and_raise('error')
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.to raise_error(RuntimeError, 'error')
end
end
context 'SKIP_POST_DEPLOYMENT_MIGRATIONS environment variable set' do
let(:rails_paths) { { 'db' => ['db'], 'db/migrate' => ['db/migrate'] } }
before do
stub_env('SKIP_POST_DEPLOYMENT_MIGRATIONS', true)
# Our environment has already been loaded, so we need to pretend like post_migrations were not
allow(Rails.application.config).to receive(:paths).and_return(rails_paths)
allow(ActiveRecord::Migrator).to receive(:migrations_paths).and_return(rails_paths['db/migrate'].dup)
end
context 'when the schema is not loaded' do
it 'adds the post deployment migration path before schema load' do
allow(connection).to receive(:tables).and_return([])
expect(Gitlab::Database).to receive(:add_post_migrate_path_to_rails).and_call_original
expect(Rake::Task['db:schema:load']).to receive(:invoke)
expect(Rake::Task['db:seed_fu']).to receive(:invoke)
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
expect(rails_paths['db/migrate'].include?(File.join(Rails.root, 'db', 'post_migrate'))).to be(true)
end
end
context 'when the schema is loaded' do
it 'ignores post deployment migrations' do
allow(connection).to receive(:tables).and_return(%w[table1 table2])
expect(Rake::Task['db:migrate']).to receive(:invoke)
expect(Gitlab::Database).not_to receive(:add_post_migrate_path_to_rails)
expect(Rake::Task['db:schema:load']).not_to receive(:invoke)
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
expect(rails_paths['db/migrate'].include?(File.join(Rails.root, 'db', 'post_migrate'))).to be(false)
end
end
end
end
it 'ignores post deployment migrations when schema has already been loaded' do
allow(ActiveRecord::Base.connection).to receive(:tables).and_return(%w[table1 table2])
expect(Rake::Task['db:migrate']).to receive(:invoke)
expect(Gitlab::Database).not_to receive(:add_post_migrate_path_to_rails)
expect(Rake::Task['db:structure:load']).not_to receive(:invoke)
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.not_to raise_error
expect(rails_paths['db/migrate'].include?(File.join(Rails.root, 'db', 'post_migrate'))).to be(false)
context 'when geo is configured' do
context 'when the main database is also configured' do
before do
skip_unless_geo_configured
end
it 'only configures the main database' do
allow(connection).to receive(:tables).and_return(%w[table1 table2])
expect(Rake::Task['db:migrate:main']).to receive(:invoke)
expect(Rake::Task['db:migrate:geo']).not_to receive(:invoke)
expect(Rake::Task['db:schema:load:geo']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
end
end
end
end
context 'with multiple databases' do
let(:main_model) { double(:model, connection: double(:connection)) }
let(:ci_model) { double(:model, connection: double(:connection)) }
let(:base_models) { { 'main' => main_model, 'ci' => ci_model }.with_indifferent_access }
let(:main_config) { double(:config, name: 'main') }
let(:ci_config) { double(:config, name: 'ci') }
before do
skip_unless_ci_uses_database_tasks
allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
end
context 'when geo is not configured' do
before do
allow(ActiveRecord::Base).to receive_message_chain('configurations.configs_for')
.and_return([main_config, ci_config])
end
context 'when no database has the schema loaded' do
before do
allow(main_model.connection).to receive(:tables).and_return(%w[schema_migrations])
allow(ci_model.connection).to receive(:tables).and_return([])
end
it 'loads the schema and seeds all the databases' do
expect(Rake::Task['db:schema:load:main']).to receive(:invoke)
expect(Rake::Task['db:schema:load:ci']).to receive(:invoke)
expect(Rake::Task['db:migrate:main']).not_to receive(:invoke)
expect(Rake::Task['db:migrate:ci']).not_to receive(:invoke)
expect(Rake::Task['db:seed_fu']).to receive(:invoke)
run_rake_task('gitlab:db:configure')
end
end
context 'when both databases have the schema loaded' do
before do
allow(main_model.connection).to receive(:tables).and_return(%w[table1 table2])
allow(ci_model.connection).to receive(:tables).and_return(%w[table1 table2])
end
it 'migrates the databases without seeding them' do
expect(Rake::Task['db:migrate:main']).to receive(:invoke)
expect(Rake::Task['db:migrate:ci']).to receive(:invoke)
expect(Rake::Task['db:schema:load:main']).not_to receive(:invoke)
expect(Rake::Task['db:schema:load:ci']).not_to receive(:invoke)
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
end
end
context 'when only one database has the schema loaded' do
before do
allow(main_model.connection).to receive(:tables).and_return(%w[table1 table2])
allow(ci_model.connection).to receive(:tables).and_return([])
end
it 'migrates and loads the schema correctly, without seeding the databases' do
expect(Rake::Task['db:migrate:main']).to receive(:invoke)
expect(Rake::Task['db:schema:load:main']).not_to receive(:invoke)
expect(Rake::Task['db:schema:load:ci']).to receive(:invoke)
expect(Rake::Task['db:migrate:ci']).not_to receive(:invoke)
expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
end
end
end
context 'when geo is configured' do
let(:geo_config) { double(:config, name: 'geo') }
before do
skip_unless_geo_configured
allow(main_model.connection).to receive(:tables).and_return(%w[schema_migrations])
allow(ci_model.connection).to receive(:tables).and_return(%w[schema_migrations])
end
it 'does not run tasks against geo' do
expect(Rake::Task['db:schema:load:main']).to receive(:invoke)
expect(Rake::Task['db:schema:load:ci']).to receive(:invoke)
expect(Rake::Task['db:seed_fu']).to receive(:invoke)
expect(Rake::Task['db:migrate:geo']).not_to receive(:invoke)
expect(Rake::Task['db:schema:load:geo']).not_to receive(:invoke)
run_rake_task('gitlab:db:configure')
end
end
end
end
@ -301,7 +450,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
let(:base_models) { { 'main' => main_model, 'ci' => ci_model } }
before do
skip_if_multiple_databases_not_setup
skip_unless_ci_uses_database_tasks
allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
@ -373,7 +522,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
context 'with multiple databases' do
before do
skip_if_multiple_databases_not_setup
skip_unless_ci_uses_database_tasks
end
context 'when running the multi-database variant' do
@ -443,6 +592,10 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
end
context 'when the single database task is used' do
before do
skip_unless_ci_uses_database_tasks
end
it 'delegates to Gitlab::Database::Reindexing with a specific database' do
expect(Gitlab::Database::Reindexing).to receive(:invoke).with('ci')
@ -576,7 +729,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
context 'with multiple databases', :reestablished_active_record_base do
before do
skip_if_multiple_databases_not_setup
skip_unless_ci_uses_database_tasks
end
describe 'db:structure:dump against a single database' do
@ -671,6 +824,14 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
run_rake_task(test_task_name)
end
def skip_unless_ci_uses_database_tasks
skip "Skipping because database tasks won't run against the ci database" unless ci_database_tasks?
end
def ci_database_tasks?
!!ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'ci')&.database_tasks?
end
def skip_unless_geo_configured
skip 'Skipping because the geo database is not configured' unless geo_configured?
end

View File

@ -27,6 +27,7 @@ RSpec.describe 'gitlab:refresh_project_statistics_build_artifacts_size rake task
stub_const("BUILD_ARTIFACTS_SIZE_REFRESH_ENQUEUE_BATCH_SIZE", 2)
stub_request(:get, csv_url).to_return(status: 200, body: csv_body)
allow(Kernel).to receive(:sleep).with(1)
end
context 'when given a list of space-separated IDs through rake argument' do
@ -35,6 +36,14 @@ RSpec.describe 'gitlab:refresh_project_statistics_build_artifacts_size rake task
expect(Projects::BuildArtifactsSizeRefresh.all.map(&:project)).to match_array([project_1, project_2, project_3])
end
it 'inserts refreshes in batches with a sleep' do
expect(Projects::BuildArtifactsSizeRefresh).to receive(:enqueue_refresh).with([project_1, project_2]).ordered
expect(Kernel).to receive(:sleep).with(1)
expect(Projects::BuildArtifactsSizeRefresh).to receive(:enqueue_refresh).with([project_3]).ordered
run_rake_task(rake_task, csv_url)
end
end
context 'when CSV has invalid header' do

View File

@ -20,6 +20,18 @@ RSpec.describe 'shared/projects/_list' do
expect(rendered).to have_content(project.name)
end
end
it "will not show elements a user shouldn't be able to see" do
allow(view).to receive(:can_show_last_commit_in_list?).and_return(false)
allow(view).to receive(:able_to_see_merge_requests?).and_return(false)
allow(view).to receive(:able_to_see_issues?).and_return(false)
render
expect(rendered).not_to have_css('a.commit-row-message')
expect(rendered).not_to have_css('a.issues')
expect(rendered).not_to have_css('a.merge-requests')
end
end
context 'without projects' do