Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b213b675ec
commit
1b6c8b34c1
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 = __(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)).
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)`.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
```
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||

|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
```
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
@ -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",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue