Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7c42073320
commit
875662ef7b
|
@ -77,7 +77,7 @@ review-build-cng:
|
|||
variables:
|
||||
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
||||
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
||||
GITLAB_HELM_CHART_REF: "41d7632d9eba84f5816d808b98ccf3f5623e9fb5"
|
||||
GITLAB_HELM_CHART_REF: "a6a609a19166f00b1a7774374041cd38a9f7e20d"
|
||||
environment:
|
||||
name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY}
|
||||
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
|
||||
|
|
|
@ -963,7 +963,7 @@ GEM
|
|||
pyu-ruby-sasl (0.0.3.3)
|
||||
raabro (1.1.6)
|
||||
racc (1.6.0)
|
||||
rack (2.2.3)
|
||||
rack (2.2.3.1)
|
||||
rack-accept (0.4.5)
|
||||
rack (>= 0.4)
|
||||
rack-attack (6.3.0)
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { s__ } from '~/locale';
|
||||
|
||||
export const PLATFORMS_WITHOUT_ARCHITECTURES = ['docker', 'kubernetes'];
|
||||
|
||||
export const REGISTRATION_TOKEN_PLACEHOLDER = '$REGISTRATION_TOKEN';
|
||||
|
||||
export const INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES = {
|
||||
|
|
|
@ -17,7 +17,6 @@ import { __, s__ } from '~/locale';
|
|||
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
|
||||
import {
|
||||
INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES,
|
||||
PLATFORMS_WITHOUT_ARCHITECTURES,
|
||||
REGISTRATION_TOKEN_PLACEHOLDER,
|
||||
} from './constants';
|
||||
import getRunnerPlatformsQuery from './graphql/queries/get_runner_platforms.query.graphql';
|
||||
|
@ -60,20 +59,20 @@ export default {
|
|||
platforms: {
|
||||
query: getRunnerPlatformsQuery,
|
||||
update(data) {
|
||||
return data?.runnerPlatforms?.nodes.map(({ name, humanReadableName, architectures }) => {
|
||||
return {
|
||||
name,
|
||||
humanReadableName,
|
||||
architectures: architectures?.nodes || [],
|
||||
};
|
||||
});
|
||||
return (
|
||||
data?.runnerPlatforms?.nodes.map(({ name, humanReadableName, architectures }) => {
|
||||
return {
|
||||
name,
|
||||
humanReadableName,
|
||||
architectures: architectures?.nodes || [],
|
||||
};
|
||||
}) ?? []
|
||||
);
|
||||
},
|
||||
result() {
|
||||
if (this.platforms.length) {
|
||||
// If it is set and available, select the defaultSelectedPlatform.
|
||||
// Otherwise, select the first available platform
|
||||
this.selectPlatform(this.defaultPlatform() || this.platforms[0]);
|
||||
}
|
||||
// If it is set and available, select the defaultSelectedPlatform.
|
||||
// Otherwise, select the first available platform
|
||||
this.selectPlatform(this.defaultPlatformName || this.platforms?.[0].name);
|
||||
},
|
||||
error() {
|
||||
this.toggleAlert(true);
|
||||
|
@ -86,8 +85,8 @@ export default {
|
|||
},
|
||||
variables() {
|
||||
return {
|
||||
platform: this.selectedPlatformName,
|
||||
architecture: this.selectedArchitectureName || '',
|
||||
platform: this.selectedPlatform,
|
||||
architecture: this.selectedArchitecture || '',
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
|
@ -109,26 +108,21 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
platformsEmpty() {
|
||||
return isEmpty(this.platforms);
|
||||
},
|
||||
instructionsEmpty() {
|
||||
return isEmpty(this.instructions);
|
||||
},
|
||||
selectedPlatformName() {
|
||||
return this.selectedPlatform?.name;
|
||||
architectures() {
|
||||
return this.platforms.find(({ name }) => name === this.selectedPlatform)?.architectures || [];
|
||||
},
|
||||
selectedArchitectureName() {
|
||||
return this.selectedArchitecture?.name;
|
||||
},
|
||||
hasArchitecureList() {
|
||||
return !PLATFORMS_WITHOUT_ARCHITECTURES.includes(this.selectedPlatformName);
|
||||
binaryUrl() {
|
||||
return this.architectures.find(({ name }) => name === this.selectedArchitecture)
|
||||
?.downloadLocation;
|
||||
},
|
||||
instructionsWithoutArchitecture() {
|
||||
return INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES[this.selectedPlatformName]?.instructions;
|
||||
return INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES[this.selectedPlatform]?.instructions;
|
||||
},
|
||||
runnerInstallationLink() {
|
||||
return INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES[this.selectedPlatformName]?.link;
|
||||
return INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES[this.selectedPlatform]?.link;
|
||||
},
|
||||
registerInstructionsWithToken() {
|
||||
const { registerInstructions } = this.instructions || {};
|
||||
|
@ -139,7 +133,6 @@ export default {
|
|||
this.registrationToken,
|
||||
);
|
||||
}
|
||||
|
||||
return registerInstructions;
|
||||
},
|
||||
},
|
||||
|
@ -150,21 +143,17 @@ export default {
|
|||
focusSelected() {
|
||||
// By default the first platform always gets the focus, but when the `defaultPlatformName`
|
||||
// property is present, any other platform might actually be selected.
|
||||
this.$refs[this.selectedPlatformName]?.[0].$el.focus();
|
||||
this.$refs[this.selectedPlatform]?.[0].$el.focus();
|
||||
},
|
||||
defaultPlatform() {
|
||||
return this.platforms.find((platform) => platform.name === this.defaultPlatformName);
|
||||
},
|
||||
selectPlatform(platform) {
|
||||
this.selectedPlatform = platform;
|
||||
selectPlatform(platformName) {
|
||||
this.selectedPlatform = platformName;
|
||||
|
||||
// Update architecture when platform changes
|
||||
const architectures = platform.architectures || [];
|
||||
const arch = architectures.find(({ name }) => name === this.selectedArchitectureName);
|
||||
const arch = this.architectures.find(({ name }) => name === this.selectedArchitecture);
|
||||
if (arch) {
|
||||
this.selectArchitecture(arch);
|
||||
this.selectArchitecture(arch.name);
|
||||
} else {
|
||||
this.selectArchitecture(architectures[0]);
|
||||
this.selectArchitecture(this.architectures[0]?.name);
|
||||
}
|
||||
},
|
||||
selectArchitecture(architecture) {
|
||||
|
@ -210,9 +199,9 @@ export default {
|
|||
{{ $options.i18n.fetchError }}
|
||||
</gl-alert>
|
||||
|
||||
<gl-skeleton-loader v-if="platformsEmpty && $apollo.loading" />
|
||||
<gl-skeleton-loader v-if="!platforms.length && $apollo.loading" />
|
||||
|
||||
<template v-if="!platformsEmpty">
|
||||
<template v-if="platforms.length">
|
||||
<h5>
|
||||
{{ __('Environment') }}
|
||||
</h5>
|
||||
|
@ -227,29 +216,29 @@ export default {
|
|||
v-for="platform in platforms"
|
||||
:key="platform.name"
|
||||
:ref="platform.name"
|
||||
:selected="selectedPlatformName === platform.name"
|
||||
@click="selectPlatform(platform)"
|
||||
:selected="selectedPlatform === platform.name"
|
||||
@click="selectPlatform(platform.name)"
|
||||
>
|
||||
{{ platform.humanReadableName }}
|
||||
</gl-button>
|
||||
</gl-button-group>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="hasArchitecureList">
|
||||
<template v-if="architectures.length">
|
||||
<template v-if="selectedPlatform">
|
||||
<h5>
|
||||
{{ $options.i18n.architecture }}
|
||||
<gl-loading-icon v-if="$apollo.loading" size="sm" inline />
|
||||
</h5>
|
||||
|
||||
<gl-dropdown class="gl-mb-3" :text="selectedArchitectureName">
|
||||
<gl-dropdown class="gl-mb-3" :text="selectedArchitecture">
|
||||
<gl-dropdown-item
|
||||
v-for="architecture in selectedPlatform.architectures"
|
||||
v-for="architecture in architectures"
|
||||
:key="architecture.name"
|
||||
:is-check-item="true"
|
||||
:is-checked="selectedArchitectureName === architecture.name"
|
||||
:is-checked="selectedArchitecture === architecture.name"
|
||||
data-testid="architecture-dropdown-item"
|
||||
@click="selectArchitecture(architecture)"
|
||||
@click="selectArchitecture(architecture.name)"
|
||||
>
|
||||
{{ architecture.name }}
|
||||
</gl-dropdown-item>
|
||||
|
@ -257,8 +246,9 @@ export default {
|
|||
<div class="gl-sm-display-flex gl-align-items-center gl-mb-3">
|
||||
<h5>{{ $options.i18n.downloadInstallBinary }}</h5>
|
||||
<gl-button
|
||||
v-if="binaryUrl"
|
||||
class="gl-ml-auto"
|
||||
:href="selectedArchitecture.downloadLocation"
|
||||
:href="binaryUrl"
|
||||
download
|
||||
icon="download"
|
||||
data-testid="binary-download-button"
|
||||
|
|
|
@ -112,13 +112,13 @@ class Projects::CompareController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def start_ref
|
||||
@start_ref ||= Addressable::URI.unescape(compare_params[:from])
|
||||
@start_ref ||= Addressable::URI.unescape(compare_params[:from]).presence
|
||||
end
|
||||
|
||||
def head_ref
|
||||
return @ref if defined?(@ref)
|
||||
|
||||
@ref = @head_ref = Addressable::URI.unescape(compare_params[:to])
|
||||
@ref = @head_ref = Addressable::URI.unescape(compare_params[:to]).presence
|
||||
end
|
||||
|
||||
def define_commits
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
- base_domain_path = help_page_path('user/project/clusters/gitlab_managed_clusters', anchor: 'base-domain')
|
||||
- base_domain_link_start = link_start % { url: base_domain_path }
|
||||
|
||||
- help_link_continouos = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank', rel: 'noopener noreferrer'
|
||||
- help_link_timed = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/customize.md', anchor: 'timed-incremental-rollout-to-production'), target: '_blank', rel: 'noopener noreferrer'
|
||||
- help_link_incremental = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/customize.md', anchor: 'incremental-rollout-to-production'), target: '_blank', rel: 'noopener noreferrer'
|
||||
|
||||
.row
|
||||
.col-lg-12
|
||||
= gitlab_ui_form_for @project, url: project_settings_ci_cd_path(@project, anchor: 'autodevops-settings') do |f|
|
||||
|
@ -33,22 +37,8 @@
|
|||
= s_('CICD|Add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} for your deployment strategy to work.').html_safe % { base_domain_link_start: base_domain_link_start, kubernetes_cluster_link_start: kubernetes_cluster_link_start, link_end: link_end }
|
||||
%label.gl-mt-3
|
||||
%strong= s_('CICD|Deployment strategy')
|
||||
.form-check
|
||||
= form.radio_button :deploy_strategy, 'continuous', class: 'form-check-input'
|
||||
= form.label :deploy_strategy_continuous, class: 'form-check-label' do
|
||||
= s_('CICD|Continuous deployment to production')
|
||||
= link_to sprite_icon('question-o'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank', rel: 'noopener noreferrer'
|
||||
|
||||
.form-check
|
||||
= form.radio_button :deploy_strategy, 'timed_incremental', class: 'form-check-input'
|
||||
= form.label :deploy_strategy_timed_incremental, class: 'form-check-label' do
|
||||
= s_('CICD|Continuous deployment to production using timed incremental rollout')
|
||||
= link_to sprite_icon('question-o'), help_page_path('topics/autodevops/customize.md', anchor: 'timed-incremental-rollout-to-production'), target: '_blank', rel: 'noopener noreferrer'
|
||||
|
||||
.form-check
|
||||
= form.radio_button :deploy_strategy, 'manual', class: 'form-check-input'
|
||||
= form.label :deploy_strategy_manual, class: 'form-check-label' do
|
||||
= s_('CICD|Automatic deployment to staging, manual deployment to production')
|
||||
= link_to sprite_icon('question-o'), help_page_path('topics/autodevops/customize.md', anchor: 'incremental-rollout-to-production'), target: '_blank', rel: 'noopener noreferrer'
|
||||
= form.gitlab_ui_radio_component :deploy_strategy, 'continuous', (s_('CICD|Continuous deployment to production') + ' ' + help_link_continouos).html_safe
|
||||
= form.gitlab_ui_radio_component :deploy_strategy, 'timed_incremental', (s_('CICD|Continuous deployment to production using timed incremental rollout') + ' ' + help_link_timed).html_safe
|
||||
= form.gitlab_ui_radio_component :deploy_strategy, 'manual', (s_('CICD|Automatic deployment to staging, manual deployment to production') + ' ' + help_link_incremental).html_safe
|
||||
|
||||
= f.submit _('Save changes'), class: "btn gl-button btn-confirm gl-mt-5", data: { qa_selector: 'save_changes_button' }
|
||||
|
|
|
@ -37,11 +37,8 @@
|
|||
data: { placeholder: _('Select branch'), endpoint: refs_project_path(@project, sort: 'updated_desc', find: 'branches') }})
|
||||
|
||||
- if source_level < target_level
|
||||
.gl-alert.gl-alert-warning.gl-alert-not-dismissible.gl-max-content.gl-mt-4
|
||||
.gl-alert-container
|
||||
.gl-alert-content{ role: 'alert' }
|
||||
= sprite_icon('warning', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
|
||||
.gl-alert-body
|
||||
= visibilityMismatchString
|
||||
%br
|
||||
= _('Review the target project before submitting to avoid exposing %{source} changes.') % { source: source_visibility }
|
||||
= render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_class: 'gl-mb-4') do |c|
|
||||
= c.body do
|
||||
= visibilityMismatchString
|
||||
%br
|
||||
= _('Review the target project before submitting to avoid exposing %{source} changes.') % { source: source_visibility }
|
||||
|
|
|
@ -855,8 +855,8 @@ if [[ -d "/builds/gitlab-examples/ci-debug-trace/.git" ]]; then
|
|||
++ CI_SERVER_PROTOCOL=https
|
||||
++ export CI_SERVER_NAME=GitLab
|
||||
++ CI_SERVER_NAME=GitLab
|
||||
++ export GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_project_service_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
|
||||
++ GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_project_service_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,cluster_health,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
|
||||
++ export GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
|
||||
++ GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,cluster_health,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
|
||||
++ export CI_PROJECT_ID=17893
|
||||
++ CI_PROJECT_ID=17893
|
||||
++ export CI_PROJECT_NAME=ci-debug-trace
|
||||
|
|
|
@ -3196,8 +3196,9 @@ job:
|
|||
with the flags `File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB`.
|
||||
- For performance reasons, GitLab matches a maximum of 10,000 `exists` patterns or
|
||||
file paths. After the 10,000th check, rules with patterned globs always match.
|
||||
In other words, the `exists` rule always assumes a match in projects with more
|
||||
than 10,000 files.
|
||||
In other words, `exists` always reports `true` if more than 10,000 checks
|
||||
run. Repositories with less than 10,000 files might still be impacted if the `exists`
|
||||
rules are checked more than 10,000 times.
|
||||
- `exists` resolves to `true` if any of the listed files are found (an `OR` operation).
|
||||
|
||||
#### `rules:allow_failure`
|
||||
|
|
|
@ -29,11 +29,11 @@ When the state of a flag changes (for example, disabled by default to enabled by
|
|||
Possible version history entries are:
|
||||
|
||||
```markdown
|
||||
> - [Introduced](issue-link) in GitLab X.X [with a flag](../../administration/feature_flags.md) named <flag name>. Disabled by default.
|
||||
> - [Introduced](issue-link) in GitLab X.X [with a flag](../../administration/feature_flags.md) named `flag_name`. Disabled by default.
|
||||
> - [Enabled on GitLab.com](issue-link) in GitLab X.X.
|
||||
> - [Enabled on GitLab.com](issue-link) in GitLab X.X. Available to GitLab.com administrators only.
|
||||
> - [Enabled on self-managed](issue-link) in GitLab X.X.
|
||||
> - [Generally available](issue-link) in GitLab X.Y. [Feature flag <flag name>](issue-link) removed.
|
||||
> - [Generally available](issue-link) in GitLab X.Y. [Feature flag `flag_name`](issue-link) removed.
|
||||
```
|
||||
|
||||
You can combine entries if they happened in the same release:
|
||||
|
@ -60,15 +60,15 @@ FLAG:
|
|||
|
||||
| If the feature is... | Use this text |
|
||||
|--------------------------|---------------|
|
||||
| Available | `On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Unavailable | `On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Available to some users | `On self-managed GitLab, by default this feature is available to a subset of users. To show or hide the feature for all, ask an administrator to [change the status of the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Available, per-group | `On self-managed GitLab, by default this feature is available. To hide the feature per group, ask an administrator to [disable the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Unavailable, per-group | `On self-managed GitLab, by default this feature is not available. To make it available per group, ask an administrator to [enable the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Available, per-project | `On self-managed GitLab, by default this feature is available. To hide the feature per project or for your entire instance, ask an administrator to [disable the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Unavailable, per-project | `On self-managed GitLab, by default this feature is not available. To make it available per project or for your entire instance, ask an administrator to [enable the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Available, per-user | `On self-managed GitLab, by default this feature is available. To hide the feature per user, ask an administrator to [disable the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Unavailable, per-user | `On self-managed GitLab, by default this feature is not available. To make it available per user, ask an administrator to [enable the feature flag](<path to>/administration/feature_flags.md) named <flag name>.` |
|
||||
| Available | ``On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
| Unavailable | ``On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
| Available to some users | ``On self-managed GitLab, by default this feature is available to a subset of users. To show or hide the feature for all, ask an administrator to [change the status of the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
| Available, per-group | ``On self-managed GitLab, by default this feature is available. To hide the feature per group, ask an administrator to [disable the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
| Unavailable, per-group | ``On self-managed GitLab, by default this feature is not available. To make it available per group, ask an administrator to [enable the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
| Available, per-project | ``On self-managed GitLab, by default this feature is available. To hide the feature per project or for your entire instance, ask an administrator to [disable the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
| Unavailable, per-project | ``On self-managed GitLab, by default this feature is not available. To make it available per project or for your entire instance, ask an administrator to [enable the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
| Available, per-user | ``On self-managed GitLab, by default this feature is available. To hide the feature per user, ask an administrator to [disable the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
| Unavailable, per-user | ``On self-managed GitLab, by default this feature is not available. To make it available per user, ask an administrator to [enable the feature flag](<path to>/administration/feature_flags.md) named `flag_name`.`` |
|
||||
|
||||
### GitLab.com availability information
|
||||
|
||||
|
@ -114,5 +114,5 @@ And, when the feature is done and fully available to all users:
|
|||
> - Introduced in GitLab 13.7 [with a flag](../../administration/feature_flags.md) named `forti_token_cloud`. Disabled by default.
|
||||
> - [Enabled on self-managed](https://gitlab.com/issue/etc) in GitLab 13.8.
|
||||
> - [Enabled on GitLab.com](https://gitlab.com/issue/etc) in GitLab 13.9.
|
||||
> - [Generally available](issue-link) in GitLab 14.0. [Feature flag <flag name>](issue-link) removed.
|
||||
> - [Generally available](issue-link) in GitLab 14.0. [Feature flag `forti_token_cloud`](issue-link) removed.
|
||||
```
|
||||
|
|
|
@ -22,6 +22,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
|
|||
| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled at the group level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
|
||||
| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled at the instance level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
|
||||
| `:integrations` | This aims to test the available [integrations](../../../user/project/integrations/index.md#available-integrations). The test requires Docker to be installed in the run context. It will provision the containers and can be run against a local instance or using the `gitlab-qa` scenario `Test::Integration::Integrations` |
|
||||
| `:issue`, `:issue_${num}` | Optional links to issues which might be related to the spec. Helps keep track of related issues and can also be used by tools that create test reports. Currently added automatically to `Allure` test report. Multiple tags can be used by adding an optional numeric suffix like `issue_1`, `issue_2` etc. |
|
||||
| `:service_ping_disabled` | The test interacts with the GitLab configuration service ping at the instance level to turn Admin Area setting service ping checkbox on or off. This tag will have the test run only in the `service_ping_disabled` job and must be paired with the `:orchestrated` and `:requires_admin` tags. |
|
||||
| `:jira` | The test requires a Jira Server. [GitLab-QA](https://gitlab.com/gitlab-org/gitlab-qa) provisions the Jira Server in a Docker container when the `Test::Integration::Jira` test scenario is run. |
|
||||
| `:kubernetes` | The test includes a GitLab instance that is configured to be run behind an SSH tunnel, allowing a TLS-accessible GitLab. This test also includes provisioning of at least one Kubernetes cluster to test against. _This tag is often be paired with `:orchestrated`._ |
|
||||
|
@ -42,6 +43,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
|
|||
| `:requires_git_protocol_v2` | The test requires that Git protocol version 2 is enabled on the server. It's assumed to be enabled by default but if not the test can be skipped by setting `QA_CAN_TEST_GIT_PROTOCOL_V2` to `false`. |
|
||||
| `:requires_praefect` | The test requires that the GitLab instance uses [Gitaly Cluster](../../../administration/gitaly/praefect.md) (a.k.a. Praefect) as the repository storage . It's assumed to be used by default but if not the test can be skipped by setting `QA_CAN_TEST_PRAEFECT` to `false`. |
|
||||
| `:runner` | The test depends on and sets up a GitLab Runner instance, typically to run a pipeline. |
|
||||
| `:sanity_feature_flags` | The test run in the `Test::Sanity::FeatureFlags` scenario to verify the functioning of the feature flag handling part of the test framework |
|
||||
| `:skip_live_env` | The test is excluded when run against live deployed environments such as Staging, Canary, and Production. |
|
||||
| `:skip_fips_env` | The test is excluded when run against an environment in FIPS mode. |
|
||||
| `:skip_signup_disabled` | The test uses UI to sign up a new user and is skipped in any environment that does not allow new user registration via the UI. |
|
||||
|
@ -49,4 +51,3 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
|
|||
| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. |
|
||||
| `:testcase` | The link to the test case issue in the [GitLab Project Test Cases](https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases). |
|
||||
| `:transient` | The test tests transient bugs. It is excluded by default. |
|
||||
| `:issue`, `:issue_${num}` | Optional links to issues which might be related to the spec. Helps keep track of related issues and can also be used by tools that create test reports. Currently added automatically to `Allure` test report. Multiple tags can be used by adding an optional numeric suffix like `issue_1`, `issue_2` etc. |
|
||||
|
|
|
@ -160,6 +160,7 @@ the related documentation.
|
|||
| Maximum test cases per [unit test report](../../ci/testing/unit_test_reports.md) | `500000` | Unlimited |
|
||||
| Maximum registered runners | Free tier: `50` per-group / `50` per-project<br/>All paid tiers: `1000` per-group / `1000` per-project | See [Number of registered runners per scope](../../administration/instance_limits.md#number-of-registered-runners-per-scope) |
|
||||
| Limit of dotenv variables | Free tier: `50` / Premium tier: `100` / Ultimate tier: `150` | See [Limit dotenv variables](../../administration/instance_limits.md#limit-dotenv-variables) |
|
||||
| Authorization token duration (minutes) | `15` | To set a custom value, in the Rails console, run `ApplicationSetting.last.update(container_registry_token_expire_delay: <integer>)`, where `<integer>` is the desired number of minutes. |
|
||||
|
||||
## Package registry limits
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ GEM
|
|||
pry (~> 0.10)
|
||||
public_suffix (4.0.6)
|
||||
racc (1.6.0)
|
||||
rack (2.2.3)
|
||||
rack (2.2.3.1)
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rainbow (3.0.0)
|
||||
|
|
|
@ -9,6 +9,8 @@ module QA
|
|||
AuthorizationError = Class.new(RuntimeError)
|
||||
UnknownScopeError = Class.new(RuntimeError)
|
||||
UnknownStateError = Class.new(RuntimeError)
|
||||
UnknownFeatureFlagError = Class.new(RuntimeError)
|
||||
DefinitionFileError = Class.new(RuntimeError)
|
||||
|
||||
class << self
|
||||
# Documentation: https://docs.gitlab.com/ee/api/features.html
|
||||
|
@ -52,7 +54,21 @@ module QA
|
|||
|
||||
def enabled?(key, **scopes)
|
||||
feature = JSON.parse(get_features).find { |flag| flag['name'] == key.to_s }
|
||||
feature && (feature['state'] == 'on' || feature['state'] == 'conditional' && scopes.present? && enabled_scope?(feature['gates'], **scopes))
|
||||
if feature
|
||||
feature['state'] == 'on' ||
|
||||
feature['state'] == 'conditional' && scopes.present? && enabled_scope?(feature['gates'], **scopes)
|
||||
else
|
||||
# The feature wasn't found via the API so we check for a default value.
|
||||
file = Pathname.new('../config/feature_flags')
|
||||
.expand_path(Runtime::Path.qa_root)
|
||||
.glob("**/#{key}.yml")
|
||||
.first
|
||||
|
||||
raise UnknownFeatureFlagError, "No feature flag found named '#{key}'" unless file
|
||||
|
||||
definition = YAML.safe_load(File.read(file))
|
||||
definition['default_enabled'].to_s.casecmp('true') == 0
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
RSpec.describe 'Feature flag handler sanity checks', :sanity_feature_flags do
|
||||
context 'with an existing feature flag definition file' do
|
||||
let(:definition) do
|
||||
path = Pathname.new('../config/feature_flags')
|
||||
.expand_path(Runtime::Path.qa_root)
|
||||
.glob('**/*.yml')
|
||||
.first
|
||||
YAML.safe_load(File.read(path))
|
||||
end
|
||||
|
||||
it 'reads the correct default enabled state' do
|
||||
# This test will fail if we ever remove all the feature flags, but that's very unlikely given how many there
|
||||
# are and how much we rely on them.
|
||||
expect(QA::Runtime::Feature.enabled?(definition['name'])).to be definition['default_enabled']
|
||||
end
|
||||
end
|
||||
|
||||
describe 'feature flag definition files' do
|
||||
let(:file) do
|
||||
path = Pathname.new('../config/feature_flags/development').expand_path(Runtime::Path.qa_root)
|
||||
Tempfile.new(%w[ff-test .yml], path)
|
||||
end
|
||||
|
||||
let(:flag) { Pathname.new(file.path).basename('.yml').to_s }
|
||||
|
||||
before do
|
||||
definition = <<~YAML
|
||||
name: #{flag}
|
||||
type: development
|
||||
default_enabled: #{flag_enabled}
|
||||
YAML
|
||||
File.write(file, definition)
|
||||
end
|
||||
|
||||
after do
|
||||
file.close!
|
||||
end
|
||||
|
||||
context 'with a default disabled feature flag' do
|
||||
let(:flag_enabled) { 'false' }
|
||||
|
||||
it 'reads the flag as disabled' do
|
||||
expect(QA::Runtime::Feature.enabled?(flag)).to be false
|
||||
end
|
||||
|
||||
it 'reads as enabled after the flag is enabled' do
|
||||
QA::Runtime::Feature.enable(flag)
|
||||
|
||||
expect(QA::Runtime::Feature.enabled?(flag)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a default enabled feature flag' do
|
||||
let(:flag_enabled) { 'true' }
|
||||
|
||||
it 'reads the flag as enabled' do
|
||||
expect(QA::Runtime::Feature.enabled?(flag)).to be true
|
||||
end
|
||||
|
||||
it 'reads as disabled after the flag is disabled' do
|
||||
QA::Runtime::Feature.disable(flag)
|
||||
|
||||
expect(QA::Runtime::Feature.enabled?(flag)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,6 +12,7 @@ module QA
|
|||
|
||||
DEFAULT_TEST_PATH_ARGS = ['--', File.expand_path('./features', __dir__)].freeze
|
||||
DEFAULT_STD_ARGS = [$stderr, $stdout].freeze
|
||||
DEFAULT_SKIPPED_TAGS = %w[orchestrated transient sanity_feature_flags].freeze
|
||||
|
||||
def initialize
|
||||
@tty = false
|
||||
|
@ -25,7 +26,7 @@ module QA
|
|||
if tags.any?
|
||||
tags.each { |tag| tags_for_rspec.push(['--tag', tag.to_s]) }
|
||||
else
|
||||
tags_for_rspec.push(%w[--tag ~orchestrated --tag ~transient]) unless (%w[-t --tag] & options).any?
|
||||
tags_for_rspec.push(DEFAULT_SKIPPED_TAGS.map { |tag| %W[--tag ~#{tag}] }) unless (%w[-t --tag] & options).any?
|
||||
end
|
||||
|
||||
tags_for_rspec.push(%w[--tag ~geo]) unless QA::Runtime::Env.geo_environment?
|
||||
|
|
|
@ -61,7 +61,7 @@ RSpec.describe QA::Runtime::Feature do
|
|||
.to receive(:get)
|
||||
.and_return(Struct.new(:code, :body).new(200, %Q([{ "name": "a_flag", "state": "conditional", "gates": #{gates} }])))
|
||||
|
||||
expect(described_class.enabled?(feature_flag, scope => actor)).to be_truthy
|
||||
expect(described_class.enabled?(feature_flag, scope => actor)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -172,7 +172,7 @@ RSpec.describe QA::Runtime::Feature do
|
|||
.to receive(:get)
|
||||
.and_return(Struct.new(:code, :body).new(200, '[{ "name": "a_flag", "state": "on" }]'))
|
||||
|
||||
expect(described_class.enabled?(feature_flag)).to be_truthy
|
||||
expect(described_class.enabled?(feature_flag)).to be true
|
||||
end
|
||||
|
||||
it 'raises an error when the scope is unknown' do
|
||||
|
@ -224,6 +224,75 @@ RSpec.describe QA::Runtime::Feature do
|
|||
let(:gates) { %q([{"key": "groups", "value": ["foo"]}]) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a feature flag is not found via the API and there is no definition file' do
|
||||
before do
|
||||
allow(QA::Runtime::API::Request)
|
||||
.to receive(:new)
|
||||
.with(api_client, "/features")
|
||||
.and_return(request)
|
||||
allow(described_class)
|
||||
.to receive(:get)
|
||||
.and_return(Struct.new(:code, :body).new(200, '[]'))
|
||||
allow(Dir).to receive(:glob).and_return([])
|
||||
end
|
||||
|
||||
it 'raises an error' do
|
||||
expect { described_class.enabled?(feature_flag) }
|
||||
.to raise_error(QA::Runtime::Feature::UnknownFeatureFlagError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with definition files' do
|
||||
context 'when no features are found via the API' do
|
||||
before do
|
||||
allow(QA::Runtime::API::Request)
|
||||
.to receive(:new)
|
||||
.with(api_client, "/features")
|
||||
.and_return(request)
|
||||
allow(described_class)
|
||||
.to receive(:get)
|
||||
.and_return(Struct.new(:code, :body).new(200, '[]'))
|
||||
allow(Dir).to receive(:glob).and_return(['file_path'])
|
||||
allow(File).to receive(:read).and_return(definition)
|
||||
end
|
||||
|
||||
context 'with a default enabled defintion' do
|
||||
let(:definition) { 'default_enabled: true' }
|
||||
|
||||
it 'returns a default enabled flag' do
|
||||
expect(described_class.enabled?(feature_flag)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a default disabled defintion' do
|
||||
let(:definition) { 'default_enabled: false' }
|
||||
|
||||
it 'returns a default disabled flag' do
|
||||
expect(described_class.enabled?(feature_flag)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the feature is found via the API' do
|
||||
before do
|
||||
allow(QA::Runtime::API::Request)
|
||||
.to receive(:new)
|
||||
.with(api_client, "/features")
|
||||
.and_return(request)
|
||||
allow(described_class)
|
||||
.to receive(:get)
|
||||
.and_return(Struct.new(:code, :body).new(200, '[{ "name": "a_flag", "state": "on" }]'))
|
||||
end
|
||||
|
||||
it 'returns the value from the API not the definition file' do
|
||||
expect(Dir).not_to receive(:glob)
|
||||
expect(File).not_to receive(:read)
|
||||
|
||||
expect(described_class.enabled?(feature_flag)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe QA::Specs::Runner do
|
||||
shared_examples 'excludes orchestrated, transient, and geo' do
|
||||
it 'excludes the orchestrated, transient, and geo tags, and includes default args' do
|
||||
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
shared_examples 'excludes default skipped, and geo' do
|
||||
it 'excludes the default skipped and geo tags, and includes default args' do
|
||||
expect_rspec_runner_arguments(DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
|
||||
subject.perform
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const('DEFAULT_SKIPPED_TAGS', %w[--tag ~orchestrated --tag ~transient --tag ~sanity_feature_flags].freeze)
|
||||
end
|
||||
|
||||
describe '#perform' do
|
||||
before do
|
||||
allow(QA::Runtime::Browser).to receive(:configure!)
|
||||
|
@ -17,13 +21,15 @@ RSpec.describe QA::Specs::Runner do
|
|||
QA::Runtime::Scenario.define(:klass, "QA::Scenario::Test::Instance::All")
|
||||
end
|
||||
|
||||
it_behaves_like 'excludes orchestrated, transient, and geo'
|
||||
it_behaves_like 'excludes default skipped, and geo'
|
||||
|
||||
context 'when tty is set' do
|
||||
subject { described_class.new.tap { |runner| runner.tty = true } }
|
||||
|
||||
it 'sets the `--tty` flag' do
|
||||
expect_rspec_runner_arguments(['--tty', '--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
expect_rspec_runner_arguments(
|
||||
['--tty'] + DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS]
|
||||
)
|
||||
|
||||
subject.perform
|
||||
end
|
||||
|
@ -39,7 +45,10 @@ RSpec.describe QA::Specs::Runner do
|
|||
end
|
||||
|
||||
it 'sets the `--dry-run` flag' do
|
||||
expect_rspec_runner_arguments(['--dry-run', '--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS], [$stderr, anything])
|
||||
expect_rspec_runner_arguments(
|
||||
['--dry-run'] + DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS],
|
||||
[$stderr, anything]
|
||||
)
|
||||
|
||||
subject.perform
|
||||
end
|
||||
|
@ -73,7 +82,10 @@ RSpec.describe QA::Specs::Runner do
|
|||
subject { described_class.new.tap { |runner| runner.options = %w[--tag actioncable] } }
|
||||
|
||||
it 'includes the option value in the file name' do
|
||||
expect_rspec_runner_arguments(['--dry-run', '--tag', '~geo', '--tag', 'actioncable', *described_class::DEFAULT_TEST_PATH_ARGS], [$stderr, anything])
|
||||
expect_rspec_runner_arguments(
|
||||
['--dry-run', '--tag', '~geo', '--tag', 'actioncable', *described_class::DEFAULT_TEST_PATH_ARGS],
|
||||
[$stderr, anything]
|
||||
)
|
||||
|
||||
expect(File).to receive(:open).with('no_of_examples/test_instance_all_actioncable.txt', 'w') { '22' }
|
||||
|
||||
|
@ -98,7 +110,10 @@ RSpec.describe QA::Specs::Runner do
|
|||
end
|
||||
|
||||
it 'sets the `--dry-run` flag' do
|
||||
expect_rspec_runner_arguments(['--dry-run', '--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS], [$stderr, anything])
|
||||
expect_rspec_runner_arguments(
|
||||
['--dry-run'] + DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS],
|
||||
[$stderr, anything]
|
||||
)
|
||||
|
||||
subject.perform
|
||||
end
|
||||
|
@ -125,7 +140,9 @@ RSpec.describe QA::Specs::Runner do
|
|||
subject { described_class.new.tap { |runner| runner.tags = %i[orchestrated github] } }
|
||||
|
||||
it 'focuses on the given tags' do
|
||||
expect_rspec_runner_arguments(['--tag', 'orchestrated', '--tag', 'github', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
expect_rspec_runner_arguments(
|
||||
['--tag', 'orchestrated', '--tag', 'github', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS]
|
||||
)
|
||||
|
||||
subject.perform
|
||||
end
|
||||
|
@ -144,8 +161,8 @@ RSpec.describe QA::Specs::Runner do
|
|||
context 'when "qa/specs/features/foo" is set as options' do
|
||||
subject { described_class.new.tap { |runner| runner.options = %w[qa/specs/features/foo] } }
|
||||
|
||||
it 'passes the given tests path and excludes the orchestrated, transient, and geo tags' do
|
||||
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', 'qa/specs/features/foo'])
|
||||
it 'passes the given tests path and excludes the default skipped, and geo tags' do
|
||||
expect_rspec_runner_arguments(DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', 'qa/specs/features/foo'])
|
||||
|
||||
subject.perform
|
||||
end
|
||||
|
@ -167,7 +184,7 @@ RSpec.describe QA::Specs::Runner do
|
|||
end
|
||||
|
||||
it 'includes default args and excludes the skip_signup_disabled tag' do
|
||||
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', '--tag', '~skip_signup_disabled', *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
expect_rspec_runner_arguments(DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', '--tag', '~skip_signup_disabled', *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
|
||||
subject.perform
|
||||
end
|
||||
|
@ -179,7 +196,7 @@ RSpec.describe QA::Specs::Runner do
|
|||
end
|
||||
|
||||
it 'includes default args and excludes the skip_live_env tag' do
|
||||
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', '--tag', '~skip_live_env', *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
expect_rspec_runner_arguments(DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', '--tag', '~skip_live_env', *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
subject.perform
|
||||
end
|
||||
end
|
||||
|
@ -212,7 +229,10 @@ RSpec.describe QA::Specs::Runner do
|
|||
end
|
||||
|
||||
it 'includes default args and excludes all unsupported tags' do
|
||||
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *excluded_feature_tags_except(feature), *described_class::DEFAULT_TEST_PATH_ARGS])
|
||||
expect_rspec_runner_arguments(
|
||||
DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', *excluded_feature_tags_except(feature),
|
||||
*described_class::DEFAULT_TEST_PATH_ARGS]
|
||||
)
|
||||
|
||||
subject.perform
|
||||
end
|
||||
|
@ -237,11 +257,11 @@ RSpec.describe QA::Specs::Runner do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'excludes orchestrated, transient, and geo'
|
||||
it_behaves_like 'excludes default skipped, and geo'
|
||||
end
|
||||
|
||||
context 'when features are not specified' do
|
||||
it_behaves_like 'excludes orchestrated, transient, and geo'
|
||||
it_behaves_like 'excludes default skipped, and geo'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -248,7 +248,6 @@ function download_chart() {
|
|||
helm repo add gitlab https://charts.gitlab.io
|
||||
|
||||
echoinfo "Building the gitlab chart's dependencies..."
|
||||
helm dependency build "gitlab-${GITLAB_HELM_CHART_REF}"
|
||||
}
|
||||
|
||||
function base_config_changed() {
|
||||
|
|
|
@ -44,6 +44,14 @@ RSpec.describe Projects::CompareController do
|
|||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
context 'with missing parameters' do
|
||||
let(:params) { super().merge(from: '', to: '') }
|
||||
|
||||
it 'returns successfully' do
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET show' do
|
||||
|
|
|
@ -44,7 +44,7 @@ RSpec.describe Integrations::Campfire do
|
|||
|
||||
it "calls Campfire API to get a list of rooms and speak in a room" do
|
||||
# make sure a valid list of rooms is returned
|
||||
body = File.read(Rails.root + 'spec/fixtures/project_services/campfire/rooms.json')
|
||||
body = File.read(Rails.root + 'spec/fixtures/integrations/campfire/rooms.json')
|
||||
|
||||
stub_full_request(@rooms_url).with(basic_auth: @auth).to_return(
|
||||
body: body,
|
||||
|
@ -65,7 +65,7 @@ RSpec.describe Integrations::Campfire do
|
|||
|
||||
it "calls Campfire API to get a list of rooms but shouldn't speak in a room" do
|
||||
# return a list of rooms that do not contain a room named 'test-room'
|
||||
body = File.read(Rails.root + 'spec/fixtures/project_services/campfire/rooms2.json')
|
||||
body = File.read(Rails.root + 'spec/fixtures/integrations/campfire/rooms2.json')
|
||||
stub_full_request(@rooms_url).with(basic_auth: @auth).to_return(
|
||||
body: body,
|
||||
status: 200,
|
||||
|
|
|
@ -44,7 +44,7 @@ Integration.available_integration_names.each do |integration|
|
|||
|
||||
let(:licensed_features) do
|
||||
{
|
||||
'github' => :github_project_service_integration
|
||||
'github' => :github_integration
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ GEM
|
|||
parallel (1.19.2)
|
||||
parser (2.7.2.0)
|
||||
ast (~> 2.4.1)
|
||||
rack (2.2.3)
|
||||
rack (2.2.3.1)
|
||||
rainbow (3.0.0)
|
||||
regexp_parser (1.8.2)
|
||||
rexml (3.2.4)
|
||||
|
|
Loading…
Reference in New Issue