# frozen_string_literal: true module Gitlab module Pages class DeploymentUpdate include ActiveModel::Validations PUBLIC_DIR = 'public' validate :validate_state, unless: -> { errors.any? } validate :validate_outdated_sha, unless: -> { errors.any? } validate :validate_max_size, unless: -> { errors.any? } validate :validate_public_folder, unless: -> { errors.any? } validate :validate_max_entries, unless: -> { errors.any? } def initialize(project, build) @project = project @build = build end def latest? # check if sha for the ref is still the most recent one # this helps in case when multiple deployments happens sha == latest_sha end def entries_count # we're using the full archive and pages daemon needs to read it # so we want the total count from entries, not only "public/" directory # because it better approximates work we need to do before we can serve the site @entries_count = build.artifacts_metadata_entry("", recursive: true).entries.count end private attr_reader :build, :project def validate_state errors.add(:base, 'missing pages artifacts') unless build.artifacts? errors.add(:base, 'missing artifacts metadata') unless build.artifacts_metadata? end def validate_max_size if total_size > max_size errors.add(:base, "artifacts for pages are too large: #{total_size}") end end # Calculate page size after extract def total_size @total_size ||= build.artifacts_metadata_entry(PUBLIC_DIR + '/', recursive: true).total_size end def max_size_from_settings Gitlab::CurrentSettings.max_pages_size.megabytes end def max_size max_pages_size = max_size_from_settings return ::Gitlab::Pages::MAX_SIZE if max_pages_size == 0 max_pages_size end def validate_max_entries if pages_file_entries_limit > 0 && entries_count > pages_file_entries_limit errors.add( :base, "pages site contains #{entries_count} file entries, while limit is set to #{pages_file_entries_limit}" ) end end def validate_public_folder if total_size <= 0 errors.add(:base, 'Error: The `public/` folder is missing, or not declared in `.gitlab-ci.yml`.') end end def pages_file_entries_limit project.actual_limits.pages_file_entries end def validate_outdated_sha return if latest? # use pipeline_id in case the build is retried last_deployed_pipeline_id = project.pages_metadatum&.pages_deployment&.ci_build&.pipeline_id return unless last_deployed_pipeline_id return if last_deployed_pipeline_id <= build.pipeline_id errors.add(:base, 'build SHA is outdated for this ref') end def latest_sha project.commit(build.ref).try(:sha).to_s ensure # Close any file descriptors that were opened and free libgit2 buffers project.cleanup end def sha build.sha end end end end Gitlab::Pages::DeploymentUpdate.prepend_mod_with('Gitlab::Pages::DeploymentUpdate')