Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_todo/lint/missing_cop_enable_directive.yml33
-rw-r--r--app/assets/javascripts/batch_comments/components/submit_dropdown.vue4
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue49
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue2
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/expiration_dropdown.vue30
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy.vue2
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue25
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/constants.js2
-rw-r--r--app/assets/javascripts/packages_and_registries/shared/components/settings_block.vue6
-rw-r--r--app/graphql/mutations/ci/runners_registration_token/reset.rb5
-rw-r--r--app/models/ci/runner.rb13
-rw-r--r--app/services/ci/runners/process_runner_version_update_service.rb27
-rw-r--r--app/services/ci/runners/reset_registration_token_service.rb10
-rw-r--r--app/views/profiles/emails/index.html.haml37
-rw-r--r--app/workers/all_queues.yml9
-rw-r--r--app/workers/ci/runners/process_runner_version_update_worker.rb25
-rw-r--r--config/sidekiq_queues.yml2
-rw-r--r--doc/ci/variables/predefined_variables.md2
-rw-r--r--doc/user/project/pages/pages_access_control.md2
-rw-r--r--lib/gitlab/background_migration/migrate_shared_vulnerability_scanners.rb2
-rw-r--r--lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml1
-rw-r--r--lib/gitlab/tracking.rb2
-rw-r--r--lib/gitlab/tracking/destinations/snowplow_micro.rb2
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb7
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb4
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap29
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/container_expiration_policy_form_spec.js.snap3
-rw-r--r--spec/lib/gitlab/tracking/destinations/snowplow_micro_spec.rb36
-rw-r--r--spec/lib/gitlab/tracking_spec.rb35
-rw-r--r--spec/models/ci/runner_spec.rb49
-rw-r--r--spec/services/ci/runners/process_runner_version_update_service_spec.rb80
-rw-r--r--spec/services/ci/runners/reset_registration_token_service_spec.rb13
-rw-r--r--spec/workers/ci/runners/process_runner_version_update_worker_spec.rb48
33 files changed, 419 insertions, 177 deletions
diff --git a/.rubocop_todo/lint/missing_cop_enable_directive.yml b/.rubocop_todo/lint/missing_cop_enable_directive.yml
index 4c1c8430204..87ac47deaf5 100644
--- a/.rubocop_todo/lint/missing_cop_enable_directive.yml
+++ b/.rubocop_todo/lint/missing_cop_enable_directive.yml
@@ -1,8 +1,5 @@
---
Lint/MissingCopEnableDirective:
- # Offense count: 199
- # Temporarily disabled due to too many offenses
- Enabled: false
Exclude:
- 'app/controllers/admin/users_controller.rb'
- 'app/controllers/projects/forks_controller.rb'
@@ -20,14 +17,19 @@ Lint/MissingCopEnableDirective:
- 'app/graphql/types/ci/build_need_type.rb'
- 'app/graphql/types/ci/config/config_type.rb'
- 'app/graphql/types/ci/config/group_type.rb'
+ - 'app/graphql/types/ci/config/include_type.rb'
- 'app/graphql/types/ci/config/job_restriction_type.rb'
- 'app/graphql/types/ci/config/job_type.rb'
- 'app/graphql/types/ci/config/need_type.rb'
- 'app/graphql/types/ci/config/stage_type.rb'
- 'app/graphql/types/ci/group_type.rb'
+ - 'app/graphql/types/ci/group_variable_type.rb'
+ - 'app/graphql/types/ci/instance_variable_type.rb'
- 'app/graphql/types/ci/job_artifact_type.rb'
- 'app/graphql/types/ci/job_type.rb'
+ - 'app/graphql/types/ci/manual_variable_type.rb'
- 'app/graphql/types/ci/pipeline_message_type.rb'
+ - 'app/graphql/types/ci/project_variable_type.rb'
- 'app/graphql/types/ci/runner_architecture_type.rb'
- 'app/graphql/types/ci/runner_platform_type.rb'
- 'app/graphql/types/ci/runner_setup_type.rb'
@@ -41,6 +43,7 @@ Lint/MissingCopEnableDirective:
- 'app/graphql/types/countable_connection_type.rb'
- 'app/graphql/types/design_management_type.rb'
- 'app/graphql/types/issue_connection_type.rb'
+ - 'app/graphql/types/limited_countable_connection_type.rb'
- 'app/graphql/types/merge_request_connection_type.rb'
- 'app/graphql/types/packages/composer/json_type.rb'
- 'app/graphql/types/packages/helm/dependency_type.rb'
@@ -71,6 +74,7 @@ Lint/MissingCopEnableDirective:
- 'db/migrate/20210818061156_remove_project_profile_compound_index_from_dast_profile_schedules.rb'
- 'db/migrate/20210818115613_add_index_project_id_on_dast_profile_schedule.rb'
- 'db/migrate/20211013014228_add_content_validation_endpoint_to_application_settings.rb'
+ - 'db/migrate/20220531024905_add_operations_access_levels_to_project_feature.rb'
- 'db/post_migrate/20210825182303_remove_duplicate_dast_site_tokens_with_same_token.rb'
- 'ee/app/controllers/ee/admin/dashboard_controller.rb'
- 'ee/app/controllers/ee/admin/groups_controller.rb'
@@ -90,6 +94,7 @@ Lint/MissingCopEnableDirective:
- 'ee/app/graphql/types/ci/minutes/project_monthly_usage_type.rb'
- 'ee/app/graphql/types/compliance_management/compliance_framework_type.rb'
- 'ee/app/graphql/types/dast/profile_cadence_type.rb'
+ - 'ee/app/graphql/types/geo/ci_secure_file_registry_type.rb'
- 'ee/app/graphql/types/geo/group_wiki_repository_registry_type.rb'
- 'ee/app/graphql/types/geo/job_artifact_registry_type.rb'
- 'ee/app/graphql/types/geo/lfs_object_registry_type.rb'
@@ -107,6 +112,7 @@ Lint/MissingCopEnableDirective:
- 'ee/app/graphql/types/security_report_summary_type.rb'
- 'ee/app/graphql/types/security_scanners.rb'
- 'ee/app/graphql/types/time_report_stats_type.rb'
+ - 'ee/app/graphql/types/timebox_error_type.rb'
- 'ee/app/graphql/types/timebox_metrics_type.rb'
- 'ee/app/graphql/types/timebox_report_type.rb'
- 'ee/app/graphql/types/vulnerabilities_count_by_day_type.rb'
@@ -135,20 +141,29 @@ Lint/MissingCopEnableDirective:
- 'ee/app/graphql/types/vulnerable_dependency_type.rb'
- 'ee/app/graphql/types/vulnerable_kubernetes_resource_type.rb'
- 'ee/app/graphql/types/vulnerable_package_type.rb'
+ - 'ee/app/services/ee/ci/queue/build_queue_service.rb'
+ - 'ee/app/workers/ci/runners/stale_group_runners_prune_cron_worker.rb'
- 'ee/app/workers/groups/export_memberships_worker.rb'
- 'ee/app/workers/update_max_seats_used_for_gitlab_com_subscriptions_worker.rb'
- 'ee/lib/api/ldap_group_links.rb'
- 'ee/lib/api/scim.rb'
+ - 'ee/lib/ee/gitlab/background_migration/backfill_project_statistics_container_repository_size.rb'
- 'ee/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules.rb'
+ - 'ee/lib/ee/gitlab/background_migration/purge_stale_security_scans.rb'
- 'ee/lib/ee/gitlab/usage_data.rb'
- - 'ee/lib/elastic/latest/git_class_proxy.rb'
- 'ee/lib/gitlab/spdx/license.rb'
+ - 'ee/spec/controllers/projects/legacy_pipelines_controller_spec.rb'
+ - 'ee/spec/helpers/groups/security_features_helper_spec.rb'
+ - 'ee/spec/helpers/projects/security/discover_helper_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/delete_invalid_epic_issues_spec.rb'
+ - 'lib/gitlab/audit/null_author.rb'
- 'lib/gitlab/auth/ldap/dn.rb'
+ - 'lib/gitlab/background_migration/backfill_imported_issue_search_data.rb'
- 'lib/gitlab/background_migration/backfill_issue_search_data.rb'
- 'lib/gitlab/background_migration/backfill_iteration_cadence_id_for_boards.rb'
- 'lib/gitlab/background_migration/backfill_namespace_traversal_ids_children.rb'
- 'lib/gitlab/background_migration/backfill_namespace_traversal_ids_roots.rb'
- - 'lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans.rb'
+ - 'lib/gitlab/background_migration/delete_invalid_epic_issues.rb'
- 'lib/gitlab/background_migration/drop_invalid_vulnerabilities.rb'
- 'lib/gitlab/background_migration/fix_incorrect_max_seats_used.rb'
- 'lib/gitlab/background_migration/mailers/unconfirm_mailer.rb'
@@ -161,11 +176,13 @@ Lint/MissingCopEnableDirective:
- 'lib/gitlab/background_migration/populate_resolved_on_default_branch_column.rb'
- 'lib/gitlab/background_migration/populate_test_reports_issue_id.rb'
- 'lib/gitlab/background_migration/populate_uuids_for_security_findings.rb'
+ - 'lib/gitlab/background_migration/purge_stale_security_scans.rb'
- 'lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb'
- 'lib/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb'
- 'lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings.rb'
- 'lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url.rb'
- 'lib/gitlab/background_migration/update_users_where_two_factor_auth_required_from_group.rb'
+ - 'lib/gitlab/buffered_io.rb'
- 'lib/gitlab/ci/reports/test_suite_summary.rb'
- 'lib/gitlab/data_builder/push.rb'
- 'lib/gitlab/database/load_balancing/connection_proxy.rb'
@@ -174,7 +191,6 @@ Lint/MissingCopEnableDirective:
- 'lib/gitlab/github_import/client.rb'
- 'lib/gitlab/github_import/importer/diff_note_importer.rb'
- 'lib/gitlab/gon_helper.rb'
- - 'lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb'
- 'lib/gitlab/graphql/pagination/keyset/last_items.rb'
- 'lib/gitlab/graphql/standard_graphql_error.rb'
- 'lib/gitlab/metrics/methods.rb'
@@ -184,10 +200,13 @@ Lint/MissingCopEnableDirective:
- 'lib/gitlab/testing/request_blocker_middleware.rb'
- 'lib/gitlab/testing/request_inspector_middleware.rb'
- 'lib/gitlab/testing/robots_blocker_middleware.rb'
+ - 'lib/unnested_in_filters/dsl.rb'
+ - 'lib/unnested_in_filters/rewriter.rb'
- 'qa/qa/scenario/test/integration/registry_with_cdn.rb'
- 'spec/benchmarks/banzai_benchmark.rb'
- 'spec/lib/gitlab/sidekiq_middleware/size_limiter/server_spec.rb'
+ - 'spec/lib/initializer_connections_spec.rb'
- 'spec/support/capybara.rb'
- 'spec/support/cycle_analytics_helpers/test_generation.rb'
- 'spec/support/google_api/cloud_platform_helpers.rb'
- - 'tooling/danger/product_intelligence.rb' \ No newline at end of file
+ - 'tooling/danger/product_intelligence.rb'
diff --git a/app/assets/javascripts/batch_comments/components/submit_dropdown.vue b/app/assets/javascripts/batch_comments/components/submit_dropdown.vue
index 7ed77426a5e..54b9953270b 100644
--- a/app/assets/javascripts/batch_comments/components/submit_dropdown.vue
+++ b/app/assets/javascripts/batch_comments/components/submit_dropdown.vue
@@ -84,7 +84,7 @@ export default {
class="submit-review-dropdown"
data-qa-selector="submit_review_dropdown"
variant="info"
- category="secondary"
+ category="primary"
>
<template #button-content>
{{ __('Finish review') }}
@@ -139,7 +139,7 @@ export default {
</div>
</div>
</gl-form-group>
- <div class="gl-display-flex gl-justify-content-end gl-mt-5">
+ <div class="gl-display-flex gl-justify-content-start gl-mt-5">
<gl-button
:loading="isSubmitting"
variant="confirm"
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
index f5946797626..36e1b883400 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue
@@ -65,9 +65,6 @@ export default {
this.checkBreakpoints();
},
methods: {
- dynamicSlotName(index) {
- return `metadata-tag${index}`;
- },
checkBreakpoints() {
this.isDesktop = GlBreakpointInstance.isDesktop();
},
@@ -83,21 +80,38 @@ export default {
data-qa-selector="package_title"
>
<template #sub-header>
- <span data-testid="sub-header">
+ <div data-testid="sub-header" class="gl-display-flex gl-gap-3">
<gl-sprintf :message="$options.i18n.packageInfo">
<template #version>
{{ packageEntity.version }}
</template>
<template #timeAgo>
- <time-ago-tooltip
- v-if="packageEntity.createdAt"
- class="gl-ml-2"
- :time="packageEntity.createdAt"
- />
+ <time-ago-tooltip v-if="packageEntity.createdAt" :time="packageEntity.createdAt" />
</template>
</gl-sprintf>
- </span>
+
+ <package-tags
+ v-if="isDesktop && hasTagsToDisplay"
+ :tag-display-limit="2"
+ :tags="packageEntity.tags.nodes"
+ hide-label
+ />
+
+ <!-- we need to duplicate the package tags on mobile to ensure proper styling inside the flex wrap -->
+ <template v-else-if="hasTagsToDisplay">
+ <gl-badge
+ v-for="(tag, index) in packageEntity.tags.nodes"
+ :key="index"
+ class="gl-my-1"
+ data-testid="tag-badge"
+ variant="info"
+ size="sm"
+ >
+ {{ tag.name }}
+ </gl-badge>
+ </template>
+ </div>
</template>
<template v-if="packageTypeDisplay" #metadata-type>
@@ -121,21 +135,6 @@ export default {
<metadata-item data-testid="package-ref" icon="branch" :text="packagePipeline.ref" />
</template>
- <template v-if="isDesktop && hasTagsToDisplay" #metadata-tags>
- <package-tags :tag-display-limit="2" :tags="packageEntity.tags.nodes" hide-label />
- </template>
-
- <!-- we need to duplicate the package tags on mobile to ensure proper styling inside the flex wrap -->
- <template
- v-for="(tag, index) in packageEntity.tags.nodes"
- v-else-if="hasTagsToDisplay"
- #[dynamicSlotName(index)]
- >
- <gl-badge :key="index" class="gl-my-1" data-testid="tag-badge" variant="info" size="sm">
- {{ tag.name }}
- </gl-badge>
- </template>
-
<template #right-actions>
<slot name="delete-button"></slot>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue
index 90a18d5cf5a..1c44d2bc38b 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue
@@ -11,7 +11,7 @@ import {
UNAVAILABLE_ADMIN_FEATURE_TEXT,
} from '~/packages_and_registries/settings/project/constants';
import expirationPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_expiration_policy.query.graphql';
-import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
+import SettingsBlock from '~/packages_and_registries/shared/components/settings_block.vue';
import ContainerExpirationPolicyForm from './container_expiration_policy_form.vue';
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/expiration_dropdown.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/expiration_dropdown.vue
index 7682754fdcb..f06e3a41bd0 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/expiration_dropdown.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/expiration_dropdown.vue
@@ -35,22 +35,34 @@ export default {
required: false,
default: '',
},
+ dropdownClass: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
};
</script>
<template>
<gl-form-group :id="`${name}-form-group`" :label-for="name" :label="label">
- <gl-form-select :id="name" :value="value" :disabled="disabled" @input="$emit('input', $event)">
- <option
- v-for="option in formOptions"
- :key="option.key"
- :value="option.key"
- data-testid="option"
+ <div :class="dropdownClass">
+ <gl-form-select
+ :id="name"
+ :value="value"
+ :disabled="disabled"
+ @input="$emit('input', $event)"
>
- {{ option.label }}
- </option>
- </gl-form-select>
+ <option
+ v-for="option in formOptions"
+ :key="option.key"
+ :value="option.key"
+ data-testid="option"
+ >
+ {{ option.label }}
+ </option>
+ </gl-form-select>
+ </div>
<template v-if="description" #description>
<span data-testid="description" class="gl-text-gray-400">
{{ description }}
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy.vue
index 1170407a349..2f4bc35e5f7 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy.vue
@@ -6,7 +6,7 @@ import {
PACKAGES_CLEANUP_POLICY_DESCRIPTION,
} from '~/packages_and_registries/settings/project/constants';
import packagesCleanupPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_packages_cleanup_policy.query.graphql';
-import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
+import SettingsBlock from '~/packages_and_registries/shared/components/settings_block.vue';
import PackagesCleanupPolicyForm from './packages_cleanup_policy_form.vue';
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue
index b1751d5174a..f1f0b970b15 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue
@@ -3,10 +3,10 @@ import { GlButton } from '@gitlab/ui';
import {
UPDATE_SETTINGS_ERROR_MESSAGE,
UPDATE_SETTINGS_SUCCESS_MESSAGE,
- SET_CLEANUP_POLICY_BUTTON,
KEEP_N_DUPLICATED_PACKAGE_FILES_DESCRIPTION,
KEEP_N_DUPLICATED_PACKAGE_FILES_FIELDNAME,
KEEP_N_DUPLICATED_PACKAGE_FILES_LABEL,
+ SET_CLEANUP_POLICY_BUTTON,
} from '~/packages_and_registries/settings/project/constants';
import updatePackagesCleanupPolicyMutation from '~/packages_and_registries/settings/project/graphql/mutations/update_packages_cleanup_policy.mutation.graphql';
import { formOptionsGenerator } from '~/packages_and_registries/settings/project/utils';
@@ -108,18 +108,17 @@ export default {
<template>
<form ref="form-element" @submit.prevent="submit">
- <div class="gl-md-max-w-50p">
- <expiration-dropdown
- v-model="prefilledForm.keepNDuplicatedPackageFiles"
- :disabled="isFieldDisabled"
- :form-options="$options.formOptions.keepNDuplicatedPackageFiles"
- :label="$options.i18n.KEEP_N_DUPLICATED_PACKAGE_FILES_LABEL"
- :description="$options.i18n.KEEP_N_DUPLICATED_PACKAGE_FILES_DESCRIPTION"
- name="keep-n-duplicated-package-files"
- data-testid="keep-n-duplicated-package-files-dropdown"
- @input="onModelChange($event, 'keepNDuplicatedPackageFiles')"
- />
- </div>
+ <expiration-dropdown
+ :value="prefilledForm.keepNDuplicatedPackageFiles"
+ :disabled="isFieldDisabled"
+ :form-options="$options.formOptions.keepNDuplicatedPackageFiles"
+ :label="$options.i18n.KEEP_N_DUPLICATED_PACKAGE_FILES_LABEL"
+ :description="$options.i18n.KEEP_N_DUPLICATED_PACKAGE_FILES_DESCRIPTION"
+ dropdown-class="gl-md-max-w-50p gl-sm-pr-5"
+ name="keep-n-duplicated-package-files"
+ data-testid="keep-n-duplicated-package-files-dropdown"
+ @input="onModelChange($event, 'keepNDuplicatedPackageFiles')"
+ />
<div class="gl-mt-7 gl-display-flex gl-align-items-center">
<gl-button
data-testid="save-button"
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/constants.js b/app/assets/javascripts/packages_and_registries/settings/project/constants.js
index 948520151ce..fcb4a8ee297 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/constants.js
+++ b/app/assets/javascripts/packages_and_registries/settings/project/constants.js
@@ -4,7 +4,7 @@ export const CONTAINER_CLEANUP_POLICY_TITLE = s__(`ContainerRegistry|Clean up im
export const CONTAINER_CLEANUP_POLICY_DESCRIPTION = s__(
`ContainerRegistry|Save storage space by automatically deleting tags from the container registry and keeping the ones you want. %{linkStart}How does cleanup work?%{linkEnd}`,
);
-export const SET_CLEANUP_POLICY_BUTTON = __('Save');
+export const SET_CLEANUP_POLICY_BUTTON = __('Save changes');
export const UNAVAILABLE_FEATURE_TITLE = s__(
`ContainerRegistry|Cleanup policy for tags is disabled`,
);
diff --git a/app/assets/javascripts/packages_and_registries/shared/components/settings_block.vue b/app/assets/javascripts/packages_and_registries/shared/components/settings_block.vue
index 5caf95cd050..0458b914b58 100644
--- a/app/assets/javascripts/packages_and_registries/shared/components/settings_block.vue
+++ b/app/assets/javascripts/packages_and_registries/shared/components/settings_block.vue
@@ -1,7 +1,7 @@
<template>
<section class="settings gl-py-7">
- <div class="gl-lg-display-flex">
- <div class="gl-lg-w-half gl-pr-10">
+ <div class="gl-lg-display-flex gl-gap-6">
+ <div class="gl-lg-w-40p gl-pr-10 gl-flex-shrink-0">
<h4>
<slot name="title"></slot>
</h4>
@@ -9,7 +9,7 @@
<slot name="description"></slot>
</p>
</div>
- <div class="gl-lg-w-half gl-pt-3">
+ <div class="gl-pt-3 gl-flex-grow-1">
<slot></slot>
</div>
</div>
diff --git a/app/graphql/mutations/ci/runners_registration_token/reset.rb b/app/graphql/mutations/ci/runners_registration_token/reset.rb
index 8c49b682ab0..c9fe7ea47f0 100644
--- a/app/graphql/mutations/ci/runners_registration_token/reset.rb
+++ b/app/graphql/mutations/ci/runners_registration_token/reset.rb
@@ -49,7 +49,10 @@ module Mutations
end
def reset_token(scope)
- ::Ci::Runners::ResetRegistrationTokenService.new(scope, current_user).execute if scope
+ return unless scope
+
+ result = ::Ci::Runners::ResetRegistrationTokenService.new(scope, current_user).execute
+ result.payload[:new_registration_token] if result.success?
end
end
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 47d9cb9393e..6c3754d84d0 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -437,7 +437,12 @@ module Ci
cache_attributes(values)
# We save data without validation, it will always change due to `contacted_at`
- self.update_columns(values) if persist_cached_data?
+ if persist_cached_data?
+ version_updated = values.include?(:version) && values[:version] != version
+
+ update_columns(values)
+ schedule_runner_version_update if version_updated
+ end
end
end
@@ -565,6 +570,12 @@ module Ci
errors.add(:runner, 'needs to be assigned to exactly one group')
end
end
+
+ def schedule_runner_version_update
+ return unless version
+
+ Ci::Runners::ProcessRunnerVersionUpdateWorker.perform_async(version)
+ end
end
end
diff --git a/app/services/ci/runners/process_runner_version_update_service.rb b/app/services/ci/runners/process_runner_version_update_service.rb
new file mode 100644
index 00000000000..ed591a9ab3e
--- /dev/null
+++ b/app/services/ci/runners/process_runner_version_update_service.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class ProcessRunnerVersionUpdateService
+ def initialize(version)
+ @version = version
+ end
+
+ def execute
+ return ServiceResponse.error(message: 'version not present') unless @version
+
+ _, status = upgrade_check_service.check_runner_upgrade_suggestion(@version)
+ return ServiceResponse.error(message: 'upgrade version check failed') if status == :error
+
+ Ci::RunnerVersion.upsert({ version: @version, status: status })
+ ServiceResponse.success(payload: { upgrade_status: status.to_s })
+ end
+
+ private
+
+ def upgrade_check_service
+ Gitlab::Ci::RunnerUpgradeCheck.instance
+ end
+ end
+ end
+end
diff --git a/app/services/ci/runners/reset_registration_token_service.rb b/app/services/ci/runners/reset_registration_token_service.rb
index 81a70a771cf..dddbfb78d44 100644
--- a/app/services/ci/runners/reset_registration_token_service.rb
+++ b/app/services/ci/runners/reset_registration_token_service.rb
@@ -11,15 +11,19 @@ module Ci
end
def execute
- return unless @user.present? && @user.can?(:update_runners_registration_token, scope)
+ unless @user.present? && @user.can?(:update_runners_registration_token, scope)
+ return ServiceResponse.error(message: 'user not allowed to update runners registration token')
+ end
if scope.respond_to?(:runners_registration_token)
scope.reset_runners_registration_token!
- scope.runners_registration_token
+ runners_token = scope.runners_registration_token
else
scope.reset_runners_token!
- scope.runners_token
+ runners_token = scope.runners_token
end
+
+ ServiceResponse.success(payload: { new_registration_token: runners_token })
end
private
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index 0ec32004a9a..ef9e7512b57 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -36,28 +36,31 @@
%ul.content-list
%li
= render partial: 'shared/email_with_badge', locals: { email: @primary_email, verified: current_user.confirmed? }
- %span.float-right
- = gl_badge_tag s_('Profiles|Primary email'), variant: :success
+ %ul
+ %li= s_('Profiles|Primary email')
- if @primary_email === current_user.commit_email_or_default
- = gl_badge_tag s_('Profiles|Commit email'), variant: :info
+ %li= s_('Profiles|Commit email')
- if @primary_email === current_user.public_email
- = gl_badge_tag s_('Profiles|Public email'), variant: :info
+ %li= s_('Profiles|Public email')
- if @primary_email === current_user.notification_email_or_default
- = gl_badge_tag s_('Profiles|Default notification email'), variant: :info
+ %li= s_('Profiles|Default notification email')
- @emails.reject(&:user_primary_email?).each do |email|
%li{ data: { qa_selector: 'email_row_content' } }
- = render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
- %span.float-right
+ .gl-display-flex.gl-justify-content-space-between{ style: 'flex-flow: wrap-reverse; row-gap: 0.5rem' }
+ %div
+ = render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
+ .gl-ml-n3
+ - unless email.confirmed?
+ - confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}"
+ = link_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, class: 'gl-button btn btn-sm btn-default gl-ml-3'
+
+ = link_to profile_email_path(email), data: { confirm: _('Are you sure?'), qa_selector: 'delete_email_link'}, method: :delete, class: 'gl-button btn btn-sm btn-danger gl-ml-3' do
+ %span.sr-only= _('Remove')
+ = sprite_icon('remove')
+ %ul
- if email.email === current_user.commit_email_or_default
- = gl_badge_tag s_('Profiles|Commit email'), variant: :info
+ %li= s_('Profiles|Commit email')
- if email.email === current_user.public_email
- = gl_badge_tag s_('Profiles|Public email'), variant: :info
+ %li= s_('Profiles|Public email')
- if email.email === current_user.notification_email_or_default
- = gl_badge_tag s_('Profiles|Notification email'), variant: :info
- - unless email.confirmed?
- - confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}"
- = link_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, class: 'gl-button btn btn-sm btn-default gl-ml-3'
-
- = link_to profile_email_path(email), data: { confirm: _('Are you sure?'), qa_selector: 'delete_email_link'}, method: :delete, class: 'gl-button btn btn-sm btn-danger gl-ml-3' do
- %span.sr-only= _('Remove')
- = sprite_icon('remove')
+ %li= s_('Profiles|Notification email')
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 2fc1998568c..73a9eea3a7d 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -2136,6 +2136,15 @@
:weight: 1
:idempotent: true
:tags: []
+- :name: ci_runners_process_runner_version_update
+ :worker_name: Ci::Runners::ProcessRunnerVersionUpdateWorker
+ :feature_category: :runner_fleet
+ :has_external_dependencies: false
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: create_commit_signature
:worker_name: CreateCommitSignatureWorker
:feature_category: :source_code_management
diff --git a/app/workers/ci/runners/process_runner_version_update_worker.rb b/app/workers/ci/runners/process_runner_version_update_worker.rb
new file mode 100644
index 00000000000..f1ad0c8563e
--- /dev/null
+++ b/app/workers/ci/runners/process_runner_version_update_worker.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class ProcessRunnerVersionUpdateWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ feature_category :runner_fleet
+ urgency :low
+
+ idempotent!
+ deduplicate :until_executing
+
+ def perform(version)
+ result = ::Ci::Runners::ProcessRunnerVersionUpdateService.new(version).execute
+
+ result.to_h.slice(:status, :message, :upgrade_status).each do |key, value|
+ log_extra_metadata_on_done(key, value)
+ end
+ end
+ end
+ end
+end
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index b4e2071668e..d49c2f1b072 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -93,6 +93,8 @@
- 1
- - ci_job_artifacts_expire_project_build_artifacts
- 1
+- - ci_runners_process_runner_version_update
+ - 1
- - ci_upstream_projects_subscriptions_cleanup
- 1
- - cluster_agent
diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md
index 024e47b2cea..87624d98bbb 100644
--- a/doc/ci/variables/predefined_variables.md
+++ b/doc/ci/variables/predefined_variables.md
@@ -93,7 +93,7 @@ as it can cause the pipeline to behave unexpectedly.
| `CI_PROJECT_NAMESPACE` | 8.10 | 0.5 | The project namespace (username or group name) of the job. |
| `CI_PROJECT_PATH_SLUG` | 9.3 | all | `$CI_PROJECT_PATH` in lowercase with characters that are not `a-z` or `0-9` replaced with `-` and shortened to 63 bytes. Use in URLs and domain names. |
| `CI_PROJECT_PATH` | 8.10 | 0.5 | The project namespace with the project name included. |
-| `CI_PROJECT_REPOSITORY_LANGUAGES` | 12.3 | all | A comma-separated, lowercase list of the languages used in the repository. For example `ruby,javascript,html,css`. |
+| `CI_PROJECT_REPOSITORY_LANGUAGES` | 12.3 | all | A comma-separated, lowercase list of the languages used in the repository. For example `ruby,javascript,html,css`. The maximum number of languages is limited to 5. An issue [proposes to increase the limit](https://gitlab.com/gitlab-org/gitlab/-/issues/368925). |
| `CI_PROJECT_ROOT_NAMESPACE` | 13.2 | 0.5 | The root project namespace (username or group name) of the job. For example, if `CI_PROJECT_NAMESPACE` is `root-group/child-group/grandchild-group`, `CI_PROJECT_ROOT_NAMESPACE` is `root-group`. |
| `CI_PROJECT_TITLE` | 12.4 | all | The human-readable project name as displayed in the GitLab web interface. |
| `CI_PROJECT_DESCRIPTION` | 15.1 | all | The project description as displayed in the GitLab web interface. |
diff --git a/doc/user/project/pages/pages_access_control.md b/doc/user/project/pages/pages_access_control.md
index eb897c176fa..e6446c34bf0 100644
--- a/doc/user/project/pages/pages_access_control.md
+++ b/doc/user/project/pages/pages_access_control.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Pages access control **(FREE)**
-> Available on GitLab.com in GitLab 12.4.
-
You can enable Pages access control on your project
if your administrator has [enabled the access control feature](../../../administration/pages/index.md#access-control)
on your GitLab instance. When enabled, only authenticated
diff --git a/lib/gitlab/background_migration/migrate_shared_vulnerability_scanners.rb b/lib/gitlab/background_migration/migrate_shared_vulnerability_scanners.rb
index 6b6fa1cc848..bea0120f093 100644
--- a/lib/gitlab/background_migration/migrate_shared_vulnerability_scanners.rb
+++ b/lib/gitlab/background_migration/migrate_shared_vulnerability_scanners.rb
@@ -7,8 +7,10 @@ module Gitlab
def perform
end
end
+ # rubocop: enable Style/Documentation
end
end
# rubocop: disable Layout/LineLength
Gitlab::BackgroundMigration::MigrateSharedVulnerabilityScanners.prepend_mod_with("Gitlab::BackgroundMigration::MigrateSharedVulnerabilityScanners")
+# rubocop: enable Layout/LineLength
diff --git a/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml b/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
index 464b81965f2..dc55277318b 100644
--- a/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
@@ -42,6 +42,7 @@ lint-test-job: # This job also runs in the test stage.
deploy-job: # This job runs in the deploy stage.
stage: deploy # It only runs when *both* jobs in the test stage complete successfully.
+ environment: production
script:
- echo "Deploying application..."
- echo "Application successfully deployed."
diff --git a/lib/gitlab/tracking.rb b/lib/gitlab/tracking.rb
index 04745bafe7c..3b46b4c5498 100644
--- a/lib/gitlab/tracking.rb
+++ b/lib/gitlab/tracking.rb
@@ -41,7 +41,7 @@ module Gitlab
def snowplow_micro_enabled?
Rails.env.development? && Gitlab.config.snowplow_micro.enabled
rescue Settingslogic::MissingSetting
- Gitlab::Utils.to_boolean(ENV['SNOWPLOW_MICRO_ENABLE'])
+ false
end
private
diff --git a/lib/gitlab/tracking/destinations/snowplow_micro.rb b/lib/gitlab/tracking/destinations/snowplow_micro.rb
index c7a95e88d0b..09480f26106 100644
--- a/lib/gitlab/tracking/destinations/snowplow_micro.rb
+++ b/lib/gitlab/tracking/destinations/snowplow_micro.rb
@@ -54,7 +54,7 @@ module Gitlab
scheme = Gitlab.config.gitlab.https ? 'https' : 'http'
"#{scheme}://#{url}"
rescue Settingslogic::MissingSetting
- ENV['SNOWPLOW_MICRO_URI'] || DEFAULT_URI
+ DEFAULT_URI
end
end
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 8ccbc0d3fe2..a943a5e0205 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -1894,15 +1894,12 @@ RSpec.describe Projects::MergeRequestsController do
# First run to insert test data from lets, which does take up some 30 queries
get_ci_environments_status
- control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { get_ci_environments_status }.count
+ control_count = ActiveRecord::QueryRecorder.new { get_ci_environments_status }
environment2 = create(:environment, project: forked)
create(:deployment, :succeed, environment: environment2, sha: sha, ref: 'master', deployable: build)
- # TODO address the last 3 queries
- # See https://gitlab.com/gitlab-org/gitlab-foss/issues/63952 (3 queries)
- leeway = 3
- expect { get_ci_environments_status }.not_to exceed_all_query_limit(control_count + leeway)
+ expect { get_ci_environments_status }.not_to exceed_all_query_limit(control_count)
end
end
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index 9468540736f..1fb46c669e7 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -31,7 +31,6 @@ RSpec.describe 'Project > Settings > Packages & Registries > Container registry
subject
within '[data-testid="container-expiration-policy-project-settings"]' do
- click_button('Expand')
select('Every day', from: 'Run cleanup')
select('50 tags per image name', from: 'Keep the most recent:')
fill_in('Keep tags matching:', with: 'stable')
@@ -50,7 +49,6 @@ RSpec.describe 'Project > Settings > Packages & Registries > Container registry
subject
within '[data-testid="container-expiration-policy-project-settings"]' do
- click_button('Expand')
fill_in('Remove tags matching:', with: '*-production')
submit_button = find('[data-testid="save-button"')
@@ -76,7 +74,6 @@ RSpec.describe 'Project > Settings > Packages & Registries > Container registry
subject
within '[data-testid="container-expiration-policy-project-settings"]' do
- click_button('Expand')
expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
end
end
@@ -91,7 +88,6 @@ RSpec.describe 'Project > Settings > Packages & Registries > Container registry
subject
within '[data-testid="container-expiration-policy-project-settings"]' do
- click_button('Expand')
expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled')
end
end
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
index fdddc131412..61923233d2e 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
@@ -29,19 +29,25 @@ exports[`PackageTitle renders with tags 1`] = `
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-3"
>
- <span
+ <div
+ class="gl-display-flex gl-gap-3"
data-testid="sub-header"
>
v
1.0.0
published
<time-ago-tooltip-stub
- class="gl-ml-2"
cssclass=""
time="2020-08-17T14:23:32Z"
tooltipplacement="top"
/>
- </span>
+
+ <package-tags-stub
+ hidelabel="true"
+ tagdisplaylimit="2"
+ tags="[object Object],[object Object],[object Object]"
+ />
+ </div>
</div>
</div>
</div>
@@ -73,15 +79,6 @@ exports[`PackageTitle renders with tags 1`] = `
texttooltip=""
/>
</div>
- <div
- class="gl-display-flex gl-align-items-center gl-mr-5"
- >
- <package-tags-stub
- hidelabel="true"
- tagdisplaylimit="2"
- tags="[object Object],[object Object],[object Object]"
- />
- </div>
</div>
</div>
@@ -121,19 +118,21 @@ exports[`PackageTitle renders without tags 1`] = `
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-3"
>
- <span
+ <div
+ class="gl-display-flex gl-gap-3"
data-testid="sub-header"
>
v
1.0.0
published
<time-ago-tooltip-stub
- class="gl-ml-2"
cssclass=""
time="2020-08-17T14:23:32Z"
tooltipplacement="top"
/>
- </span>
+
+ <!---->
+ </div>
</div>
</div>
</div>
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/container_expiration_policy_form_spec.js.snap b/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/container_expiration_policy_form_spec.js.snap
index 108d9478788..5d08574234c 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/container_expiration_policy_form_spec.js.snap
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/container_expiration_policy_form_spec.js.snap
@@ -5,6 +5,7 @@ exports[`Container Expiration Policy Settings Form Cadence matches snapshot 1`]
class="gl-mr-7 gl-mb-0!"
data-testid="cadence-dropdown"
description=""
+ dropdownclass=""
formoptions="[object Object],[object Object],[object Object],[object Object],[object Object]"
label="Run cleanup:"
name="cadence"
@@ -24,6 +25,7 @@ exports[`Container Expiration Policy Settings Form Keep N matches snapshot 1`] =
<expiration-dropdown-stub
data-testid="keep-n-dropdown"
description=""
+ dropdownclass=""
formoptions="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"
label="Keep the most recent:"
name="keep-n"
@@ -47,6 +49,7 @@ exports[`Container Expiration Policy Settings Form OlderThan matches snapshot 1`
<expiration-dropdown-stub
data-testid="older-than-dropdown"
description=""
+ dropdownclass=""
formoptions="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"
label="Remove tags older than:"
name="older-than"
diff --git a/spec/lib/gitlab/tracking/destinations/snowplow_micro_spec.rb b/spec/lib/gitlab/tracking/destinations/snowplow_micro_spec.rb
index 2554a15d97e..48092a33da3 100644
--- a/spec/lib/gitlab/tracking/destinations/snowplow_micro_spec.rb
+++ b/spec/lib/gitlab/tracking/destinations/snowplow_micro_spec.rb
@@ -48,40 +48,8 @@ RSpec.describe Gitlab::Tracking::Destinations::SnowplowMicro do
allow(Gitlab.config).to receive(:snowplow_micro).and_raise(Settingslogic::MissingSetting)
end
- context 'when SNOWPLOW_MICRO_URI has scheme and port' do
- before do
- stub_env('SNOWPLOW_MICRO_URI', 'http://gdk.test:9091')
- end
-
- it 'returns hostname URI part' do
- expect(subject.hostname).to eq('gdk.test:9091')
- end
- end
-
- context 'when SNOWPLOW_MICRO_URI is without protocol' do
- before do
- stub_env('SNOWPLOW_MICRO_URI', 'gdk.test:9091')
- end
-
- it 'returns hostname URI part' do
- expect(subject.hostname).to eq('gdk.test:9091')
- end
- end
-
- context 'when SNOWPLOW_MICRO_URI is hostname only' do
- before do
- stub_env('SNOWPLOW_MICRO_URI', 'uriwithoutport')
- end
-
- it 'returns hostname URI with default HTTP port' do
- expect(subject.hostname).to eq('uriwithoutport:80')
- end
- end
-
- context 'when SNOWPLOW_MICRO_URI is not set' do
- it 'returns localhost hostname' do
- expect(subject.hostname).to eq('localhost:9090')
- end
+ it 'returns localhost hostname' do
+ expect(subject.hostname).to eq('localhost:9090')
end
end
end
diff --git a/spec/lib/gitlab/tracking_spec.rb b/spec/lib/gitlab/tracking_spec.rb
index 36ef1abcb50..028c985f3b3 100644
--- a/spec/lib/gitlab/tracking_spec.rb
+++ b/spec/lib/gitlab/tracking_spec.rb
@@ -90,15 +90,6 @@ RSpec.describe Gitlab::Tracking do
it_behaves_like 'delegates to SnowplowMicro destination with proper options'
end
-
- context "enabled with env variable" do
- before do
- allow(Gitlab.config).to receive(:snowplow_micro).and_raise(Settingslogic::MissingSetting)
- stub_env('SNOWPLOW_MICRO_ENABLE', '1')
- end
-
- it_behaves_like 'delegates to SnowplowMicro destination with proper options'
- end
end
it 'when feature flag is disabled' do
@@ -149,7 +140,6 @@ RSpec.describe Gitlab::Tracking do
context 'when destination is Snowplow' do
before do
- stub_env('SNOWPLOW_MICRO_ENABLE', '0')
allow(Rails.env).to receive(:development?).and_return(true)
end
@@ -158,7 +148,6 @@ RSpec.describe Gitlab::Tracking do
context 'when destination is SnowplowMicro' do
before do
- stub_env('SNOWPLOW_MICRO_ENABLE', '1')
allow(Rails.env).to receive(:development?).and_return(true)
end
@@ -212,4 +201,28 @@ RSpec.describe Gitlab::Tracking do
project: project, user: user, namespace: namespace, extra_key_1: 'extra value 1')
end
end
+
+ describe 'snowplow_micro_enabled?' do
+ before do
+ allow(Rails.env).to receive(:development?).and_return(true)
+ end
+
+ it 'returns true when snowplow_micro is enabled' do
+ stub_config(snowplow_micro: { enabled: true })
+
+ expect(described_class).to be_snowplow_micro_enabled
+ end
+
+ it 'returns false when snowplow_micro is disabled' do
+ stub_config(snowplow_micro: { enabled: false })
+
+ expect(described_class).not_to be_snowplow_micro_enabled
+ end
+
+ it 'returns false when snowplow_micro is not configured' do
+ allow(Gitlab.config).to receive(:snowplow_micro).and_raise(Settingslogic::MissingSetting)
+
+ expect(described_class).not_to be_snowplow_micro_enabled
+ end
+ end
end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index a822e613860..ae8748f8ae3 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -552,6 +552,10 @@ RSpec.describe Ci::Runner do
allow_any_instance_of(described_class).to receive(:cached_attribute).and_call_original
allow_any_instance_of(described_class).to receive(:cached_attribute)
.with(:platform).and_return("darwin")
+ allow_any_instance_of(described_class).to receive(:cached_attribute)
+ .with(:version).and_return("14.0.0")
+
+ allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async).once
end
context 'table tests' do
@@ -623,6 +627,10 @@ RSpec.describe Ci::Runner do
allow_any_instance_of(described_class).to receive(:cached_attribute).and_call_original
allow_any_instance_of(described_class).to receive(:cached_attribute)
.with(:platform).and_return("darwin")
+ allow_any_instance_of(described_class).to receive(:cached_attribute)
+ .with(:version).and_return("14.0.0")
+
+ allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async).once
end
context 'no cache value' do
@@ -693,19 +701,6 @@ RSpec.describe Ci::Runner do
it { is_expected.to eq([runner1]) }
end
- describe '#tick_runner_queue' do
- it 'sticks the runner to the primary and calls the original method' do
- runner = create(:ci_runner)
-
- expect(described_class.sticking).to receive(:stick)
- .with(:runner, runner.id)
-
- expect(Gitlab::Workhorse).to receive(:set_key_and_notify)
-
- runner.tick_runner_queue
- end
- end
-
describe '#matches_build?' do
using RSpec::Parameterized::TableSyntax
@@ -989,6 +984,16 @@ RSpec.describe Ci::Runner do
it 'returns a new last_update value' do
expect(runner.tick_runner_queue).not_to be_empty
end
+
+ it 'sticks the runner to the primary and calls the original method' do
+ runner = create(:ci_runner)
+
+ expect(described_class.sticking).to receive(:stick).with(:runner, runner.id)
+
+ expect(Gitlab::Workhorse).to receive(:set_key_and_notify)
+
+ runner.tick_runner_queue
+ end
end
describe '#ensure_runner_queue_value' do
@@ -1055,14 +1060,19 @@ RSpec.describe Ci::Runner do
it 'updates cache' do
expect_redis_update
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).not_to receive(:perform_async)
heartbeat
+
+ expect(runner.runner_version).to be_nil
end
end
context 'when database was not updated recently' do
before do
runner.contacted_at = 2.hours.ago
+
+ allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async)
end
context 'with invalid runner' do
@@ -1075,12 +1085,25 @@ RSpec.describe Ci::Runner do
expect_redis_update
does_db_update
+
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async).once
+ end
+ end
+
+ context 'with unchanged runner version' do
+ let(:runner) { create(:ci_runner, version: version) }
+
+ it 'does not schedule ci_runner_versions update' do
+ heartbeat
+
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).not_to have_received(:perform_async)
end
end
it 'updates redis cache and database' do
expect_redis_update
does_db_update
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async).once
end
%w(custom shell docker docker-windows docker-ssh ssh parallels virtualbox docker+machine docker-ssh+machine kubernetes some-unknown-type).each do |executor|
diff --git a/spec/services/ci/runners/process_runner_version_update_service_spec.rb b/spec/services/ci/runners/process_runner_version_update_service_spec.rb
new file mode 100644
index 00000000000..b885138fc7a
--- /dev/null
+++ b/spec/services/ci/runners/process_runner_version_update_service_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::Runners::ProcessRunnerVersionUpdateService do
+ subject(:service) { described_class.new(version) }
+
+ let(:version) { '1.0.0' }
+ let(:available_runner_releases) { %w[1.0.0 1.0.1] }
+
+ describe '#execute' do
+ subject(:execute) { service.execute }
+
+ context 'with upgrade check returning error' do
+ let(:service_double) { instance_double(Gitlab::Ci::RunnerUpgradeCheck) }
+
+ before do
+ allow(service_double).to receive(:check_runner_upgrade_suggestion).with(version)
+ .and_return([version, :error])
+ allow(service).to receive(:upgrade_check_service).and_return(service_double)
+ end
+
+ it 'does not update ci_runner_versions records', :aggregate_failures do
+ expect do
+ expect(execute).to be_error
+ expect(execute.message).to eq 'upgrade version check failed'
+ end.not_to change(Ci::RunnerVersion, :count).from(0)
+ expect(service_double).to have_received(:check_runner_upgrade_suggestion).with(version).once
+ end
+ end
+
+ context 'with successful result from upgrade check' do
+ before do
+ url = ::Gitlab::CurrentSettings.current_application_settings.public_runner_releases_url
+
+ WebMock.stub_request(:get, url).to_return(
+ body: available_runner_releases.map { |v| { name: v } }.to_json,
+ status: 200,
+ headers: { 'Content-Type' => 'application/json' }
+ )
+ end
+
+ context 'with no existing ci_runner_version record' do
+ it 'creates ci_runner_versions record', :aggregate_failures do
+ expect do
+ expect(execute).to be_success
+ expect(execute.http_status).to eq :ok
+ expect(execute.payload).to eq({ upgrade_status: 'recommended' })
+ end.to change(Ci::RunnerVersion, :all).to contain_exactly(
+ an_object_having_attributes(version: version, status: 'recommended')
+ )
+ end
+ end
+
+ context 'with existing ci_runner_version record' do
+ let!(:runner_version) { create(:ci_runner_version, version: '1.0.0', status: :not_available) }
+
+ it 'updates ci_runner_versions record', :aggregate_failures do
+ expect do
+ expect(execute).to be_success
+ expect(execute.http_status).to eq :ok
+ expect(execute.payload).to eq({ upgrade_status: 'recommended' })
+ end.to change { runner_version.reload.status }.from('not_available').to('recommended')
+ end
+ end
+
+ context 'with up-to-date ci_runner_version record' do
+ let!(:runner_version) { create(:ci_runner_version, version: '1.0.0', status: :recommended) }
+
+ it 'does not update ci_runner_versions record', :aggregate_failures do
+ expect do
+ expect(execute).to be_success
+ expect(execute.http_status).to eq :ok
+ expect(execute.payload).to eq({ upgrade_status: 'recommended' })
+ end.not_to change { runner_version.reload.status }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/runners/reset_registration_token_service_spec.rb b/spec/services/ci/runners/reset_registration_token_service_spec.rb
index c4bfff51cc8..f96838cea98 100644
--- a/spec/services/ci/runners/reset_registration_token_service_spec.rb
+++ b/spec/services/ci/runners/reset_registration_token_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe ::Ci::Runners::ResetRegistrationTokenService, '#execute' do
- subject { described_class.new(scope, current_user).execute }
+ subject(:execute) { described_class.new(scope, current_user).execute }
let_it_be(:user) { build(:user) }
let_it_be(:admin_user) { create(:user, :admin) }
@@ -12,20 +12,20 @@ RSpec.describe ::Ci::Runners::ResetRegistrationTokenService, '#execute' do
context 'without user' do
let(:current_user) { nil }
- it 'does not reset registration token and returns nil' do
+ it 'does not reset registration token and returns error response' do
expect(scope).not_to receive(token_reset_method_name)
- is_expected.to be_nil
+ is_expected.to be_error
end
end
context 'with unauthorized user' do
let(:current_user) { user }
- it 'does not reset registration token and returns nil' do
+ it 'does not reset registration token and returns error response' do
expect(scope).not_to receive(token_reset_method_name)
- is_expected.to be_nil
+ is_expected.to be_error
end
end
@@ -37,7 +37,8 @@ RSpec.describe ::Ci::Runners::ResetRegistrationTokenService, '#execute' do
expect(scope).to receive(token_method_name).once.and_return("#{token_method_name} return value")
end
- is_expected.to eq("#{token_method_name} return value")
+ is_expected.to be_success
+ expect(execute.payload[:new_registration_token]).to eq("#{token_method_name} return value")
end
end
end
diff --git a/spec/workers/ci/runners/process_runner_version_update_worker_spec.rb b/spec/workers/ci/runners/process_runner_version_update_worker_spec.rb
new file mode 100644
index 00000000000..ff67266c3e8
--- /dev/null
+++ b/spec/workers/ci/runners/process_runner_version_update_worker_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::Runners::ProcessRunnerVersionUpdateWorker do
+ subject(:worker) { described_class.new }
+
+ describe '#perform' do
+ let(:version) { '1.0.0' }
+ let(:job_args) { version }
+
+ include_examples 'an idempotent worker' do
+ subject(:perform_twice) { perform_multiple(job_args, worker: worker, exec_times: 2) }
+
+ let(:service) { ::Ci::Runners::ProcessRunnerVersionUpdateService.new(version) }
+ let(:available_runner_releases) do
+ %w[1.0.0 1.0.1]
+ end
+
+ before do
+ allow(Ci::Runners::ProcessRunnerVersionUpdateService).to receive(:new).and_return(service)
+ allow(service).to receive(:execute).and_call_original
+
+ url = ::Gitlab::CurrentSettings.current_application_settings.public_runner_releases_url
+
+ WebMock.stub_request(:get, url).to_return(
+ body: available_runner_releases.map { |v| { name: v } }.to_json,
+ status: 200,
+ headers: { 'Content-Type' => 'application/json' }
+ )
+ end
+
+ it 'logs the service result', :aggregate_failures do
+ perform_twice
+
+ expect(Ci::Runners::ProcessRunnerVersionUpdateService).to have_received(:new).twice
+ expect(service).to have_received(:execute).twice
+ expect(worker.logging_extras).to eq(
+ {
+ 'extra.ci_runners_process_runner_version_update_worker.status' => :success,
+ 'extra.ci_runners_process_runner_version_update_worker.message' => nil,
+ 'extra.ci_runners_process_runner_version_update_worker.upgrade_status' => 'recommended'
+ }
+ )
+ end
+ end
+ end
+end