Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
12b96f0b82
commit
135b9a7019
|
|
@ -8,7 +8,6 @@ exclude:
|
|||
- 'spec/**/*'
|
||||
- 'ee/spec/**/*'
|
||||
require:
|
||||
- './haml_lint/linter/documentation_links.rb'
|
||||
- './haml_lint/linter/inline_javascript.rb'
|
||||
- './haml_lint/linter/no_plain_nodes.rb'
|
||||
|
||||
|
|
|
|||
|
|
@ -465,8 +465,6 @@ Gitlab/DocumentationLinks/HardcodedUrl:
|
|||
|
||||
Gitlab/DocumentationLinks/Link:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- '**/*.haml'
|
||||
|
||||
GitlabSecurity/PublicSend:
|
||||
Enabled: true
|
||||
|
|
|
|||
|
|
@ -2279,11 +2279,11 @@ Gitlab/BoundedContexts:
|
|||
- 'ee/app/graphql/mutations/iterations/create.rb'
|
||||
- 'ee/app/graphql/mutations/iterations/delete.rb'
|
||||
- 'ee/app/graphql/mutations/iterations/update.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/base.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/create.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/admin/base.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/admin/create.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/admin/update.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/base.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/create.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/delete.rb'
|
||||
- 'ee/app/graphql/mutations/member_roles/update.rb'
|
||||
- 'ee/app/graphql/mutations/quality_management/test_cases/create.rb'
|
||||
|
|
|
|||
|
|
@ -320,7 +320,6 @@ Gitlab/StrongMemoizeAttr:
|
|||
- 'ee/app/services/protected_environments/base_service.rb'
|
||||
- 'ee/app/services/security/ingestion/tasks/ingest_vulnerabilities/mark_resolved_as_detected.rb'
|
||||
- 'ee/app/services/security/report_summary_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/operational_vulnerabilities_configuration_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/validate_policy_service.rb'
|
||||
- 'ee/app/services/status_page/publish_attachments_service.rb'
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ Layout/EmptyLinesAroundMethodBody:
|
|||
- 'lib/gitlab/database/partitioning/list/convert_table.rb'
|
||||
- 'lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb'
|
||||
- 'lib/gitlab/diff/file.rb'
|
||||
- 'lib/gitlab/fp/settings/default_settings_parser.rb'
|
||||
- 'lib/gitlab/git/repository.rb'
|
||||
- 'lib/gitlab/gitaly_client/operation_service.rb'
|
||||
- 'lib/gitlab/import/import_failure_service.rb'
|
||||
|
|
@ -28,5 +27,4 @@ Layout/EmptyLinesAroundMethodBody:
|
|||
- 'spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb'
|
||||
- 'spec/lib/gitlab/popen/runner_spec.rb'
|
||||
- 'spec/support/helpers/workhorse_lfs_helpers.rb'
|
||||
- 'spec/support/matchers/invoke_rop_steps.rb'
|
||||
- 'tooling/lib/tooling/find_changes.rb'
|
||||
|
|
|
|||
|
|
@ -261,7 +261,6 @@ Layout/LineEndStringConcatenationIndentation:
|
|||
- 'ee/spec/requests/api/graphql/mutations/iterations/create_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/mutations/iterations/delete_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/mutations/iterations/update_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/mutations/member_role/create_member_role_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/mutations/projects/initialize_product_analytics_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/mutations/projects/product_analytics_project_settings_update_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb'
|
||||
|
|
|
|||
|
|
@ -727,7 +727,6 @@ Layout/LineLength:
|
|||
- 'ee/app/services/security/report_summary_service.rb'
|
||||
- 'ee/app/services/security/scanned_resources_counting_service.rb'
|
||||
- 'ee/app/services/security/scanned_resources_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/policy_commit_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/policy_configuration_validation_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/process_policy_service.rb'
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ Rails/InverseOf:
|
|||
- 'app/models/merge_request/metrics.rb'
|
||||
- 'app/models/namespace.rb'
|
||||
- 'app/models/notification_setting.rb'
|
||||
- 'app/models/packages/maven/metadatum.rb'
|
||||
- 'app/models/project.rb'
|
||||
- 'app/models/project_label.rb'
|
||||
- 'app/models/resource_state_event.rb'
|
||||
|
|
|
|||
|
|
@ -1110,7 +1110,6 @@ RSpec/BeEq:
|
|||
- 'spec/models/integrations/jira_cloud_app_spec.rb'
|
||||
- 'spec/models/integrations/jira_spec.rb'
|
||||
- 'spec/models/integrations/prometheus_spec.rb'
|
||||
- 'spec/models/integrations/telegram_spec.rb'
|
||||
- 'spec/models/integrations/zentao_tracker_data_spec.rb'
|
||||
- 'spec/models/issue_spec.rb'
|
||||
- 'spec/models/jira_connect_installation_spec.rb'
|
||||
|
|
|
|||
|
|
@ -330,7 +330,6 @@ RSpec/BeforeAllRoleAssignment:
|
|||
- 'ee/spec/requests/api/graphql/boards/epic_lists_query_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/ci/minutes/usage_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/compliance_management/merge_requests/compliance_violations_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/dora/dora_scores_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/gitlab_subscriptions/preview_billable_user_change_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/group/dast_profile_schedule_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/group/epic/epic_aggregate_query_spec.rb'
|
||||
|
|
|
|||
|
|
@ -574,7 +574,6 @@ RSpec/ContextWording:
|
|||
- 'ee/spec/serializers/dashboard_operations_project_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/group_child_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/issue_sidebar_extras_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/merge_request_poll_cached_widget_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/user_serializer_spec.rb'
|
||||
- 'ee/spec/serializers/environment_entity_spec.rb'
|
||||
- 'ee/spec/serializers/issue_serializer_spec.rb'
|
||||
|
|
@ -2203,7 +2202,6 @@ RSpec/ContextWording:
|
|||
- 'spec/requests/api/project_clusters_spec.rb'
|
||||
- 'spec/requests/api/project_container_repositories_spec.rb'
|
||||
- 'spec/requests/api/project_events_spec.rb'
|
||||
- 'spec/requests/api/project_export_spec.rb'
|
||||
- 'spec/requests/api/project_packages_spec.rb'
|
||||
- 'spec/requests/api/project_snippets_spec.rb'
|
||||
- 'spec/requests/api/projects_spec.rb'
|
||||
|
|
|
|||
|
|
@ -674,10 +674,7 @@ RSpec/FeatureCategory:
|
|||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_ci_builds_metric_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_deployment_approvals_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/epics_deepest_relationship_level_metric_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/historical_max_users_metrics_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/license_management_jobs_metric_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/license_metric_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/licensee_metrics_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environment_approval_rules_required_approvals_average_metric_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environments_required_approvals_average_metric_spec.rb'
|
||||
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/user_cap_setting_enabled_metric_spec.rb'
|
||||
|
|
@ -902,7 +899,6 @@ RSpec/FeatureCategory:
|
|||
- 'ee/spec/serializers/ee/issue_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/issue_sidebar_basic_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/issue_sidebar_extras_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/merge_request_poll_cached_widget_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/note_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/user_serializer_spec.rb'
|
||||
- 'ee/spec/serializers/epic_entity_spec.rb'
|
||||
|
|
@ -1727,7 +1723,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/helpers/admin/identities_helper_spec.rb'
|
||||
- 'spec/helpers/appearances_helper_spec.rb'
|
||||
- 'spec/helpers/application_helper_spec.rb'
|
||||
- 'spec/helpers/application_settings_helper_spec.rb'
|
||||
- 'spec/helpers/auto_devops_helper_spec.rb'
|
||||
- 'spec/helpers/award_emoji_helper_spec.rb'
|
||||
- 'spec/helpers/badges_helper_spec.rb'
|
||||
|
|
@ -2125,7 +2120,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/lib/gitlab/ci/parsers/test/junit_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/parsers_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/pipeline/chain/build_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/pipeline/chain/command_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/pipeline/chain/create_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/pipeline/chain/ensure_environments_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/pipeline/chain/ensure_resource_groups_spec.rb'
|
||||
|
|
@ -2502,7 +2496,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/lib/gitlab/git/push_spec.rb'
|
||||
- 'spec/lib/gitlab/git/raw_diff_change_spec.rb'
|
||||
- 'spec/lib/gitlab/git/remote_mirror_spec.rb'
|
||||
- 'spec/lib/gitlab/git/user_spec.rb'
|
||||
- 'spec/lib/gitlab/git/util_spec.rb'
|
||||
- 'spec/lib/gitlab/git/wiki_page_version_spec.rb'
|
||||
- 'spec/lib/gitlab/git_access_design_spec.rb'
|
||||
|
|
@ -3764,7 +3757,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/serializers/member_user_entity_spec.rb'
|
||||
- 'spec/serializers/merge_request_for_pipeline_entity_spec.rb'
|
||||
- 'spec/serializers/merge_request_metrics_helper_spec.rb'
|
||||
- 'spec/serializers/merge_request_poll_widget_entity_spec.rb'
|
||||
- 'spec/serializers/merge_request_user_entity_spec.rb'
|
||||
- 'spec/serializers/merge_request_widget_commit_entity_spec.rb'
|
||||
- 'spec/serializers/merge_requests/pipeline_entity_spec.rb'
|
||||
|
|
|
|||
|
|
@ -734,7 +734,6 @@ RSpec/NamedSubject:
|
|||
- 'ee/spec/serializers/ee/issue_board_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/issue_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/issue_sidebar_extras_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/merge_request_poll_cached_widget_entity_spec.rb'
|
||||
- 'ee/spec/serializers/ee/note_entity_spec.rb'
|
||||
- 'ee/spec/serializers/environment_entity_spec.rb'
|
||||
- 'ee/spec/serializers/epic_entity_spec.rb'
|
||||
|
|
@ -2459,7 +2458,6 @@ RSpec/NamedSubject:
|
|||
- 'spec/models/integrations/jenkins_spec.rb'
|
||||
- 'spec/models/integrations/matrix_spec.rb'
|
||||
- 'spec/models/integrations/squash_tm_spec.rb'
|
||||
- 'spec/models/integrations/telegram_spec.rb'
|
||||
- 'spec/models/integrations/zentao_spec.rb'
|
||||
- 'spec/models/internal_id_spec.rb'
|
||||
- 'spec/models/issue/metrics_spec.rb'
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ RSpec/SubjectDeclaration:
|
|||
- 'spec/models/event_collection_spec.rb'
|
||||
- 'spec/models/group_spec.rb'
|
||||
- 'spec/models/integrations/matrix_spec.rb'
|
||||
- 'spec/models/integrations/telegram_spec.rb'
|
||||
- 'spec/models/issue_spec.rb'
|
||||
- 'spec/models/project_spec.rb'
|
||||
- 'spec/models/x509_certificate_spec.rb'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
RSpec/VerifiedDoubleReference:
|
||||
Exclude:
|
||||
- 'ee/spec/controllers/groups/analytics/productivity_analytics_controller_spec.rb'
|
||||
- 'ee/spec/controllers/groups/security/policies_controller_spec.rb'
|
||||
- 'ee/spec/features/custom_models/code_suggestions_spec.rb'
|
||||
- 'ee/spec/features/custom_models/duo_chat_spec.rb'
|
||||
- 'ee/spec/features/merge_request/user_sees_security_policy_rules_licence_compliance_spec.rb'
|
||||
|
|
@ -49,7 +48,6 @@ RSpec/VerifiedDoubleReference:
|
|||
- 'ee/spec/requests/api/graphql/project/google_cloud/artifact_registry/docker_images_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/user_code_suggestions_available_spec.rb'
|
||||
- 'ee/spec/requests/api/security_scans_spec.rb'
|
||||
- 'ee/spec/requests/projects/security/policies_controller_spec.rb'
|
||||
- 'ee/spec/serializers/dashboard_environments_project_entity_spec.rb'
|
||||
- 'ee/spec/serializers/vulnerabilities/finding_entity_spec.rb'
|
||||
- 'ee/spec/services/analytics/cycle_analytics/consistency_check_service_spec.rb'
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ Style/GuardClause:
|
|||
- 'app/models/operations/feature_flags/strategy.rb'
|
||||
- 'app/models/operations/feature_flags/user_list.rb'
|
||||
- 'app/models/packages/conan/file_metadatum.rb'
|
||||
- 'app/models/packages/maven/metadatum.rb'
|
||||
- 'app/models/pages_domain.rb'
|
||||
- 'app/models/personal_access_token.rb'
|
||||
- 'app/models/project.rb'
|
||||
|
|
@ -161,7 +160,6 @@ Style/GuardClause:
|
|||
- 'app/services/protected_branches/legacy_api_update_service.rb'
|
||||
- 'app/services/repositories/changelog_service.rb'
|
||||
- 'app/services/snippets/repository_validation_service.rb'
|
||||
- 'app/services/todo_service.rb'
|
||||
- 'app/services/users/build_service.rb'
|
||||
- 'app/services/wikis/create_attachment_service.rb'
|
||||
- 'app/uploaders/content_type_whitelist.rb'
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ Style/IfUnlessModifier:
|
|||
- 'app/models/packages/conan/file_metadatum.rb'
|
||||
- 'app/models/packages/dependency.rb'
|
||||
- 'app/models/packages/go/module.rb'
|
||||
- 'app/models/packages/maven/metadatum.rb'
|
||||
- 'app/models/pages_domain.rb'
|
||||
- 'app/models/project.rb'
|
||||
- 'app/models/project_team.rb'
|
||||
|
|
@ -317,7 +316,6 @@ Style/IfUnlessModifier:
|
|||
- 'ee/app/services/merge_trains/refresh_merge_request_service.rb'
|
||||
- 'ee/app/services/projects/mark_for_deletion_service.rb'
|
||||
- 'ee/app/services/projects/update_mirror_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/policy_configuration_validation_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/process_policy_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/project_create_service.rb'
|
||||
|
|
|
|||
|
|
@ -1228,7 +1228,6 @@ Style/InlineDisableAnnotation:
|
|||
- 'ee/app/services/app_sec/dast/site_tokens/find_or_create_service.rb'
|
||||
- 'ee/app/services/app_sec/dast/sites/find_or_create_service.rb'
|
||||
- 'ee/app/services/approval_rules/params_filtering_service.rb'
|
||||
- 'ee/app/services/billable_members/destroy_service.rb'
|
||||
- 'ee/app/services/ci/minutes/additional_packs/create_service.rb'
|
||||
- 'ee/app/services/ci/minutes/refresh_cached_data_service.rb'
|
||||
- 'ee/app/services/ci/minutes/reset_usage_service.rb'
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ Style/SuperArguments:
|
|||
- 'app/models/current.rb'
|
||||
- 'app/models/hooks/service_hook.rb'
|
||||
- 'app/models/integrations/matrix.rb'
|
||||
- 'app/models/integrations/telegram.rb'
|
||||
- 'app/models/issue.rb'
|
||||
- 'app/models/label.rb'
|
||||
- 'app/models/list.rb'
|
||||
|
|
|
|||
|
|
@ -55,5 +55,5 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<ci-icon v-if="status" :status="statusObject" show-status-text class="!gl-border-0" />
|
||||
<ci-icon v-if="status" :status="statusObject" show-status-text />
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
mutation updatePipelineVariablesDefaultRoleGroupSetting(
|
||||
$fullPath: ID!
|
||||
$pipelineVariablesDefaultRole: PipelineVariablesDefaultRoleType!
|
||||
) {
|
||||
namespaceSettingsUpdate(
|
||||
input: { fullPath: $fullPath, pipelineVariablesDefaultRole: $pipelineVariablesDefaultRole }
|
||||
) {
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
query getPipelineVariablesDefaultRoleGroupSetting($fullPath: ID!) {
|
||||
group(fullPath: $fullPath) {
|
||||
id
|
||||
ciCdSettings {
|
||||
pipelineVariablesDefaultRole
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import PipelineVariablesDefaultRole from './pipeline_variables_default_role.vue';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
const apolloProvider = new VueApollo({
|
||||
defaultClient: createDefaultClient(),
|
||||
});
|
||||
|
||||
export default (containerId = 'js-pipeline-variables-default-role') => {
|
||||
const containerEl = document.getElementById(containerId);
|
||||
|
||||
if (!containerEl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { fullPath } = containerEl.dataset;
|
||||
|
||||
return new Vue({
|
||||
el: containerEl,
|
||||
name: 'PipelineVariablesDefaultRoleRoot',
|
||||
apolloProvider,
|
||||
provide: {
|
||||
fullPath,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(PipelineVariablesDefaultRole);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
<script>
|
||||
import { GlButton, GlFormGroup, GlFormRadio, GlFormRadioGroup, GlLink } from '@gitlab/ui';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { createAlert } from '~/alert';
|
||||
import { __, s__ } from '~/locale';
|
||||
import { reportToSentry } from '~/ci/utils';
|
||||
import getPipelineVariablesDefaultRoleSetting from './graphql/queries/get_pipeline_variables_default_role_group_setting.query.graphql';
|
||||
import updatePipelineVariablesDefaultRoleSetting from './graphql/mutations/update_pipeline_variables_default_role_group_setting.mutation.graphql';
|
||||
|
||||
export const DEFAULT_ROLE_DEVELOPER = 'DEVELOPER';
|
||||
export const DEFAULT_ROLE_MAINTAINER = 'MAINTAINER';
|
||||
export const DEFAULT_ROLE_NO_ONE = 'NO_ONE_ALLOWED';
|
||||
export const DEFAULT_ROLE_OWNER = 'OWNER';
|
||||
|
||||
export default {
|
||||
name: 'PipelineVariablesDefaultRole',
|
||||
helpPath: helpPagePath('ci/variables/_index', {
|
||||
anchor: 'cicd-variable-precedence',
|
||||
}),
|
||||
ROLE_OPTIONS: [
|
||||
{
|
||||
text: __('No one allowed'),
|
||||
value: DEFAULT_ROLE_NO_ONE,
|
||||
help: s__('CiVariables|Pipeline variables cannot be used.'),
|
||||
},
|
||||
{
|
||||
text: __('Owner'),
|
||||
value: DEFAULT_ROLE_OWNER,
|
||||
},
|
||||
{
|
||||
text: __('Maintainer'),
|
||||
value: DEFAULT_ROLE_MAINTAINER,
|
||||
},
|
||||
{
|
||||
text: __('Developer'),
|
||||
value: DEFAULT_ROLE_DEVELOPER,
|
||||
},
|
||||
],
|
||||
components: { GlButton, GlFormGroup, GlFormRadio, GlFormRadioGroup, GlLink },
|
||||
inject: ['fullPath'],
|
||||
data() {
|
||||
return {
|
||||
isSubmitting: false,
|
||||
pipelineVariablesDefaultRole: null,
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
pipelineVariablesDefaultRole: {
|
||||
query: getPipelineVariablesDefaultRoleSetting,
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.fullPath,
|
||||
};
|
||||
},
|
||||
update({ group }) {
|
||||
return (
|
||||
group?.ciCdSettings?.pipelineVariablesDefaultRole?.toUpperCase() || DEFAULT_ROLE_NO_ONE
|
||||
);
|
||||
},
|
||||
error(err) {
|
||||
createAlert({
|
||||
message: s__(
|
||||
'CiVariables|There was a problem fetching the pipeline variables default role.',
|
||||
),
|
||||
});
|
||||
reportToSentry(this.$options.name, err);
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async updateDefaultRole() {
|
||||
this.isSubmitting = true;
|
||||
try {
|
||||
const {
|
||||
data: {
|
||||
namespaceSettingsUpdate: { errors },
|
||||
},
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: updatePipelineVariablesDefaultRoleSetting,
|
||||
variables: {
|
||||
fullPath: this.fullPath,
|
||||
pipelineVariablesDefaultRole: this.pipelineVariablesDefaultRole,
|
||||
},
|
||||
});
|
||||
|
||||
if (errors.length) {
|
||||
createAlert({ message: errors[0].message });
|
||||
reportToSentry(this.$options.name, errors[0].message);
|
||||
} else {
|
||||
this.$toast.show(s__('CiVariables|Pipeline variable access role successfully updated.'));
|
||||
}
|
||||
} catch (err) {
|
||||
createAlert({
|
||||
message: s__(
|
||||
'CiVariables|There was a problem updating the pipeline variables default role setting.',
|
||||
),
|
||||
});
|
||||
reportToSentry(this.$options.name, err);
|
||||
}
|
||||
this.isSubmitting = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-mb-5">
|
||||
<gl-form-group :label="s__('CiVariables|Default role to use pipeline variables')">
|
||||
<template #label-description>
|
||||
<span>{{
|
||||
s__(
|
||||
'CiVariables|SSelect the default minimum role to use in new projects, to run a new pipeline with pipeline variables.',
|
||||
)
|
||||
}}</span>
|
||||
<gl-link :href="$options.helpPath" target="_blank">{{
|
||||
s__('CiVariables|What are pipeline variables?')
|
||||
}}</gl-link>
|
||||
</template>
|
||||
<gl-form-radio-group v-model="pipelineVariablesDefaultRole">
|
||||
<gl-form-radio v-for="role in $options.ROLE_OPTIONS" :key="role.value" :value="role.value">
|
||||
{{ role.text }}
|
||||
<template v-if="role.help" #help>{{ role.help }}</template>
|
||||
</gl-form-radio>
|
||||
</gl-form-radio-group>
|
||||
<gl-button
|
||||
category="primary"
|
||||
variant="confirm"
|
||||
class="gl-mt-3"
|
||||
:loading="isSubmitting"
|
||||
@click="updateDefaultRole"
|
||||
>{{ __('Save changes') }}
|
||||
</gl-button>
|
||||
</gl-form-group>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -2,6 +2,7 @@ import initStaleRunnerCleanupSetting from 'ee_else_ce/group_settings/stale_runne
|
|||
import { initAllowRunnerRegistrationTokenToggle } from '~/group_settings/allow_runner_registration_token_toggle';
|
||||
import { initJwtCiCdJobTokenEnabledToggle } from '~/group_settings/jwt_ci_cd_job_token_enabled_toggle';
|
||||
|
||||
import initPipelineVariablesDefaultRole from '~/group_settings/pipeline_variables_default_role';
|
||||
import initVariableList from '~/ci/ci_variable_list';
|
||||
import initSharedRunnersForm from '~/group_settings/mount_shared_runners';
|
||||
import initSettingsPanels from '~/settings_panels';
|
||||
|
|
@ -15,3 +16,4 @@ initJwtCiCdJobTokenEnabledToggle();
|
|||
initSharedRunnersForm();
|
||||
initStaleRunnerCleanupSetting();
|
||||
initVariableList();
|
||||
initPipelineVariablesDefaultRole();
|
||||
|
|
|
|||
|
|
@ -40,14 +40,21 @@ module Mutations
|
|||
required: false,
|
||||
description: 'Variables for the pipeline.'
|
||||
|
||||
argument :inputs, [Types::Ci::Inputs::InputType],
|
||||
required: false,
|
||||
description: 'Inputs for the pipeline.',
|
||||
experiment: { milestone: '17.10' }
|
||||
|
||||
authorize :create_pipeline
|
||||
|
||||
def resolve(project_path:, ref:, async: false, variables: {})
|
||||
def resolve(project_path:, ref:, async: false, variables: {}, inputs: [])
|
||||
project = authorized_find!(project_path)
|
||||
creation_params = { ref: ref, variables_attributes: variables.map(&:to_h) }
|
||||
service = ::Ci::CreatePipelineService.new(project, current_user, creation_params)
|
||||
|
||||
response = execute_service(service, source, async)
|
||||
execute_options = EXECUTE_OPTIONS.merge(inputs: parse_inputs(inputs))
|
||||
|
||||
service = ::Ci::CreatePipelineService.new(project, current_user, creation_params)
|
||||
response = execute_service(service, source, async, execute_options)
|
||||
|
||||
if response.success?
|
||||
if async
|
||||
|
|
@ -62,11 +69,11 @@ module Mutations
|
|||
|
||||
private
|
||||
|
||||
def execute_service(service, source, async)
|
||||
def execute_service(service, source, async, options)
|
||||
if async
|
||||
service.execute_async(source, EXECUTE_OPTIONS)
|
||||
service.execute_async(source, options)
|
||||
else
|
||||
service.execute(source, **EXECUTE_OPTIONS)
|
||||
service.execute(source, **options)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -75,6 +82,10 @@ module Mutations
|
|||
|
||||
'api'
|
||||
end
|
||||
|
||||
def parse_inputs(inputs)
|
||||
inputs.to_h { |input| [input.key, input.value] }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Ci
|
||||
module Inputs
|
||||
class InputType < BaseInputObject
|
||||
graphql_name 'CiInputsInputType'
|
||||
description 'Attributes for defining an input.'
|
||||
|
||||
argument :key,
|
||||
GraphQL::Types::String,
|
||||
required: true,
|
||||
description: 'Name of the input.'
|
||||
|
||||
argument :value,
|
||||
Inputs::ValueInputType,
|
||||
required: true,
|
||||
description: 'Value of the input.'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Ci
|
||||
module Inputs
|
||||
class ValueInputType < BaseScalar
|
||||
graphql_name 'CiInputsValueInputType'
|
||||
description 'Value for a CI input. Can be a string, array, number, or boolean.'
|
||||
|
||||
def self.coerce_input(value, _ctx)
|
||||
case value
|
||||
when String, Array, Numeric, TrueClass, FalseClass, NilClass
|
||||
value
|
||||
else
|
||||
raise GraphQL::CoercionError, 'Invalid CI input value'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -13,3 +13,5 @@ module Types
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
::Types::PermissionTypes::WorkItem.prepend_mod
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ module WebHooks
|
|||
end
|
||||
|
||||
def help_path
|
||||
'user/project/integrations/webhooks'
|
||||
Gitlab::Routing.url_helpers.help_page_path('user/project/integrations/webhooks.md')
|
||||
end
|
||||
|
||||
# @return [Boolean] Whether or not the WebHook is currently throttled.
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class SystemHook < WebHook
|
|||
end
|
||||
|
||||
def help_path
|
||||
'administration/system_hooks'
|
||||
Gitlab::Routing.url_helpers.help_page_path('administration/system_hooks.md')
|
||||
end
|
||||
|
||||
override :validate_public_url?
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
- save_endpoint = local_assigns.fetch(:save_endpoint, nil)
|
||||
- is_group = !@group.nil?
|
||||
- is_project = !@project.nil?
|
||||
- is_root_group = @group && @group.root?
|
||||
|
||||
- if is_root_group
|
||||
#js-pipeline-variables-default-role{ data: { full_path: @group.full_path } }
|
||||
|
||||
- if is_project
|
||||
#js-ci-variables-minimum-override-role-app{ data: { full_path: @project.full_path } }
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@
|
|||
window.gl.mrWidgetData.pipeline_etag = '#{graphql_etag_pipeline_sha_path(@merge_request.diff_head_sha)}';
|
||||
window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge.md")}';
|
||||
window.gl.mrWidgetData.ci_troubleshooting_docs_path = '#{help_page_path('ci/debugging.md')}';
|
||||
window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviews/_index.md', anchor: 'troubleshooting')}';
|
||||
window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds.md', anchor: 'require-a-successful-pipeline-for-merge')}';
|
||||
window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/merge_request_troubleshooting.md')}';
|
||||
window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/auto_merge.md', anchor: 'require-a-successful-pipeline-for-merge')}';
|
||||
window.gl.mrWidgetData.code_coverage_check_help_page_path = '#{help_page_path('ci/testing/code_coverage/_index.md', anchor: 'add-a-coverage-check-approval-rule')}';
|
||||
window.gl.mrWidgetData.security_configuration_path = '#{project_security_configuration_path(@project)}';
|
||||
window.gl.mrWidgetData.license_compliance_docs_path = '#{help_page_path('user/compliance/license_scanning_of_cyclonedx_files/_index.md')}';
|
||||
window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/approvals/rules.md', anchor: 'eligible-approvers')}';
|
||||
window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/approvals/_index.md")}';
|
||||
window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("ci/testing/code_quality.md", anchor: "code-quality-reports")}';
|
||||
window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("ci/testing/code_quality.md", anchor: "pipeline-details-view")}';
|
||||
window.gl.mrWidgetData.false_positive_doc_url = '#{help_page_path('user/application_security/vulnerabilities/_index.md')}';
|
||||
window.gl.mrWidgetData.can_view_false_positive = '#{@merge_request.project.licensed_feature_available?(:sast_fp_reduction).to_s}';
|
||||
window.gl.mrWidgetData.user_preferences_gitpod_path = '#{profile_preferences_path(anchor: 'user_gitpod_enabled')}';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- webhooks_link = tag_pair(link_to('', help_page_path(hook.help_path), target: '_blank', rel: 'noopener noreferrer'), :webhooks_link_start, :webhooks_link_end)
|
||||
- webhooks_link = tag_pair(link_to('', hook.help_path, target: '_blank', rel: 'noopener noreferrer'), :webhooks_link_start, :webhooks_link_end)
|
||||
|
||||
- if @project
|
||||
- integrations_link = tag_pair(link_to('', scoped_integrations_path(project: @project)), :integrations_link_start, :integrations_link_end)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
table_name: work_item_current_statuses
|
||||
classes:
|
||||
- WorkItems::Statuses::CurrentStatus
|
||||
feature_categories:
|
||||
- team_planning
|
||||
description: Persists link between work item and a system defined or custom status
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181962
|
||||
milestone: '17.10'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
sharding_key:
|
||||
namespace_id: namespaces
|
||||
table_size: unknown
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TruncateSecurityPipelineExecutionProjectSchedules < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
truncate_tables!('security_pipeline_execution_project_schedules')
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddCronAndTimeWindowSecondsToSecurityPipelineExecutionProjectSchedules < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :security_pipeline_execution_project_schedules
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
# rubocop:disable Rails/NotNullColumn -- table was emptied by previous migration
|
||||
add_column TABLE_NAME, :time_window_seconds, :integer, null: false, if_not_exists: true
|
||||
add_column TABLE_NAME, :cron, :text, null: false, if_not_exists: true
|
||||
add_column TABLE_NAME, :cron_timezone, :text, null: false, if_not_exists: true
|
||||
# rubocop:enable Rails/NotNullColumn
|
||||
end
|
||||
|
||||
add_text_limit TABLE_NAME, :cron, 128
|
||||
add_text_limit TABLE_NAME, :cron_timezone, 255
|
||||
|
||||
constraint_name = check_constraint_name(TABLE_NAME, :time_window_seconds, "positive")
|
||||
add_check_constraint TABLE_NAME, "time_window_seconds > 0", constraint_name
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_column TABLE_NAME, :time_window_seconds, if_exists: true
|
||||
remove_column TABLE_NAME, :cron, if_exists: true
|
||||
remove_column TABLE_NAME, :cron_timezone, if_exists: true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveUniqueIndexOnPipelineExecutionSchedulesProjectsAndPolicies < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :security_pipeline_execution_project_schedules
|
||||
INDEX_NAME = "uniq_idx_pipeline_execution_schedules_projects_and_policies"
|
||||
|
||||
def up
|
||||
remove_index(TABLE_NAME, name: INDEX_NAME) # rubocop:disable Migration/RemoveIndex -- table was truncated
|
||||
end
|
||||
|
||||
def down
|
||||
# rubocop:disable Migration/AddIndex -- table was truncated
|
||||
add_index(TABLE_NAME, %w[project_id security_policy_id], unique: true, name: INDEX_NAME)
|
||||
# rubocop:enable Migration/AddIndex
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIndexOnPipelineExecutionSchedulesProjects < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.9'
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :security_pipeline_execution_project_schedules
|
||||
INDEX_NAME = 'idx_pipeline_execution_schedules_on_project_id'
|
||||
|
||||
def up
|
||||
# rubocop:disable Migration/AddIndex -- table was truncated
|
||||
add_index(TABLE_NAME, :project_id, name: INDEX_NAME)
|
||||
# rubocop:enable Migration/AddIndex
|
||||
end
|
||||
|
||||
def down
|
||||
remove_index(TABLE_NAME, name: INDEX_NAME) # rubocop:disable Migration/RemoveIndex -- table was truncated
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateWorkItemCurrentStatuses < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def change
|
||||
# factory is in `ee/spec/factories/work_items/statuses/current_status.rb`
|
||||
create_table :work_item_current_statuses do |t| # rubocop:disable Migration/EnsureFactoryForTable -- reason above
|
||||
t.references :namespace, null: false, foreign_key: { on_delete: :cascade }
|
||||
t.references :work_item, null: false, foreign_key: { to_table: :issues, on_delete: :cascade },
|
||||
index: { unique: true }
|
||||
t.bigint :system_defined_status_id, null: true
|
||||
# Should be references if model already existed, but we'll add this in a follow up MR.
|
||||
# We can already add it here so column order is correct.
|
||||
t.bigint :custom_status_id, null: true
|
||||
t.datetime_with_timezone :updated_at, null: false
|
||||
|
||||
t.index [:work_item_id, :system_defined_status_id],
|
||||
name: 'idx_wi_current_statuses_on_wi_id_system_def_status_id_unique', unique: true
|
||||
t.index [:work_item_id, :custom_status_id],
|
||||
name: 'idx_wi_current_statuses_on_wi_id_custom_status_id_unique', unique: true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddCheckConstraintToWorkItemCurrentStatuses < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.10'
|
||||
|
||||
def up
|
||||
# Ensure that either system_defined_status_id or custom_status_id is not null
|
||||
# but allow both ids to be set.
|
||||
add_multi_column_not_null_constraint(
|
||||
:work_item_current_statuses, :system_defined_status_id, :custom_status_id, limit: 0, operator: '>'
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_multi_column_not_null_constraint(:work_item_current_statuses, :system_defined_status_id, :custom_status_id)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddWorkItemCurrentStatusesNamespaceIdTrigger < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def up
|
||||
install_sharding_key_assignment_trigger(
|
||||
table: :work_item_current_statuses,
|
||||
sharding_key: :namespace_id,
|
||||
parent_table: :issues,
|
||||
parent_sharding_key: :namespace_id,
|
||||
foreign_key: :work_item_id
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_sharding_key_assignment_trigger(
|
||||
table: :work_item_current_statuses,
|
||||
sharding_key: :namespace_id,
|
||||
parent_table: :issues,
|
||||
parent_sharding_key: :namespace_id,
|
||||
foreign_key: :work_item_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
63d3440161336ed8d556565a0c7add785ba47324f3dae6c21d89d6c34277c91d
|
||||
|
|
@ -0,0 +1 @@
|
|||
73a8cecec58922c7b289c71e83d4217c7084d000e59c36ae98fb5cab8bda38c1
|
||||
|
|
@ -0,0 +1 @@
|
|||
b9d0f1433e900711b3811ff97e17f0e33b6f688f0ec6bdfec5adfdb8f32b83a1
|
||||
|
|
@ -0,0 +1 @@
|
|||
5c65a79dae8281c14503682c9e2147fa624893a6f22d6f64e12d4d8c5d2ca2bf
|
||||
|
|
@ -0,0 +1 @@
|
|||
2ec2eba7b8a6680e26cf9e925bb62fdc46948b3a29020dc8402d5d85897ebe6f
|
||||
|
|
@ -0,0 +1 @@
|
|||
a0f415b0088543960d7e50b58ea8f4d50c1b1102f75a6a5bd35e9f730c03bb33
|
||||
|
|
@ -0,0 +1 @@
|
|||
48660f996820dd8220fa23dbd68ebea9e45aa960a68e8ce2607d3c9fb6fd9e80
|
||||
|
|
@ -2022,6 +2022,22 @@ RETURN NEW;
|
|||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_4fc14aa830b1() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF NEW."namespace_id" IS NULL THEN
|
||||
SELECT "namespace_id"
|
||||
INTO NEW."namespace_id"
|
||||
FROM "issues"
|
||||
WHERE "issues"."id" = NEW."work_item_id";
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_54707c384ad7() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
|
|
@ -21298,7 +21314,13 @@ CREATE TABLE security_pipeline_execution_project_schedules (
|
|||
updated_at timestamp with time zone NOT NULL,
|
||||
next_run_at timestamp with time zone NOT NULL,
|
||||
security_policy_id bigint NOT NULL,
|
||||
project_id bigint NOT NULL
|
||||
project_id bigint NOT NULL,
|
||||
time_window_seconds integer NOT NULL,
|
||||
cron text NOT NULL,
|
||||
cron_timezone text NOT NULL,
|
||||
CONSTRAINT check_b93315bfbb CHECK ((char_length(cron_timezone) <= 255)),
|
||||
CONSTRAINT check_bbbe4b1b8d CHECK ((char_length(cron) <= 128)),
|
||||
CONSTRAINT check_c440017377 CHECK ((time_window_seconds > 0))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE security_pipeline_execution_project_schedules_id_seq
|
||||
|
|
@ -23962,6 +23984,25 @@ CREATE TABLE work_item_colors (
|
|||
CONSTRAINT check_485e19ad7b CHECK ((char_length(color) <= 7))
|
||||
);
|
||||
|
||||
CREATE TABLE work_item_current_statuses (
|
||||
id bigint NOT NULL,
|
||||
namespace_id bigint NOT NULL,
|
||||
work_item_id bigint NOT NULL,
|
||||
system_defined_status_id bigint,
|
||||
custom_status_id bigint,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
CONSTRAINT check_0734284d2c CHECK ((num_nonnulls(custom_status_id, system_defined_status_id) > 0))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE work_item_current_statuses_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE work_item_current_statuses_id_seq OWNED BY work_item_current_statuses.id;
|
||||
|
||||
CREATE TABLE work_item_dates_sources (
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
|
|
@ -26284,6 +26325,8 @@ ALTER TABLE ONLY wiki_page_slugs ALTER COLUMN id SET DEFAULT nextval('wiki_page_
|
|||
|
||||
ALTER TABLE ONLY wiki_repository_states ALTER COLUMN id SET DEFAULT nextval('wiki_repository_states_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY work_item_current_statuses ALTER COLUMN id SET DEFAULT nextval('work_item_current_statuses_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY work_item_hierarchy_restrictions ALTER COLUMN id SET DEFAULT nextval('work_item_hierarchy_restrictions_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY work_item_number_field_values ALTER COLUMN id SET DEFAULT nextval('work_item_number_field_values_id_seq'::regclass);
|
||||
|
|
@ -29341,6 +29384,9 @@ ALTER TABLE ONLY wiki_repository_states
|
|||
ALTER TABLE ONLY work_item_colors
|
||||
ADD CONSTRAINT work_item_colors_pkey PRIMARY KEY (issue_id);
|
||||
|
||||
ALTER TABLE ONLY work_item_current_statuses
|
||||
ADD CONSTRAINT work_item_current_statuses_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY work_item_dates_sources
|
||||
ADD CONSTRAINT work_item_dates_sources_pkey PRIMARY KEY (issue_id);
|
||||
|
||||
|
|
@ -31202,6 +31248,8 @@ CREATE INDEX idx_pat_last_used_ips_on_pat_id ON personal_access_token_last_used_
|
|||
|
||||
CREATE INDEX idx_personal_access_tokens_on_previous_personal_access_token_id ON personal_access_tokens USING btree (previous_personal_access_token_id);
|
||||
|
||||
CREATE INDEX idx_pipeline_execution_schedules_on_project_id ON security_pipeline_execution_project_schedules USING btree (project_id);
|
||||
|
||||
CREATE INDEX idx_pipeline_execution_schedules_security_policy_id_and_id ON security_pipeline_execution_project_schedules USING btree (security_policy_id, id);
|
||||
|
||||
CREATE INDEX idx_pkgs_conan_file_metadata_on_pkg_file_id_when_recipe_file ON packages_conan_file_metadata USING btree (package_file_id) WHERE (conan_file_type = 1);
|
||||
|
|
@ -31354,6 +31402,10 @@ CREATE INDEX idx_vulnerability_reads_project_id_scanner_id_vulnerability_id ON v
|
|||
|
||||
CREATE INDEX idx_vulnerability_statistics_on_traversal_ids_and_letter_grade ON vulnerability_statistics USING btree (traversal_ids, letter_grade) WHERE (archived = false);
|
||||
|
||||
CREATE UNIQUE INDEX idx_wi_current_statuses_on_wi_id_custom_status_id_unique ON work_item_current_statuses USING btree (work_item_id, custom_status_id);
|
||||
|
||||
CREATE UNIQUE INDEX idx_wi_current_statuses_on_wi_id_system_def_status_id_unique ON work_item_current_statuses USING btree (work_item_id, system_defined_status_id);
|
||||
|
||||
CREATE UNIQUE INDEX idx_wi_number_values_on_work_item_id_custom_field_id ON work_item_number_field_values USING btree (work_item_id, custom_field_id);
|
||||
|
||||
CREATE INDEX idx_wi_select_field_values_on_custom_field_select_option_id ON work_item_select_field_values USING btree (custom_field_select_option_id);
|
||||
|
|
@ -35748,6 +35800,10 @@ CREATE INDEX index_wiki_repository_states_on_verification_state ON wiki_reposito
|
|||
|
||||
CREATE INDEX index_wiki_repository_states_pending_verification ON wiki_repository_states USING btree (verified_at NULLS FIRST) WHERE (verification_state = 0);
|
||||
|
||||
CREATE INDEX index_work_item_current_statuses_on_namespace_id ON work_item_current_statuses USING btree (namespace_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_work_item_current_statuses_on_work_item_id ON work_item_current_statuses USING btree (work_item_id);
|
||||
|
||||
CREATE INDEX index_work_item_hierarchy_restrictions_on_child_type_id ON work_item_hierarchy_restrictions USING btree (child_type_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_work_item_hierarchy_restrictions_on_parent_and_child ON work_item_hierarchy_restrictions USING btree (parent_type_id, child_type_id);
|
||||
|
|
@ -36122,8 +36178,6 @@ CREATE UNIQUE INDEX uniq_idx_on_packages_conan_package_revisions_revision ON pac
|
|||
|
||||
CREATE UNIQUE INDEX uniq_idx_packages_packages_on_project_id_name_version_ml_model ON packages_packages USING btree (project_id, name, version) WHERE ((package_type = 14) AND (status <> 4));
|
||||
|
||||
CREATE UNIQUE INDEX uniq_idx_pipeline_execution_schedules_projects_and_policies ON security_pipeline_execution_project_schedules USING btree (project_id, security_policy_id);
|
||||
|
||||
CREATE UNIQUE INDEX uniq_idx_project_compliance_framework_on_project_framework ON project_compliance_framework_settings USING btree (project_id, framework_id);
|
||||
|
||||
CREATE UNIQUE INDEX uniq_idx_security_policy_requirements_on_requirement_and_policy ON security_policy_requirements USING btree (compliance_framework_security_policy_id, compliance_requirement_id);
|
||||
|
|
@ -38392,6 +38446,8 @@ CREATE TRIGGER trigger_4cc5c3ac4d7f BEFORE INSERT OR UPDATE ON bulk_import_expor
|
|||
|
||||
CREATE TRIGGER trigger_4dc8ec48e038 BEFORE INSERT OR UPDATE ON requirements_management_test_reports FOR EACH ROW EXECUTE FUNCTION trigger_4dc8ec48e038();
|
||||
|
||||
CREATE TRIGGER trigger_4fc14aa830b1 BEFORE INSERT OR UPDATE ON work_item_current_statuses FOR EACH ROW EXECUTE FUNCTION trigger_4fc14aa830b1();
|
||||
|
||||
CREATE TRIGGER trigger_54707c384ad7 BEFORE INSERT OR UPDATE ON security_orchestration_policy_rule_schedules FOR EACH ROW EXECUTE FUNCTION trigger_54707c384ad7();
|
||||
|
||||
CREATE TRIGGER trigger_56d49f4ed623 BEFORE INSERT OR UPDATE ON workspace_variables FOR EACH ROW EXECUTE FUNCTION trigger_56d49f4ed623();
|
||||
|
|
@ -42348,6 +42404,9 @@ ALTER TABLE ONLY design_management_repository_states
|
|||
ALTER TABLE ONLY web_hooks
|
||||
ADD CONSTRAINT fk_rails_d35697648e FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY work_item_current_statuses
|
||||
ADD CONSTRAINT fk_rails_d37e56a437 FOREIGN KEY (work_item_id) REFERENCES issues(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY group_group_links
|
||||
ADD CONSTRAINT fk_rails_d3a0488427 FOREIGN KEY (shared_group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
@ -42549,6 +42608,9 @@ ALTER TABLE ONLY iterations_cadences
|
|||
ALTER TABLE ONLY dast_profiles
|
||||
ADD CONSTRAINT fk_rails_ed1e66fbbf FOREIGN KEY (dast_site_profile_id) REFERENCES dast_site_profiles(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY work_item_current_statuses
|
||||
ADD CONSTRAINT fk_rails_ed36c2df68 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY project_security_settings
|
||||
ADD CONSTRAINT fk_rails_ed4abe1338 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ You can use the following GitLab Duo Chat features with GitLab Duo Self-Hosted:
|
|||
- [Ask about GitLab](../../user/gitlab_duo_chat/examples.md#ask-about-gitlab)
|
||||
- [Ask about a specific issue](../../user/gitlab_duo_chat/examples.md#ask-about-a-specific-issue)
|
||||
- [Ask about a specific epic](../../user/gitlab_duo_chat/examples.md#ask-about-a-specific-epic)
|
||||
- [Ask about a specific merge request](../../user/gitlab_duo_chat/examples.md#ask-about-a-specific-merge-request)
|
||||
- [Ask about a specific commit](../../user/gitlab_duo_chat/examples.md#ask-about-a-specific-commit)
|
||||
- [Ask about a specific pipeline job](../../user/gitlab_duo_chat/examples.md#ask-about-a-specific-pipeline-job)
|
||||
- [Explain selected code](../../user/gitlab_duo_chat/examples.md#explain-selected-code)
|
||||
- [Ask about or generate code](../../user/gitlab_duo_chat/examples.md#ask-about-or-generate-code)
|
||||
- [Ask follow up questions](../../user/gitlab_duo_chat/examples.md#ask-follow-up-questions)
|
||||
|
|
@ -64,7 +67,7 @@ You can use the following GitLab Duo Chat features with GitLab Duo Self-Hosted:
|
|||
- [Fix code in the IDE](../../user/gitlab_duo_chat/examples.md#fix-code-in-the-ide)
|
||||
- [Write tests in the IDE](../../user/gitlab_duo_chat/examples.md#write-tests-in-the-ide)
|
||||
- [Ask about CI/CD](../../user/gitlab_duo_chat/examples.md#ask-about-cicd)
|
||||
- [Use universal and IDE slash commands](../../user/gitlab_duo_chat/examples.md#gitlab-duo-chat-slash-commands)
|
||||
- [Use IDE slash commands](../../user/gitlab_duo_chat/examples.md#ide)
|
||||
|
||||
### Prerequisites
|
||||
|
||||
|
|
|
|||
|
|
@ -8703,6 +8703,7 @@ Input type: `PipelineCreateInput`
|
|||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationpipelinecreateasync"></a>`async` {{< icon name="warning-solid" >}} | [`Boolean`](#boolean) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.8. |
|
||||
| <a id="mutationpipelinecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationpipelinecreateinputs"></a>`inputs` {{< icon name="warning-solid" >}} | [`[CiInputsInputType!]`](#ciinputsinputtype) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.10. |
|
||||
| <a id="mutationpipelinecreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project that is triggering the pipeline. |
|
||||
| <a id="mutationpipelinecreateref"></a>`ref` | [`String!`](#string) | Ref on which to run the pipeline. |
|
||||
| <a id="mutationpipelinecreatevariables"></a>`variables` | [`[CiVariableInput!]`](#civariableinput) | Variables for the pipeline. |
|
||||
|
|
@ -39523,6 +39524,7 @@ Check permissions for the current user on a work item.
|
|||
| <a id="workitempermissionsadminparentlink"></a>`adminParentLink` | [`Boolean!`](#boolean) | If `true`, the user can perform `admin_parent_link` on this resource. |
|
||||
| <a id="workitempermissionsadminworkitem"></a>`adminWorkItem` | [`Boolean!`](#boolean) | If `true`, the user can perform `admin_work_item` on this resource. |
|
||||
| <a id="workitempermissionsadminworkitemlink"></a>`adminWorkItemLink` | [`Boolean!`](#boolean) | If `true`, the user can perform `admin_work_item_link` on this resource. |
|
||||
| <a id="workitempermissionsblockedworkitems"></a>`blockedWorkItems` | [`Boolean`](#boolean) | If `true`, the user can perform `blocked_work_items` on the work item. |
|
||||
| <a id="workitempermissionscloneworkitem"></a>`cloneWorkItem` | [`Boolean!`](#boolean) | If `true`, the user can perform `clone_work_item` on this resource. |
|
||||
| <a id="workitempermissionscreatenote"></a>`createNote` | [`Boolean!`](#boolean) | If `true`, the user can perform `create_note` on this resource. |
|
||||
| <a id="workitempermissionsdeleteworkitem"></a>`deleteWorkItem` | [`Boolean!`](#boolean) | If `true`, the user can perform `delete_work_item` on this resource. |
|
||||
|
|
@ -44298,6 +44300,10 @@ A `CiCatalogResourcesVersionID` is a global ID. It is encoded as a string.
|
|||
|
||||
An example `CiCatalogResourcesVersionID` is: `"gid://gitlab/Ci::Catalog::Resources::Version/1"`.
|
||||
|
||||
### `CiInputsValueInputType`
|
||||
|
||||
Value for a CI input. Can be a string, array, number, or boolean.
|
||||
|
||||
### `CiJobArtifactID`
|
||||
|
||||
A `CiJobArtifactID` is a global ID. It is encoded as a string.
|
||||
|
|
@ -46630,6 +46636,17 @@ Field that are available while modifying the custom mapping attributes for an HT
|
|||
| <a id="branchprotectioninputmergeaccesslevels"></a>`mergeAccessLevels` | [`[MergeAccessLevelInput!]`](#mergeaccesslevelinput) | Details about who can merge into the branch rule target. |
|
||||
| <a id="branchprotectioninputpushaccesslevels"></a>`pushAccessLevels` | [`[PushAccessLevelInput!]`](#pushaccesslevelinput) | Details about who can push to the branch rule target. |
|
||||
|
||||
### `CiInputsInputType`
|
||||
|
||||
Attributes for defining an input.
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="ciinputsinputtypekey"></a>`key` | [`String!`](#string) | Name of the input. |
|
||||
| <a id="ciinputsinputtypevalue"></a>`value` | [`CiInputsValueInputType!`](#ciinputsvalueinputtype) | Value of the input. |
|
||||
|
||||
### `CiVariableInput`
|
||||
|
||||
Attributes for defining a CI/CD variable.
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ module ActiveRecord
|
|||
def belongs_to_fixed_items(association_name, fixed_items_class:, foreign_key: nil)
|
||||
foreign_key ||= "#{association_name}_id"
|
||||
|
||||
raise "Missing attribute #{foreign_key}" unless attribute_names.include?(foreign_key)
|
||||
|
||||
# Getter method
|
||||
define_method(association_name) do
|
||||
raise "Missing attribute #{foreign_key}" unless attribute_names.include?(foreign_key)
|
||||
|
||||
current_id = read_attribute(foreign_key)
|
||||
return if current_id.nil?
|
||||
|
||||
|
|
@ -53,12 +53,16 @@ module ActiveRecord
|
|||
|
||||
# Setter method
|
||||
define_method(:"#{association_name}=") do |static_object|
|
||||
raise "Missing attribute #{foreign_key}" unless attribute_names.include?(foreign_key)
|
||||
|
||||
@cached_static_associations&.delete(association_name)
|
||||
write_attribute(foreign_key, static_object&.id)
|
||||
end
|
||||
|
||||
# Query method
|
||||
define_method(:"#{association_name}?") do
|
||||
raise "Missing attribute #{foreign_key}" unless attribute_names.include?(foreign_key)
|
||||
|
||||
attribute_present?(foreign_key)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -56,19 +56,35 @@ RSpec.describe ActiveRecord::FixedItemsModel::HasOne, feature_category: :shared
|
|||
it { is_expected.to respond_to(:static_item?) }
|
||||
|
||||
context 'when foreign key attribute does not exist' do
|
||||
it 'raises runtime error' do
|
||||
before do
|
||||
stub_const('TestRecord', Class.new do
|
||||
include ActiveModel::Attributes
|
||||
include ActiveRecord::FixedItemsModel::HasOne
|
||||
|
||||
attribute :static_item_id, :integer
|
||||
|
||||
# No need for mock methods because they're not called
|
||||
# because of the guard raise
|
||||
|
||||
belongs_to_fixed_items :doesnt_exist, fixed_items_class: TestStaticModel
|
||||
end)
|
||||
end
|
||||
|
||||
it 'getter raises runtime error' do
|
||||
expect do
|
||||
stub_const('TestRecord', Class.new do
|
||||
include ActiveModel::Attributes
|
||||
include ActiveRecord::FixedItemsModel::HasOne
|
||||
record.doesnt_exist
|
||||
end.to raise_error(RuntimeError, "Missing attribute doesnt_exist_id")
|
||||
end
|
||||
|
||||
attribute :static_item_id, :integer
|
||||
it 'setter raises runtime error' do
|
||||
expect do
|
||||
record.doesnt_exist = nil
|
||||
end.to raise_error(RuntimeError, "Missing attribute doesnt_exist_id")
|
||||
end
|
||||
|
||||
# No need for mock methods because they're not called
|
||||
# because of the guard raise
|
||||
|
||||
belongs_to_fixed_items :doesnt_exist, fixed_items_class: TestStaticModel
|
||||
end)
|
||||
it 'query method raises runtime error' do
|
||||
expect do
|
||||
record.doesnt_exist?
|
||||
end.to raise_error(RuntimeError, "Missing attribute doesnt_exist_id")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,118 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../lib/gitlab/utils/markdown'
|
||||
|
||||
module HamlLint
|
||||
class Linter
|
||||
# This class is responsible for detection of help_page_path helpers
|
||||
# with incorrect links or anchors
|
||||
class DocumentationLinks < Linter
|
||||
include ::HamlLint::LinterRegistry
|
||||
include ::Gitlab::Utils::Markdown
|
||||
extend ::RuboCop::AST::NodePattern::Macros
|
||||
|
||||
DOCS_DIRECTORY = File.join(File.expand_path('../..', __dir__), 'doc')
|
||||
|
||||
def_node_matcher :help_link, <<~PATTERN
|
||||
(send _ {:help_page_url :help_page_path} $...)
|
||||
PATTERN
|
||||
|
||||
MARKDOWN_HEADER = %r{\A\#{1,6}\s+(?<header>.+)\Z}
|
||||
|
||||
def visit_script(node)
|
||||
check(node)
|
||||
end
|
||||
|
||||
def visit_silent_script(node)
|
||||
check(node)
|
||||
end
|
||||
|
||||
def visit_tag(node)
|
||||
check(node)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check(node)
|
||||
ast_tree = fetch_ast_tree(node)
|
||||
|
||||
return unless ast_tree
|
||||
|
||||
ast_tree.descendants.each do |child_node|
|
||||
match = extract_link_and_anchor(child_node)
|
||||
validate_node(node, match)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_node(node, match)
|
||||
return if match.empty?
|
||||
|
||||
link = match[:link]
|
||||
|
||||
path_to_file = detect_path_to_file(link)
|
||||
|
||||
unless File.file?(path_to_file)
|
||||
record_lint(node, "help_page_path points to the unknown location: #{path_to_file}")
|
||||
return
|
||||
end
|
||||
|
||||
unless correct_anchor?(path_to_file, match[:anchor])
|
||||
record_lint(node, "anchor (#{match[:anchor]}) is missing in: #{path_to_file}")
|
||||
end
|
||||
|
||||
record_lint(node, "add .md extension to the link: #{link}") unless link.end_with?('.md')
|
||||
end
|
||||
|
||||
def extract_link_and_anchor(ast_tree)
|
||||
link_match, attributes_match = help_link(ast_tree)
|
||||
|
||||
{ link: fetch_link(link_match), anchor: fetch_anchor(attributes_match) }.compact
|
||||
end
|
||||
|
||||
def fetch_ast_tree(node)
|
||||
# Sometimes links are provided via data attributes in html tag
|
||||
return node.parsed_attributes.syntax_tree if node.type == :tag
|
||||
|
||||
parse_script(node).syntax_tree
|
||||
end
|
||||
|
||||
def parse_script(node)
|
||||
# It's a workaround for cases for scripts ending with "do"
|
||||
# For some reason they don't parse correctly
|
||||
code = node.script.delete_suffix(' do')
|
||||
|
||||
HamlLint::ParsedRuby.new(HamlLint::RubyParser.new.parse(code))
|
||||
end
|
||||
|
||||
def detect_path_to_file(link)
|
||||
path = File.join(DOCS_DIRECTORY, link)
|
||||
path += '.md' unless path.end_with?('.md')
|
||||
path
|
||||
end
|
||||
|
||||
def fetch_link(link_match)
|
||||
return unless link_match && link_match.str_type?
|
||||
|
||||
link_match.value
|
||||
end
|
||||
|
||||
def fetch_anchor(attributes_match)
|
||||
return unless attributes_match
|
||||
|
||||
attributes_match.each_pair do |pkey, pvalue|
|
||||
break pvalue.value if pkey.value == :anchor
|
||||
end
|
||||
end
|
||||
|
||||
def correct_anchor?(path_to_file, anchor)
|
||||
return true unless anchor
|
||||
|
||||
File.open(path_to_file).any? do |line|
|
||||
result = line.match(MARKDOWN_HEADER)
|
||||
|
||||
string_to_anchor(result[:header]) == anchor if result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -155,7 +155,7 @@ gitlab-enrich-cdx-results:
|
|||
GLAS_STATIC_REACHABILITY_MATCHER_VERSION: "v1.0.1"
|
||||
GLAS_REPORT: $GITLAB_ADVANCED_SAST_SCA_FILENAME
|
||||
SCA_TO_SARIF_PROJECT_ID: 60962090
|
||||
DEPENDENCY_SCANNING_PATTERN: "**/gl-sbom-*.cdx.json"
|
||||
DEPENDENCY_SCANNING_PATTERN: "**/gl-sbom-*-*.cdx.json"
|
||||
image:
|
||||
name: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
|
||||
entrypoint: [""]
|
||||
|
|
|
|||
|
|
@ -12463,6 +12463,9 @@ msgstr ""
|
|||
msgid "CiVariables|Cancel"
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|Default role to use pipeline variables"
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|Delete variable"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12529,6 +12532,9 @@ msgstr ""
|
|||
msgid "CiVariables|No matching values"
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|Pipeline variable access role successfully updated."
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|Pipeline variable minimum override role successfully updated."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12553,6 +12559,9 @@ msgstr ""
|
|||
msgid "CiVariables|Run job again"
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|SSelect the default minimum role to use in new projects, to run a new pipeline with pipeline variables."
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|Scope"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12589,6 +12598,12 @@ msgstr ""
|
|||
msgid "CiVariables|The value must have %{charsAmount} characters."
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|There was a problem fetching the pipeline variables default role."
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|There was a problem updating the pipeline variables default role setting."
|
||||
msgstr ""
|
||||
|
||||
msgid "CiVariables|There was an error fetching the inherited CI variables."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -50816,9 +50831,6 @@ msgstr ""
|
|||
msgid "ScanResultPolicy|All licenses have been selected"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Allow except on"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Allow the merge request to proceed, even if not all criteria are met"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -50864,9 +50876,6 @@ msgstr ""
|
|||
msgid "ScanResultPolicy|Denied license"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Deny except on"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Don't show me this again"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -50885,6 +50894,9 @@ msgstr ""
|
|||
msgid "ScanResultPolicy|Except"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Exceptions that require approval"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Fail closed"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -51050,6 +51062,9 @@ msgstr ""
|
|||
msgid "ScanResultPolicy|Severity is:"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Specify the packages where this license requires approval before use"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Status is:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -51059,9 +51074,6 @@ msgstr ""
|
|||
msgid "ScanResultPolicy|Unknown"
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|Use purl format for package paths: %{schemaStart}scheme:type/namespace/name@version?qualifiers#subpath%{schemaEnd}. For multiple packages, separate paths with comma \",\"."
|
||||
msgstr ""
|
||||
|
||||
msgid "ScanResultPolicy|When %{scanType} %{scanners} runs against the %{branches} %{branchExceptions} and find(s) %{vulnerabilitiesNumber} %{boldDescription} of the following criteria:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -52173,9 +52185,6 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|All types"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Allow except on these packages"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Allowed licenses"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -52314,9 +52323,6 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|Denied licenses"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Deny except on these packages"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Denylist details"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -52928,6 +52934,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|Use default mode for scoping"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Use the format %{schemaStart}path-to-package@package-version%{schemaEnd}. For multiple packages, separate paths with commas. For example: path/file1.yaml@1.1.1, path/file2.yaml@2.2.2"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Users can skip pipelines"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -202,12 +202,6 @@ tests = [
|
|||
expected: ['spec/lib/release_highlights/validator_spec.rb']
|
||||
},
|
||||
|
||||
{
|
||||
explanation: 'The documentation index page is used in this haml_lint spec',
|
||||
changed_file: 'doc/_index.md',
|
||||
expected: ['spec/haml_lint/linter/documentation_links_spec.rb']
|
||||
},
|
||||
|
||||
{
|
||||
explanation: 'Spec for FOSS model',
|
||||
changed_file: 'app/models/uploads/base.rb',
|
||||
|
|
|
|||
|
|
@ -256,7 +256,11 @@ RSpec.describe 'Database schema',
|
|||
system_access_group_microsoft_graph_access_tokens: %w[temp_source_id], # temporary column that is not a foreign key
|
||||
system_access_group_microsoft_applications: %w[temp_source_id], # temporary column that is not a foreign key
|
||||
subscription_user_add_on_assignment_versions: %w[item_id user_id purchase_id], # Managed by paper_trail gem, no need for FK on the historical data
|
||||
virtual_registries_packages_maven_cache_entries: %w[group_id] # We can't use a foreign key due to object storage references
|
||||
virtual_registries_packages_maven_cache_entries: %w[group_id], # We can't use a foreign key due to object storage references
|
||||
# system_defined_status_id reference to fixed items model which is stored in code
|
||||
# custom_status_id to be implemented association, column exists for better column ordering
|
||||
# TODO: Remove custom_status_id https://gitlab.com/gitlab-org/gitlab/-/work_items/520312
|
||||
work_item_current_statuses: %w[system_defined_status_id custom_status_id]
|
||||
}.with_indifferent_access.freeze
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { GlButton, GlFormGroup, GlFormRadio, GlFormRadioGroup } from '@gitlab/ui';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { createAlert } from '~/alert';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import PipelineVariablesDefaultRole, {
|
||||
DEFAULT_ROLE_MAINTAINER,
|
||||
DEFAULT_ROLE_NO_ONE,
|
||||
} from '~/group_settings/pipeline_variables_default_role/pipeline_variables_default_role.vue';
|
||||
import updatePipelineVariablesDefaultRoleSetting from '~/group_settings/pipeline_variables_default_role/graphql/mutations/update_pipeline_variables_default_role_group_setting.mutation.graphql';
|
||||
import getPipelineVariablesDefaultRoleSetting from '~/group_settings/pipeline_variables_default_role/graphql/queries/get_pipeline_variables_default_role_group_setting.query.graphql';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
jest.mock('~/alert');
|
||||
const $toast = {
|
||||
show: jest.fn(),
|
||||
};
|
||||
|
||||
const TEST_FULL_PATH = 'group/project';
|
||||
|
||||
describe('PipelineVariablesDefaultRole', () => {
|
||||
let wrapper;
|
||||
|
||||
const defaultQueryResponse = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
group: {
|
||||
id: '1',
|
||||
ciCdSettings: {
|
||||
pipelineVariablesDefaultRole: 'developer',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const defaultMutationResponse = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
namespaceSettingsUpdate: {
|
||||
errors: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const createComponent = async ({
|
||||
queryHandler = defaultQueryResponse,
|
||||
mutationHandler = defaultMutationResponse,
|
||||
} = {}) => {
|
||||
const apolloProvider = createMockApollo([
|
||||
[getPipelineVariablesDefaultRoleSetting, queryHandler],
|
||||
[updatePipelineVariablesDefaultRoleSetting, mutationHandler],
|
||||
]);
|
||||
|
||||
wrapper = shallowMount(PipelineVariablesDefaultRole, {
|
||||
provide: {
|
||||
fullPath: TEST_FULL_PATH,
|
||||
},
|
||||
mocks: {
|
||||
$toast,
|
||||
},
|
||||
apolloProvider,
|
||||
});
|
||||
|
||||
await waitForPromises();
|
||||
};
|
||||
|
||||
const findFormGroup = () => wrapper.findComponent(GlFormGroup);
|
||||
const findRadioGroup = () => wrapper.findComponent(GlFormRadioGroup);
|
||||
const findRadioButtons = () => wrapper.findAllComponents(GlFormRadio);
|
||||
const findSaveButton = () => wrapper.findComponent(GlButton);
|
||||
|
||||
const selectRadioOption = async (value, index) => {
|
||||
findRadioGroup().vm.$emit('input', value);
|
||||
findRadioButtons().at(index).vm.$emit('change');
|
||||
await waitForPromises();
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('on render', () => {
|
||||
it('renders the form group with correct label', async () => {
|
||||
await createComponent();
|
||||
|
||||
expect(findFormGroup().exists()).toBe(true);
|
||||
expect(findFormGroup().attributes('label')).toBe('Default role to use pipeline variables');
|
||||
});
|
||||
|
||||
it('renders all role options as radio buttons', async () => {
|
||||
await createComponent();
|
||||
|
||||
expect(findRadioButtons()).toHaveLength(PipelineVariablesDefaultRole.ROLE_OPTIONS.length);
|
||||
|
||||
PipelineVariablesDefaultRole.ROLE_OPTIONS.forEach((option, index) => {
|
||||
expect(findRadioButtons().at(index).attributes('value')).toBe(option.value);
|
||||
expect(findRadioButtons().at(index).text()).toContain(option.text);
|
||||
});
|
||||
});
|
||||
|
||||
it('has the correct help path', () => {
|
||||
expect(PipelineVariablesDefaultRole.helpPath).toBe(
|
||||
helpPagePath('ci/variables/_index', {
|
||||
anchor: 'cicd-variable-precedence',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GraphQL operations', () => {
|
||||
describe('query', () => {
|
||||
it('fetches initial role setting successfully', async () => {
|
||||
await createComponent();
|
||||
|
||||
expect(defaultQueryResponse).toHaveBeenCalledWith({ fullPath: TEST_FULL_PATH });
|
||||
expect(findRadioButtons().at(3).attributes('value')).toBe('DEVELOPER');
|
||||
expect(wrapper.vm.pipelineVariablesDefaultRole).toBe('DEVELOPER');
|
||||
});
|
||||
|
||||
it('sets default role to NO_ONE_ALLOWED when query returns null', async () => {
|
||||
const queryHandler = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
group: null,
|
||||
},
|
||||
});
|
||||
|
||||
await createComponent({ queryHandler });
|
||||
|
||||
expect(wrapper.vm.pipelineVariablesDefaultRole).toBe(DEFAULT_ROLE_NO_ONE);
|
||||
});
|
||||
|
||||
it('shows error alert when query fails', async () => {
|
||||
const queryHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
|
||||
|
||||
await createComponent({ queryHandler });
|
||||
|
||||
expect(createAlert).toHaveBeenCalledWith({
|
||||
message: 'There was a problem fetching the pipeline variables default role.',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mutation', () => {
|
||||
it('updates role setting successfully', async () => {
|
||||
await createComponent();
|
||||
await selectRadioOption(DEFAULT_ROLE_MAINTAINER, 2);
|
||||
findSaveButton().vm.$emit('click');
|
||||
|
||||
expect(defaultMutationResponse).toHaveBeenCalledWith({
|
||||
fullPath: TEST_FULL_PATH,
|
||||
pipelineVariablesDefaultRole: DEFAULT_ROLE_MAINTAINER,
|
||||
});
|
||||
});
|
||||
|
||||
it('displays a toast message on success', async () => {
|
||||
await createComponent();
|
||||
await selectRadioOption(DEFAULT_ROLE_MAINTAINER, 2);
|
||||
findSaveButton().vm.$emit('click');
|
||||
await waitForPromises();
|
||||
|
||||
expect($toast.show).toHaveBeenCalledWith(
|
||||
'Pipeline variable access role successfully updated.',
|
||||
);
|
||||
});
|
||||
|
||||
it('shows error alert when mutation returns errors', async () => {
|
||||
const mutationHandler = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
namespaceSettingsUpdate: {
|
||||
errors: [{ message: 'Update failed' }],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await createComponent({ mutationHandler });
|
||||
await selectRadioOption(DEFAULT_ROLE_MAINTAINER, 2);
|
||||
findSaveButton().vm.$emit('click');
|
||||
await waitForPromises();
|
||||
|
||||
expect(createAlert).toHaveBeenCalledWith({
|
||||
message: 'Update failed',
|
||||
});
|
||||
});
|
||||
|
||||
it('shows error alert when mutation fails', async () => {
|
||||
const mutationHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
|
||||
|
||||
await createComponent({ mutationHandler });
|
||||
await selectRadioOption(DEFAULT_ROLE_MAINTAINER, 2);
|
||||
findSaveButton().vm.$emit('click');
|
||||
await waitForPromises();
|
||||
|
||||
expect(createAlert).toHaveBeenCalledWith({
|
||||
message: 'There was a problem updating the pipeline variables default role setting.',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['CiInputsInputType'], feature_category: :pipeline_composition do
|
||||
specify { expect(described_class.graphql_name).to eq('CiInputsInputType') }
|
||||
|
||||
it 'has the correct arguments' do
|
||||
expect(described_class.arguments.keys).to match_array(%w[key value])
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['CiInputsValueInputType'], feature_category: :pipeline_composition do
|
||||
specify { expect(described_class.graphql_name).to eq('CiInputsValueInputType') }
|
||||
|
||||
describe '.coerce_input' do
|
||||
subject(:coerce_input) { described_class.coerce_isolated_input(value) }
|
||||
|
||||
context 'on valid values' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:value, :result) do
|
||||
'foo' | 'foo'
|
||||
1 | 1
|
||||
[1, 2] | [1, 2]
|
||||
true | true
|
||||
false | false
|
||||
nil | nil
|
||||
end
|
||||
|
||||
with_them do
|
||||
it { is_expected.to eq(result) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'on invalid values' do
|
||||
let(:value) { { foo: :bar } }
|
||||
|
||||
it { expect { coerce_input }.to raise_error(GraphQL::CoercionError) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'fast_spec_helper'
|
||||
require 'haml_lint'
|
||||
require 'haml_lint/spec'
|
||||
|
||||
require_relative '../../../haml_lint/linter/documentation_links'
|
||||
|
||||
RSpec.describe HamlLint::Linter::DocumentationLinks, feature_category: :tooling do
|
||||
include_context 'linter'
|
||||
|
||||
shared_examples 'link validation rules' do |link_pattern|
|
||||
context 'when link_to points to the existing file path' do
|
||||
let(:haml) { "= link_to 'Description', #{link_pattern}('_index.md')" }
|
||||
|
||||
it { is_expected.not_to report_lint }
|
||||
end
|
||||
|
||||
context 'when link_to points to the existing file with valid anchor' do
|
||||
let(:haml) { "= link_to 'Description', #{link_pattern}('_index.md', anchor: 'user-accounts'), target: '_blank'" }
|
||||
|
||||
it { is_expected.not_to report_lint }
|
||||
end
|
||||
|
||||
context 'when link_to points to the existing file path without .md extension' do
|
||||
let(:haml) { "= link_to 'Description', #{link_pattern}('index')" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
end
|
||||
|
||||
context 'when anchor is not correct' do
|
||||
let(:haml) { "= link_to 'Description', #{link_pattern}('_index.md', anchor: 'wrong')" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
|
||||
context "when #{link_pattern} has multiple options" do
|
||||
let(:haml) { "= link_to 'Description', #{link_pattern}('_index.md', key: :value, anchor: 'wrong')" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when file path is wrong' do
|
||||
let(:haml) { "= link_to 'Description', #{link_pattern}('wrong.md'), target: '_blank'" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
|
||||
context 'when haml ends with block definition' do
|
||||
let(:haml) { "= link_to 'Description', #{link_pattern}('wrong.md') do" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when link with wrong file path is assigned to a variable' do
|
||||
let(:haml) { "- my_link = link_to 'Description', #{link_pattern}('wrong.md')" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
end
|
||||
|
||||
context 'when it is a broken code' do
|
||||
let(:haml) { "= I am broken! ]]]]" }
|
||||
|
||||
it { is_expected.not_to report_lint }
|
||||
end
|
||||
|
||||
context 'when anchor belongs to a different element' do
|
||||
let(:haml) { "= link_to 'Description', #{link_pattern}('_index.md'), target: (anchor: 'blank')" }
|
||||
|
||||
it { is_expected.not_to report_lint }
|
||||
end
|
||||
|
||||
context "when a simple #{link_pattern}" do
|
||||
let(:haml) { "- url = #{link_pattern}('wrong')" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
end
|
||||
|
||||
context 'when link is not a string' do
|
||||
let(:haml) { "- url = #{link_pattern}(help_url)" }
|
||||
|
||||
it { is_expected.not_to report_lint }
|
||||
end
|
||||
|
||||
context 'when link is a part of the tag' do
|
||||
let(:haml) { ".data-form{ data: { url: #{link_pattern}('wrong') } }" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
end
|
||||
|
||||
context 'when the second link is invalid' do
|
||||
let(:haml) { ".data-form{ data: { url: #{link_pattern}('_index.md'), wrong_url: #{link_pattern}('wrong') } }" }
|
||||
|
||||
it { is_expected.to report_lint }
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'link validation rules', 'help_page_path'
|
||||
it_behaves_like 'link validation rules', 'help_page_url'
|
||||
it_behaves_like 'link validation rules', 'Rails.application.routes.url_helpers.help_page_url'
|
||||
it_behaves_like 'link validation rules', 'Gitlab::Routing.url_helpers.help_page_url'
|
||||
end
|
||||
|
|
@ -251,6 +251,6 @@ RSpec.describe SystemHook, feature_category: :webhooks do
|
|||
describe '#help_path' do
|
||||
subject { build(:system_hook).help_path }
|
||||
|
||||
it { is_expected.to eq('administration/system_hooks') }
|
||||
it { is_expected.to eq('/help/administration/system_hooks.md') }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -72,6 +72,105 @@ RSpec.describe 'PipelineCreate', feature_category: :pipeline_composition do
|
|||
expect(created_pipeline.source).to eq('api')
|
||||
expect(mutation_response['pipeline']['id']).to eq(created_pipeline.to_global_id.to_s)
|
||||
end
|
||||
|
||||
context 'when passing inputs' do
|
||||
let(:inputs) do
|
||||
[
|
||||
{ key: 'deploy_strategy', value: 'blue-green' },
|
||||
{ key: 'job_stage', value: 'deploy' },
|
||||
{ key: 'test_script', value: ['echo "test"'] },
|
||||
{ key: 'test_rules', value: [{ if: '$CI_PIPELINE_SOURCE == "api"' }] }, # static source of the mutation
|
||||
{ key: 'test_framework', value: '$TEST_FRAMEWORK' }
|
||||
]
|
||||
end
|
||||
|
||||
let(:params) { { ref: 'master', inputs: inputs } }
|
||||
|
||||
before do
|
||||
stub_ci_pipeline_yaml_file(
|
||||
File.read(Rails.root.join('spec/lib/gitlab/ci/config/yaml/fixtures/complex-included-ci.yml'))
|
||||
)
|
||||
end
|
||||
|
||||
it 'creates a pipeline using the inputs' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: user)
|
||||
end.to change { ::Ci::Pipeline.count }.by(1)
|
||||
|
||||
created_pipeline = ::Ci::Pipeline.last
|
||||
expect(created_pipeline.builds.map(&:name)).to contain_exactly(
|
||||
'my-job-build 1/2', 'my-job-build 2/2', 'my-job-test', 'my-job-test-2', 'my-job-deploy'
|
||||
)
|
||||
end
|
||||
|
||||
context 'when passing some inputs multiple times' do
|
||||
let(:inputs) do
|
||||
[
|
||||
{ key: 'deploy_strategy', value: 'blue-green' },
|
||||
{ key: 'job_stage', value: 'deploy' },
|
||||
{ key: 'test_script', value: ['echo "test"'] },
|
||||
{ key: 'job_stage', value: 'test' }
|
||||
]
|
||||
end
|
||||
|
||||
it 'creates a pipeline using the inputs considering the last key' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: user)
|
||||
end.to change { ::Ci::Pipeline.count }.by(1)
|
||||
|
||||
created_pipeline = ::Ci::Pipeline.last
|
||||
expect(created_pipeline.stages.map(&:name)).to contain_exactly('test')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the FF ci_inputs_for_pipelines is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_inputs_for_pipelines: false)
|
||||
end
|
||||
|
||||
it 'behaves like the inputs are never passed and returns errors' do
|
||||
post_graphql_mutation(mutation, current_user: user)
|
||||
|
||||
expect(mutation_response['errors'].first).to include(
|
||||
'`deploy_strategy` input: required value has not been provided'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are errors in the inputs' do
|
||||
let(:inputs) do
|
||||
[{ key: 'deploy_strategy', value: 'invalid' }]
|
||||
end
|
||||
|
||||
it 'returns errors' do
|
||||
post_graphql_mutation(mutation, current_user: user)
|
||||
|
||||
expect(mutation_response['errors'].first).to include(
|
||||
'`deploy_strategy` input: `invalid` cannot be used because it is not in the list of allowed options'
|
||||
)
|
||||
expect(mutation_response['errors'].first).to include(
|
||||
'`job_stage` input: required value has not been provided'
|
||||
)
|
||||
expect(mutation_response['errors'].first).to include(
|
||||
'`test_script` input: required value has not been provided'
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the FF ci_inputs_for_pipelines is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_inputs_for_pipelines: false)
|
||||
end
|
||||
|
||||
it 'behaves like the inputs are never passed and returns errors' do
|
||||
post_graphql_mutation(mutation, current_user: user)
|
||||
|
||||
expect(mutation_response['errors'].first).to include(
|
||||
'`deploy_strategy` input: required value has not been provided'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the `async` argument is `true`' do
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ RSpec.describe 'Query.work_item(id)', feature_category: :team_planning do
|
|||
'reference' => work_item.to_reference,
|
||||
'createNoteEmail' => work_item_email,
|
||||
'archived' => false,
|
||||
'userPermissions' => {
|
||||
'userPermissions' => hash_including(
|
||||
'readWorkItem' => true,
|
||||
'updateWorkItem' => true,
|
||||
'deleteWorkItem' => false,
|
||||
|
|
@ -92,7 +92,7 @@ RSpec.describe 'Query.work_item(id)', feature_category: :team_planning do
|
|||
'cloneWorkItem' => true,
|
||||
'reportSpam' => false,
|
||||
'summarizeComments' => false
|
||||
},
|
||||
),
|
||||
'project' => hash_including('id' => project.to_gid.to_s, 'fullPath' => project.full_path)
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -109,9 +109,6 @@ mapping:
|
|||
- source: 'data/whats_new/\w*\.yml'
|
||||
test: 'spec/lib/release_highlights/validator_spec.rb'
|
||||
|
||||
# The documentation index page is used in this haml_lint spec
|
||||
- source: 'doc/_index\.md'
|
||||
test: 'spec/haml_lint/linter/documentation_links_spec.rb'
|
||||
|
||||
- source: '(?<prefix>ee/)?app/models/.+\.rb'
|
||||
test: 'spec/models/every_model_spec.rb'
|
||||
|
|
|
|||
Loading…
Reference in New Issue