diff --git a/.gitlab/ci/build-images.gitlab-ci.yml b/.gitlab/ci/build-images.gitlab-ci.yml index d4a9582ded3bb61b60ddab333f2749d261f057bc..cde1e2b75dbd92d0a4b2a3e9ac43e11ac424c6a3 100644 --- a/.gitlab/ci/build-images.gitlab-ci.yml +++ b/.gitlab/ci/build-images.gitlab-ci.yml @@ -29,6 +29,21 @@ build-qa-image as-if-foss: - .as-if-foss - .build-images:rules:build-qa-image-as-if-foss +retag-gdk-image: + extends: + - .base-image-build + - .build-images:rules:retag-gdk-image + tags: + - docker + stage: build-images + needs: [] + script: + - | + image="registry.gitlab.com/gitlab-org/gitlab-development-kit/asdf-bootstrapped-verify/main" + tag=$(awk '/ARG GDK_SHA=/ {print $2}' qa/gdk/Dockerfile.gdk | sed 's/.*=//g') + skopeo login -u $RETAG_GDK_IMAGE_TOKEN_NAME -p $RETAG_GDK_IMAGE_TOKEN $CI_REGISTRY + skopeo copy docker://${image}:${tag} docker://${image}:stable-${tag} + build-gdk-image: extends: - .base-image-build-buildx @@ -36,7 +51,9 @@ build-gdk-image: tags: - saas-linux-xlarge-amd64 stage: build-images - needs: [] + needs: + - job: retag-gdk-image + optional: true script: - run_timed_command "scripts/build_gdk_image" diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index d8cc67a966a21209499dce5b164014a33e4d35eb..87a02aac70c456ebb29c95dc732ab8ff5372be1d 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -906,6 +906,16 @@ variables: ARCH: amd64,arm64 +# When new minor release tag is pushed, re-tag gdk image with pattern ignored by registry cleanup +.build-images:rules:retag-gdk-image: + rules: + - !reference [".qa:rules:package-and-test-never-run", rules] + - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.0-ee$/ && $CI_PIPELINE_SOURCE == "push"' + # In case gdk base tag is updated via backport mr, make sure we retag it with stable prefix as well + - if: '$CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable-ee$/' + changes: + - qa/gdk/Dockerfile.gdk + # We use a multi-stage image to: # - (re)build the first stage in master pipelines (including scheduled pipelines), and # - build the final stage in code-change pipelines (including MRs), and scheduled pipelines diff --git a/ee/spec/services/groups/compliance_report_csv_service_spec.rb b/ee/spec/services/groups/compliance_report_csv_service_spec.rb index 329024ffadb65d7c5e1750f65d21316e417d8c29..962494cd8af9ed3e31b5ee46ddc276b168852b64 100644 --- a/ee/spec/services/groups/compliance_report_csv_service_spec.rb +++ b/ee/spec/services/groups/compliance_report_csv_service_spec.rb @@ -2,10 +2,11 @@ require 'spec_helper' -RSpec.describe Groups::ComplianceReportCsvService, feature_category: :compliance_management do +RSpec.describe Groups::ComplianceReportCsvService, :freeze_time, feature_category: :compliance_management do subject(:service) { described_class.new(user, group, filters) } - let(:filters) { { from: 10.years.ago, to: Time.current } } + let(:from) { 10.years.ago } + let(:filters) { { from: from, to: Time.current } } let_it_be(:user) { create(:user, name: 'John Cena') } @@ -107,9 +108,9 @@ context 'when verifying the csv data' do let(:all_commits) do - commits = project1.repository.commits(nil, limit: 100).map(&:sha) + - project2.repository.commits(nil, limit: 100).map(&:sha) + - sub_group_project.repository.commits(nil, limit: 100).map(&:sha) + commits = project1.repository.commits(nil, limit: 100, after: from).map(&:sha) + + project2.repository.commits(nil, limit: 100, after: from).map(&:sha) + + sub_group_project.repository.commits(nil, limit: 100, after: from).map(&:sha) commits.sort.uniq end diff --git a/ee/spec/services/security/scan_result_policies/update_approvals_service_spec.rb b/ee/spec/services/security/scan_result_policies/update_approvals_service_spec.rb index 80ca76f176967589fa38fa1d9e80a0675a10e13d..c132eaed8f61a7cde95d1a583b73ade9c1047b51 100644 --- a/ee/spec/services/security/scan_result_policies/update_approvals_service_spec.rb +++ b/ee/spec/services/security/scan_result_policies/update_approvals_service_spec.rb @@ -217,7 +217,7 @@ message: 'Evaluating MR approval rules from scan result policies', pipeline_ids: [pipeline.id], target_pipeline_ids: [target_pipeline.id], - project_path: 'namespace1/project-1' + project_path: project.full_path ).and_call_original expect(::Gitlab::AppJsonLogger) @@ -230,7 +230,7 @@ merge_request_id: merge_request.id, merge_request_iid: merge_request.iid, reason: 'scan_finding rule violated', - project_path: 'namespace1/project-1' + project_path: project.full_path ).and_call_original execute diff --git a/lib/gitlab/sidekiq_config.rb b/lib/gitlab/sidekiq_config.rb index 33a15d95d225d7dcebe25e53784222bdbd8a65c6..b2ff80b235715142874be53ee00bf961250d4af7 100644 --- a/lib/gitlab/sidekiq_config.rb +++ b/lib/gitlab/sidekiq_config.rb @@ -40,6 +40,7 @@ module SidekiqConfig class << self include Gitlab::SidekiqConfig::CliMethods + include Gitlab::Utils::StrongMemoize def redis_queues # Not memoized, because this can change during the life of the application @@ -54,28 +55,27 @@ def config_queues end def cron_jobs - @cron_jobs ||= begin - Gitlab.config.load_dynamic_cron_schedules! - - jobs = Gitlab.config.cron_jobs.to_hash - - jobs.delete('poll_interval') # Would be interpreted as a job otherwise - - # Settingslogic (former gem used for yaml configuration) didn't allow 'class' key - # Therefore, we configure cron jobs with `job_class` as a workaround. - required_keys = %w[job_class cron] - jobs.each do |k, v| - if jobs[k] && required_keys.all? { |s| jobs[k].key?(s) } - jobs[k]['class'] = jobs[k].delete('job_class') - else - jobs.delete(k) - Gitlab::AppLogger.error("Invalid cron_jobs config key: '#{k}'. Check your gitlab config file.") - end - end + Gitlab.config.load_dynamic_cron_schedules! + + jobs = Gitlab.config.cron_jobs.to_hash + + jobs.delete('poll_interval') # Would be interpreted as a job otherwise - jobs + # Settingslogic (former gem used for yaml configuration) didn't allow 'class' key + # Therefore, we configure cron jobs with `job_class` as a workaround. + required_keys = %w[job_class cron] + jobs.each do |k, v| + if jobs[k] && required_keys.all? { |s| jobs[k].key?(s) } + jobs[k]['class'] = jobs[k].delete('job_class') + else + jobs.delete(k) + Gitlab::AppLogger.error("Invalid cron_jobs config key: '#{k}'. Check your gitlab config file.") + end end + + jobs end + strong_memoize_attr :cron_jobs def cron_workers @cron_workers ||= cron_jobs.map { |job_name, options| options['class'].constantize } diff --git a/qa/gdk/Dockerfile.gdk b/qa/gdk/Dockerfile.gdk index 18902b57068a0f62ecb49820b8b4decae0766df1..adf1b330cb7de41b51329039ae4d72a21a932fbf 100644 --- a/qa/gdk/Dockerfile.gdk +++ b/qa/gdk/Dockerfile.gdk @@ -1,4 +1,8 @@ -FROM registry.gitlab.com/gitlab-org/gitlab-development-kit/asdf-bootstrapped-verify:main@sha256:fb833ce8f838e38104ee3b499a99f86e7a5844a4d4d8fdeeababd2d717504f3e as base +ARG GDK_SHA=e8a2f3c30d3031c5574957efbaa917bacdeb3f1a +# Use tag prefix when running on 'stable' branch to make sure 'protected' image is used which is not deleted by registry cleanup +ARG GDK_BASE_TAG_PREFIX + +FROM registry.gitlab.com/gitlab-org/gitlab-development-kit/asdf-bootstrapped-verify/main:${GDK_BASE_TAG_PREFIX}${GDK_SHA} as base ENV GITLAB_LICENSE_MODE=test \ GDK_KILL_CONFIRM=true @@ -53,7 +57,7 @@ RUN set -eux; \ # FROM base as gitlab-gems -COPY --chown=gdk:gdk Gemfile Gemfile.lock ./gitlab/ +COPY --chown=gdk:gdk Gemfile Gemfile.lock .tool-versions ./gitlab/ COPY --chown=gdk:gdk vendor/gems/ ./gitlab/vendor/gems/ COPY --chown=gdk:gdk gems/ ./gitlab/gems/ RUN make .gitlab-bundle \ diff --git a/scripts/build_gdk_image b/scripts/build_gdk_image index cb1dbd03adb4125b2187748583cd65afd4f0cc91..894f888becef18afca61b8290574fd0fe243bfb9 100755 --- a/scripts/build_gdk_image +++ b/scripts/build_gdk_image @@ -7,6 +7,7 @@ source "$(dirname "$0")/utils.sh" REGISTRY="${CI_REGISTRY}/${CI_PROJECT_PATH}" SHA_TAG="${CI_COMMIT_SHA}" BRANCH_TAG="${CI_COMMIT_REF_SLUG}" +STABLE_BRANCH_PATTERN="^[\d-]+-stable-ee$" IMAGE="${REGISTRY}/gitlab-qa-gdk" @@ -16,6 +17,10 @@ else OUTPUT_OPTION="--load" fi +if [[ "$BRANCH_TAG" =~ $STABLE_BRANCH_PATTERN || "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" =~ $STABLE_BRANCH_PATTERN ]]; then + GDK_BASE_TAG_PREFIX="stable-" +fi + echoinfo "Building GDK image" "yes" docker buildx build \ @@ -24,6 +29,7 @@ docker buildx build \ --cache-from="${IMAGE}/cache:master" \ --file="qa/gdk/Dockerfile.gdk" \ --platform=${ARCH:-amd64} \ + --build-arg "GDK_BASE_TAG_PREFIX=${GDK_BASE_TAG_PREFIX}" \ --tag="${IMAGE}:${SHA_TAG}" \ --tag="${IMAGE}:${BRANCH_TAG}" \ ${OUTPUT_OPTION} \ diff --git a/spec/initializers/sidekiq_spec.rb b/spec/initializers/sidekiq_spec.rb index a034e628d25972a5530760434bbdbc711f5d9bb4..fb1377244d207bef2327578032d89ed09050e4ee 100644 --- a/spec/initializers/sidekiq_spec.rb +++ b/spec/initializers/sidekiq_spec.rb @@ -78,11 +78,13 @@ end around do |example| + Gitlab::SidekiqConfig.clear_memoization(:cron_jobs) original_settings = Gitlab.config['cron_jobs'] Gitlab.config['cron_jobs'] = cron_jobs_settings example.run + Gitlab::SidekiqConfig.clear_memoization(:cron_jobs) Gitlab.config['cron_jobs'] = original_settings end diff --git a/spec/lib/gitlab/sidekiq_config_spec.rb b/spec/lib/gitlab/sidekiq_config_spec.rb index 00b1666106f5c8cb73324e4ef962254556d67e6e..5885151ecb58c2bbe72bdb3ab87fc7bc3dcbc4d3 100644 --- a/spec/lib/gitlab/sidekiq_config_spec.rb +++ b/spec/lib/gitlab/sidekiq_config_spec.rb @@ -18,6 +18,14 @@ end describe '.cron_jobs' do + around do |example| + described_class.clear_memoization(:cron_jobs) + + example.run + + described_class.clear_memoization(:cron_jobs) + end + it 'renames job_class to class and removes incomplete jobs' do expect(Gitlab) .to receive(:config)