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:
Diffstat (limited to 'app/models/ci')
-rw-r--r--app/models/ci/bridge.rb9
-rw-r--r--app/models/ci/build.rb90
-rw-r--r--app/models/ci/build_metadata.rb1
-rw-r--r--app/models/ci/build_trace_metadata.rb4
-rw-r--r--app/models/ci/deleted_object.rb4
-rw-r--r--app/models/ci/job_artifact.rb67
-rw-r--r--app/models/ci/pipeline.rb104
-rw-r--r--app/models/ci/processable.rb2
-rw-r--r--app/models/ci/runner.rb17
-rw-r--r--app/models/ci/runner_version.rb4
-rw-r--r--app/models/ci/secure_file.rb6
11 files changed, 204 insertions, 104 deletions
diff --git a/app/models/ci/bridge.rb b/app/models/ci/bridge.rb
index 13af5b1f8d1..3fda8693a58 100644
--- a/app/models/ci/bridge.rb
+++ b/app/models/ci/bridge.rb
@@ -19,7 +19,7 @@ module Ci
belongs_to :project
belongs_to :trigger_request
has_many :sourced_pipelines, class_name: "::Ci::Sources::Pipeline",
- foreign_key: :source_job_id
+ foreign_key: :source_job_id
has_one :sourced_pipeline, class_name: "::Ci::Sources::Pipeline", foreign_key: :source_job_id
has_one :downstream_pipeline, through: :sourced_pipeline, source: :pipeline
@@ -114,7 +114,12 @@ module Ci
def downstream_project_path
strong_memoize(:downstream_project_path) do
- options&.dig(:trigger, :project)
+ project = options&.dig(:trigger, :project)
+ next unless project
+
+ scoped_variables.to_runner_variables.yield_self do |all_variables|
+ ::ExpandVariables.expand(project, all_variables)
+ end
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 7f9697d0424..bf8817e6e78 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -194,7 +194,7 @@ module Ci
after_save :stick_build_if_status_changed
after_create unless: :importing? do |build|
- run_after_commit { BuildHooksWorker.perform_async(build) }
+ run_after_commit { build.feature_flagged_execute_hooks }
end
class << self
@@ -285,7 +285,7 @@ module Ci
build.run_after_commit do
BuildQueueWorker.perform_async(id)
- BuildHooksWorker.perform_async(build)
+ build.feature_flagged_execute_hooks
end
end
@@ -313,7 +313,7 @@ module Ci
build.run_after_commit do
build.ensure_persistent_ref
- BuildHooksWorker.perform_async(build)
+ build.feature_flagged_execute_hooks
end
end
@@ -322,6 +322,8 @@ module Ci
build.run_status_commit_hooks!
Ci::BuildFinishedWorker.perform_async(id)
+
+ observe_report_types
end
end
@@ -340,8 +342,8 @@ module Ci
# rubocop: disable CodeReuse/ServiceClass
Ci::RetryJobService.new(build.project, build.user).execute(build)
# rubocop: enable CodeReuse/ServiceClass
- rescue Gitlab::Access::AccessDeniedError => ex
- Gitlab::AppLogger.error "Unable to auto-retry job #{build.id}: #{ex}"
+ rescue Gitlab::Access::AccessDeniedError => e
+ Gitlab::AppLogger.error "Unable to auto-retry job #{build.id}: #{e}"
end
end
end
@@ -490,11 +492,7 @@ module Ci
if metadata&.expanded_environment_name.present?
metadata.expanded_environment_name
else
- if ::Feature.enabled?(:ci_expand_environment_name_and_url, project)
- ExpandVariables.expand(environment, -> { simple_variables.sort_and_expand_all })
- else
- ExpandVariables.expand(environment, -> { simple_variables })
- end
+ ExpandVariables.expand(environment, -> { simple_variables.sort_and_expand_all })
end
end
end
@@ -527,10 +525,14 @@ module Ci
self.options.fetch(:environment, {}).fetch(:action, 'start') if self.options
end
- def environment_deployment_tier
+ def environment_tier_from_options
self.options.dig(:environment, :deployment_tier) if self.options
end
+ def environment_tier
+ environment_tier_from_options || persisted_environment.try(:tier)
+ end
+
def triggered_by?(current_user)
user == current_user
end
@@ -585,6 +587,7 @@ module Ci
variables.concat(persisted_environment.predefined_variables)
variables.append(key: 'CI_ENVIRONMENT_ACTION', value: environment_action)
+ variables.append(key: 'CI_ENVIRONMENT_TIER', value: environment_tier)
# Here we're passing unexpanded environment_url for runner to expand,
# and we need to make sure that CI_ENVIRONMENT_NAME and
@@ -777,10 +780,20 @@ module Ci
pending? && !any_runners_online?
end
+ def feature_flagged_execute_hooks
+ if Feature.enabled?(:execute_build_hooks_inline, project)
+ execute_hooks
+ else
+ BuildHooksWorker.perform_async(self)
+ end
+ end
+
def execute_hooks
return unless project
return if user&.blocked?
+ ActiveRecord::Associations::Preloader.new.preload([self], { runner: :tags })
+
project.execute_hooks(build_data.dup, :job_hooks) if project.has_active_hooks?(:job_hooks)
project.execute_integrations(build_data.dup, :job_hooks) if project.has_active_integrations?(:job_hooks)
end
@@ -818,7 +831,11 @@ module Ci
)
end
- job_artifacts.erasable.destroy_all # rubocop: disable Cop/DestroyAll
+ destroyed_artifacts = job_artifacts.erasable.destroy_all # rubocop: disable Cop/DestroyAll
+
+ Gitlab::Ci::Artifacts::Logger.log_deleted(destroyed_artifacts, 'Ci::Build#erase_erasable_artifacts!')
+
+ destroyed_artifacts
end
def erase(opts = {})
@@ -831,7 +848,12 @@ module Ci
)
end
- job_artifacts.destroy_all # rubocop: disable Cop/DestroyAll
+ # TODO: We should use DestroyBatchService here
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/369132
+ destroyed_artifacts = job_artifacts.destroy_all # rubocop: disable Cop/DestroyAll
+
+ Gitlab::Ci::Artifacts::Logger.log_deleted(destroyed_artifacts, 'Ci::Build#erase')
+
erase_trace!
update_erased!(opts[:erased_by])
end
@@ -983,7 +1005,7 @@ module Ci
def collect_test_reports!(test_reports)
test_reports.get_suite(test_suite_name).tap do |test_suite|
- each_report(Ci::JobArtifact::TEST_REPORT_FILE_TYPES) do |file_type, blob|
+ each_report(Ci::JobArtifact.file_types_for_report(:test)) do |file_type, blob|
Gitlab::Ci::Parsers.fabricate!(file_type).parse!(
blob,
test_suite,
@@ -994,7 +1016,7 @@ module Ci
end
def collect_accessibility_reports!(accessibility_report)
- each_report(Ci::JobArtifact::ACCESSIBILITY_REPORT_FILE_TYPES) do |file_type, blob|
+ each_report(Ci::JobArtifact.file_types_for_report(:accessibility)) do |file_type, blob|
Gitlab::Ci::Parsers.fabricate!(file_type).parse!(blob, accessibility_report)
end
@@ -1002,7 +1024,7 @@ module Ci
end
def collect_codequality_reports!(codequality_report)
- each_report(Ci::JobArtifact::CODEQUALITY_REPORT_FILE_TYPES) do |file_type, blob|
+ each_report(Ci::JobArtifact.file_types_for_report(:codequality)) do |file_type, blob|
Gitlab::Ci::Parsers.fabricate!(file_type).parse!(blob, codequality_report)
end
@@ -1010,7 +1032,7 @@ module Ci
end
def collect_terraform_reports!(terraform_reports)
- each_report(::Ci::JobArtifact::TERRAFORM_REPORT_FILE_TYPES) do |file_type, blob, report_artifact|
+ each_report(::Ci::JobArtifact.file_types_for_report(:terraform)) do |file_type, blob, report_artifact|
::Gitlab::Ci::Parsers.fabricate!(file_type).parse!(blob, terraform_reports, artifact: report_artifact)
end
@@ -1079,7 +1101,10 @@ module Ci
end
def drop_with_exit_code!(failure_reason, exit_code)
- drop!(::Gitlab::Ci::Build::Status::Reason.new(self, failure_reason, exit_code))
+ failure_reason ||= :unknown_failure
+ result = drop!(::Gitlab::Ci::Build::Status::Reason.new(self, failure_reason, exit_code))
+ ::Ci::TrackFailedBuildWorker.perform_async(id, exit_code, failure_reason)
+ result
end
def exit_codes_defined?
@@ -1149,6 +1174,21 @@ module Ci
end
end
+ def clone(current_user:, new_job_variables_attributes: [])
+ new_build = super
+
+ if action? && new_job_variables_attributes.any?
+ new_build.job_variables = []
+ new_build.job_variables_attributes = new_job_variables_attributes
+ end
+
+ new_build
+ end
+
+ def job_artifact_types
+ job_artifacts.map(&:file_type)
+ end
+
protected
def run_status_commit_hooks!
@@ -1256,6 +1296,20 @@ module Ci
expires_in: RUNNERS_STATUS_CACHE_EXPIRATION
) { yield }
end
+
+ def observe_report_types
+ return unless ::Gitlab.com? && Feature.enabled?(:report_artifact_build_completed_metrics_on_build_completion)
+
+ report_types = options&.dig(:artifacts, :reports)&.keys || []
+
+ report_types.each do |report_type|
+ next unless Ci::JobArtifact::REPORT_TYPES.include?(report_type)
+
+ ::Gitlab::Ci::Artifacts::Metrics
+ .build_completed_report_type_counter(report_type)
+ .increment(status: status)
+ end
+ end
end
end
diff --git a/app/models/ci/build_metadata.rb b/app/models/ci/build_metadata.rb
index 4ee661d89f4..5fc21ba3f28 100644
--- a/app/models/ci/build_metadata.rb
+++ b/app/models/ci/build_metadata.rb
@@ -19,6 +19,7 @@ module Ci
before_create :set_build_project
validates :build, presence: true
+ validates :id_tokens, json_schema: { filename: 'build_metadata_id_tokens' }
validates :secrets, json_schema: { filename: 'build_metadata_secrets' }
serialize :config_options, Serializers::SymbolizedJson # rubocop:disable Cop/ActiveRecordSerialize
diff --git a/app/models/ci/build_trace_metadata.rb b/app/models/ci/build_trace_metadata.rb
index 1ffa0e31f99..86de90983ff 100644
--- a/app/models/ci/build_trace_metadata.rb
+++ b/app/models/ci/build_trace_metadata.rb
@@ -39,8 +39,8 @@ module Ci
def track_archival!(trace_artifact_id, checksum)
update!(trace_artifact_id: trace_artifact_id,
- checksum: checksum,
- archived_at: Time.current)
+ checksum: checksum,
+ archived_at: Time.current)
end
def archival_attempts_message
diff --git a/app/models/ci/deleted_object.rb b/app/models/ci/deleted_object.rb
index aba7b73aba9..d36646aba66 100644
--- a/app/models/ci/deleted_object.rb
+++ b/app/models/ci/deleted_object.rb
@@ -27,8 +27,8 @@ module Ci
def delete_file_from_storage
file.remove!
true
- rescue StandardError => exception
- Gitlab::ErrorTracking.track_exception(exception)
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_exception(e)
false
end
end
diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb
index ee7175a4f69..71d33f0bb63 100644
--- a/app/models/ci/job_artifact.rb
+++ b/app/models/ci/job_artifact.rb
@@ -13,14 +13,19 @@ module Ci
include EachBatch
include Gitlab::Utils::StrongMemoize
- TEST_REPORT_FILE_TYPES = %w[junit].freeze
- COVERAGE_REPORT_FILE_TYPES = %w[cobertura].freeze
- CODEQUALITY_REPORT_FILE_TYPES = %w[codequality].freeze
- ACCESSIBILITY_REPORT_FILE_TYPES = %w[accessibility].freeze
NON_ERASABLE_FILE_TYPES = %w[trace].freeze
- TERRAFORM_REPORT_FILE_TYPES = %w[terraform].freeze
- SAST_REPORT_TYPES = %w[sast].freeze
- SECRET_DETECTION_REPORT_TYPES = %w[secret_detection].freeze
+
+ REPORT_FILE_TYPES = {
+ sast: %w[sast],
+ secret_detection: %w[secret_detection],
+ test: %w[junit],
+ accessibility: %w[accessibility],
+ coverage: %w[cobertura],
+ codequality: %w[codequality],
+ terraform: %w[terraform],
+ sbom: %w[cyclonedx]
+ }.freeze
+
DEFAULT_FILE_NAMES = {
archive: nil,
metadata: nil,
@@ -48,7 +53,8 @@ module Ci
cluster_applications: 'gl-cluster-applications.json', # DEPRECATED: https://gitlab.com/gitlab-org/gitlab/-/issues/361094
requirements: 'requirements.json',
coverage_fuzzing: 'gl-coverage-fuzzing.json',
- api_fuzzing: 'gl-api-fuzzing-report.json'
+ api_fuzzing: 'gl-api-fuzzing-report.json',
+ cyclonedx: 'gl-sbom.cdx.zip'
}.freeze
INTERNAL_TYPES = {
@@ -88,7 +94,8 @@ module Ci
terraform: :raw,
requirements: :raw,
coverage_fuzzing: :raw,
- api_fuzzing: :raw
+ api_fuzzing: :raw,
+ cyclonedx: :zip
}.freeze
DOWNLOADABLE_TYPES = %w[
@@ -112,6 +119,7 @@ module Ci
secret_detection
requirements
cluster_image_scanning
+ cyclonedx
].freeze
TYPE_AND_FORMAT_PAIRS = INTERNAL_TYPES.merge(REPORT_TYPES).freeze
@@ -152,36 +160,14 @@ module Ci
where(file_type: types)
end
- scope :all_reports, -> do
- with_file_types(REPORT_TYPES.keys.map(&:to_s))
- end
-
- scope :sast_reports, -> do
- with_file_types(SAST_REPORT_TYPES)
- end
-
- scope :secret_detection_reports, -> do
- with_file_types(SECRET_DETECTION_REPORT_TYPES)
- end
-
- scope :test_reports, -> do
- with_file_types(TEST_REPORT_FILE_TYPES)
- end
-
- scope :accessibility_reports, -> do
- with_file_types(ACCESSIBILITY_REPORT_FILE_TYPES)
- end
-
- scope :coverage_reports, -> do
- with_file_types(COVERAGE_REPORT_FILE_TYPES)
- end
-
- scope :codequality_reports, -> do
- with_file_types(CODEQUALITY_REPORT_FILE_TYPES)
+ REPORT_FILE_TYPES.each do |report_type, file_types|
+ scope "#{report_type}_reports", -> do
+ with_file_types(file_types)
+ end
end
- scope :terraform_reports, -> do
- with_file_types(TERRAFORM_REPORT_FILE_TYPES)
+ scope :all_reports, -> do
+ with_file_types(REPORT_TYPES.keys.map(&:to_s))
end
scope :erasable, -> do
@@ -225,7 +211,8 @@ module Ci
browser_performance: 24, ## EE-specific
load_performance: 25, ## EE-specific
api_fuzzing: 26, ## EE-specific
- cluster_image_scanning: 27 ## EE-specific
+ cluster_image_scanning: 27, ## EE-specific
+ cyclonedx: 28 ## EE-specific
}
# `file_location` indicates where actual files are stored.
@@ -259,6 +246,10 @@ module Ci
end
end
+ def self.file_types_for_report(report_type)
+ REPORT_FILE_TYPES.fetch(report_type)
+ end
+
def self.associated_file_types_for(file_type)
return unless file_types.include?(file_type)
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 95c6da4a7af..a94330270e2 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -52,15 +52,15 @@ module Ci
belongs_to :ci_ref, class_name: 'Ci::Ref', foreign_key: :ci_ref_id, inverse_of: :pipelines
has_internal_id :iid, scope: :project, presence: false,
- track_if: -> { !importing? },
- ensure_if: -> { !importing? },
- init: ->(pipeline, scope) do
- if pipeline
- pipeline.project&.all_pipelines&.maximum(:iid) || pipeline.project&.all_pipelines&.count
- elsif scope
- ::Ci::Pipeline.where(**scope).maximum(:iid)
- end
- end
+ track_if: -> { !importing? },
+ ensure_if: -> { !importing? },
+ init: ->(pipeline, scope) do
+ if pipeline
+ pipeline.project&.all_pipelines&.maximum(:iid) || pipeline.project&.all_pipelines&.count
+ elsif scope
+ ::Ci::Pipeline.where(**scope).maximum(:iid)
+ end
+ end
has_many :stages, -> { order(position: :asc) }, inverse_of: :pipeline
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
@@ -102,6 +102,7 @@ module Ci
has_one :chat_data, class_name: 'Ci::PipelineChatData'
has_many :triggered_pipelines, through: :sourced_pipelines, source: :pipeline
+ # Only includes direct and not nested children
has_many :child_pipelines, -> { merge(Ci::Sources::Pipeline.same_project) }, through: :sourced_pipelines, source: :pipeline
has_one :triggered_by_pipeline, through: :source_pipeline, source: :source_pipeline
has_one :parent_pipeline, -> { merge(Ci::Sources::Pipeline.same_project) }, through: :source_pipeline, source: :source_pipeline
@@ -389,7 +390,7 @@ module Ci
end
def self.latest_status(ref = nil)
- newest_first(ref: ref).pluck(:status).first
+ newest_first(ref: ref).pick(:status)
end
def self.latest_successful_for_ref(ref)
@@ -592,26 +593,20 @@ module Ci
canceled? && auto_canceled_by_id?
end
- def cancel_running(retries: 1)
- preloaded_relations = [:project, :pipeline, :deployment, :taggings]
-
- retry_lock(cancelable_statuses, retries, name: 'ci_pipeline_cancel_running') do |cancelables|
- cancelables.find_in_batches do |batch|
- Preloaders::CommitStatusPreloader.new(batch).execute(preloaded_relations)
-
- batch.each do |job|
- yield(job) if block_given?
- job.cancel
- end
- end
- end
- end
+ # Cancel a pipelines cancelable jobs and optionally it's child pipelines cancelable jobs
+ # retries - # of times to retry if errors
+ # cascade_to_children - if true cancels all related child pipelines for parent child pipelines
+ # auto_canceled_by_pipeline_id - store the pipeline_id of the pipeline that triggered cancellation
+ # execute_async - if true cancel the children asyncronously
+ def cancel_running(retries: 1, cascade_to_children: true, auto_canceled_by_pipeline_id: nil, execute_async: true)
+ update(auto_canceled_by_id: auto_canceled_by_pipeline_id) if auto_canceled_by_pipeline_id
- def auto_cancel_running(pipeline, retries: 1)
- update(auto_canceled_by: pipeline)
+ cancel_jobs(cancelable_statuses, retries: retries, auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id)
- cancel_running(retries: retries) do |job|
- job.auto_canceled_by = pipeline
+ if cascade_to_children
+ # cancel any bridges that could spin up new child pipelines
+ cancel_jobs(bridges_in_self_and_descendants.cancelable, retries: retries, auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id)
+ cancel_children(auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id, execute_async: execute_async)
end
end
@@ -953,6 +948,10 @@ module Ci
Ci::Build.latest.where(pipeline: self_and_descendants)
end
+ def bridges_in_self_and_descendants
+ Ci::Bridge.latest.where(pipeline: self_and_descendants)
+ end
+
def environments_in_self_and_descendants(deployment_status: nil)
# We limit to 100 unique environments for application safety.
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/340781#note_699114700
@@ -986,6 +985,11 @@ module Ci
object_hierarchy(project_condition: :same).base_and_descendants
end
+ # With only parent-child pipelines
+ def all_child_pipelines
+ object_hierarchy(project_condition: :same).descendants
+ end
+
def self_and_descendants_complete?
self_and_descendants.all?(&:complete?)
end
@@ -1152,6 +1156,10 @@ module Ci
end
end
+ def modified_paths_since(compare_to_sha)
+ project.repository.diff_stats(project.repository.merge_base(compare_to_sha, sha), sha).paths
+ end
+
def all_worktree_paths
strong_memoize(:all_worktree_paths) do
project.repository.ls_files(sha)
@@ -1216,10 +1224,6 @@ module Ci
stages.find_by(name: name)
end
- def find_stage_by_name!(name)
- stages.find_by!(name: name)
- end
-
def full_error_messages
errors ? errors.full_messages.to_sentence : ""
end
@@ -1321,6 +1325,42 @@ module Ci
private
+ def cancel_jobs(jobs, retries: 1, auto_canceled_by_pipeline_id: nil)
+ retry_lock(jobs, retries, name: 'ci_pipeline_cancel_running') do |statuses|
+ preloaded_relations = [:project, :pipeline, :deployment, :taggings]
+
+ statuses.find_in_batches do |status_batch|
+ relation = CommitStatus.where(id: status_batch)
+ Preloaders::CommitStatusPreloader.new(relation).execute(preloaded_relations)
+
+ relation.each do |job|
+ job.auto_canceled_by_id = auto_canceled_by_pipeline_id if auto_canceled_by_pipeline_id
+ job.cancel
+ end
+ end
+ end
+ end
+
+ # For parent child-pipelines only (not multi-project)
+ def cancel_children(auto_canceled_by_pipeline_id: nil, execute_async: true)
+ all_child_pipelines.each do |child_pipeline|
+ if execute_async
+ ::Ci::CancelPipelineWorker.perform_async(
+ child_pipeline.id,
+ auto_canceled_by_pipeline_id
+ )
+ else
+ child_pipeline.cancel_running(
+ # cascade_to_children is false because we iterate through children
+ # we also cancel bridges prior to prevent more children
+ cascade_to_children: false,
+ execute_async: execute_async,
+ auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id
+ )
+ end
+ end
+ end
+
def add_message(severity, content)
messages.build(severity: severity, content: content)
end
diff --git a/app/models/ci/processable.rb b/app/models/ci/processable.rb
index f666629c8fd..a2ff49077be 100644
--- a/app/models/ci/processable.rb
+++ b/app/models/ci/processable.rb
@@ -101,7 +101,7 @@ module Ci
:merge_train_pipeline?,
to: :pipeline
- def clone(current_user:)
+ def clone(current_user:, new_job_variables_attributes: [])
new_attributes = self.class.clone_accessors.to_h do |attribute|
[attribute, public_send(attribute)] # rubocop:disable GitlabSecurity/PublicSend
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index f41ad890184..6c3754d84d0 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -15,7 +15,7 @@ module Ci
include Presentable
include EachBatch
- ignore_column :semver, remove_with: '15.3', remove_after: '2022-07-22'
+ ignore_column :semver, remove_with: '15.4', remove_after: '2022-08-22'
add_authentication_token_field :token, encrypted: :optional, expires_at: :compute_token_expiration, expiration_enforced?: :token_expiration_enforced?
@@ -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
@@ -477,7 +482,7 @@ module Ci
private
scope :with_upgrade_status, ->(upgrade_status) do
- Ci::Runner.joins(:runner_version).where(runner_version: { status: upgrade_status })
+ joins(:runner_version).where(runner_version: { status: upgrade_status })
end
EXECUTOR_NAME_TO_TYPES = {
@@ -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/models/ci/runner_version.rb b/app/models/ci/runner_version.rb
index 6b2d0060c9b..bbde98ee591 100644
--- a/app/models/ci/runner_version.rb
+++ b/app/models/ci/runner_version.rb
@@ -8,7 +8,6 @@ module Ci
enum_with_nil status: {
not_processed: nil,
invalid_version: -1,
- unknown: 0,
not_available: 1,
available: 2,
recommended: 3
@@ -16,7 +15,6 @@ module Ci
STATUS_DESCRIPTIONS = {
invalid_version: 'Runner version is not valid.',
- unknown: 'Upgrade status is unknown.',
not_available: 'Upgrade is not available for the runner.',
available: 'Upgrade is available for the runner.',
recommended: 'Upgrade is available and recommended for the runner.'
@@ -27,7 +25,7 @@ module Ci
# This scope returns all versions that might need recalculating. For instance, once a version is considered
# :recommended, it normally doesn't change status even if the instance is upgraded
- scope :potentially_outdated, -> { where(status: [nil, :not_available, :available, :unknown]) }
+ scope :potentially_outdated, -> { where(status: [nil, :not_available, :available]) }
validates :version, length: { maximum: 2048 }
end
diff --git a/app/models/ci/secure_file.rb b/app/models/ci/secure_file.rb
index 078b05ff779..9a35f1876c9 100644
--- a/app/models/ci/secure_file.rb
+++ b/app/models/ci/secure_file.rb
@@ -3,11 +3,8 @@
module Ci
class SecureFile < Ci::ApplicationRecord
include FileStoreMounter
- include IgnorableColumns
include Limitable
- ignore_column :permissions, remove_with: '15.2', remove_after: '2022-06-22'
-
FILE_SIZE_LIMIT = 5.megabytes.freeze
CHECKSUM_ALGORITHM = 'sha256'
@@ -24,6 +21,7 @@ module Ci
before_validation :assign_checksum
scope :order_by_created_at, -> { order(created_at: :desc) }
+ scope :project_id_in, ->(ids) { where(project_id: ids) }
default_value_for(:file_store) { Ci::SecureFileUploader.default_store }
@@ -46,3 +44,5 @@ module Ci
end
end
end
+
+Ci::SecureFile.prepend_mod