Skip to content

Commit

Permalink
Move all builds page to use the Build model (#667)
Browse files Browse the repository at this point in the history
  • Loading branch information
nid90 authored Dec 17, 2024
1 parent 2ac859e commit d9cfd85
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 138 deletions.
22 changes: 3 additions & 19 deletions app/components/all_builds_table_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@
</div>
</th>

<% if external_release_status? %>
<th class="px-2 py-3 whitespace-nowrap">
<div class="font-semibold text-left">
<%= sort_link(column: "external_release_status", label: "External Status") %>
</div>
</th>
<% end %>

<th class="px-2 py-3 whitespace-nowrap">
<div class="font-semibold text-left">
<div class="font-semibold text-left">
Expand All @@ -50,7 +42,7 @@

<th class="px-2 py-3 whitespace-nowrap">
<div class="font-semibold text-left">
<%= sort_link(column: "step_name", label: "Step") %>
<%= sort_link(column: "kind", label: "Kind") %>
</div>
</th>

Expand Down Expand Up @@ -91,14 +83,6 @@
</div>
</td>

<% if external_release_status? %>
<td class="px-2 py-3 whitespace-nowrap">
<div class="text-left">
<%= external_release_status(build) %>
</div>
</td>
<% end %>

<td class="px-2 py-3 whitespace-nowrap">
<div class="text-left">
<%= time_format build.built_at, with_year: true %>
Expand All @@ -119,13 +103,13 @@

<td class="px-2 py-3 whitespace-nowrap">
<div class="text-left">
<%= build.step_name %>
<%= build.kind.humanize %>
</div>
</td>

<td class="px-2 py-3 whitespace-nowrap">
<div class="text-left">
<%= deployments(build) %>
<%= submissions(build) %>
</div>
</td>

Expand Down
10 changes: 7 additions & 3 deletions app/components/all_builds_table_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ def external_release_status(build)
status_badge(build.external_release_status.titleize.humanize, %w[mx-1], :routine)
end

def deployments(build)
def submissions(build)
tag.div do
build.deployments.collect do |d|
concat tag.div show_deployment(d)
if build.submissions.blank?
concat "–"
else
build.submissions.collect do |submission|
concat tag.div submission.submission_info
end
end
end
end
Expand Down
118 changes: 27 additions & 91 deletions app/libs/queries/builds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,15 @@ class Queries::Builds
DEFAULT_SORT_COLUMN = "version_code"

BASE_ATTR_MAPPING = {
version_code: StepRun.arel_table[:build_number],
version_name: StepRun.arel_table[:build_version],
ci_link: StepRun.arel_table[:ci_link],
step_status: StepRun.arel_table[:status],
step_name: Step.arel_table[:name],
version_code: Arel::Nodes::NamedFunction.new("CAST", [Build.arel_table[:build_number].as("integer")]),
version_name: Build.arel_table[:version_name],
ci_link: WorkflowRun.arel_table[:external_url],
train_name: Train.arel_table[:name],
platform: ReleasePlatform.arel_table[:platform],
release_status: ReleasePlatformRun.arel_table[:status]
release_status: ReleasePlatformRun.arel_table[:status],
built_at: Build.arel_table[:generated_at],
kind: WorkflowRun.arel_table[:kind]
}
ANDROID_ATTR_MAPPING =
BASE_ATTR_MAPPING.merge(built_at: BuildArtifact.arel_table[:generated_at])
IOS_ATTR_MAPPING =
BASE_ATTR_MAPPING
.merge(built_at: ExternalRelease.arel_table[:added_at], external_release_status: ExternalRelease.arel_table[:status])

def self.all(**params)
new(**params).all
Expand All @@ -34,91 +29,44 @@ def initialize(app:, params:)
end

attr_reader :app, :sort_column, :sort_direction, :params
delegate :android?, :ios?, :cross_platform?, to: :app

def all
return android_all if android?
return ios_all if ios?
android_all + ios_all if cross_platform?
end

def count
return android_records.size if android?
return ios_records.size if ios?
android_records.size + ios_records.size if cross_platform?
end

def android_all
selected_android_records.to_a.map do |record|
deployments = record.step_run.deployment_runs.map(&:deployment)
selected_records
.to_a
.map do |record|
attributes =
record
.attributes
.with_indifferent_access
.merge(download_url: record.download_url)
.merge(deployments: deployments)
.except(:id, :step_run_id)
.merge(download_url: record.artifact&.download_url)
.merge(submissions: record.store_submissions.order(created_at: :asc).filter(&:finished?).map(&:conf))
.except(:id, :workflow_run_id)

Queries::Build.new(attributes)
end
end

memoize def selected_android_records
android_records
.select(select_attrs(ANDROID_ATTR_MAPPING))
.order(params.sort)
.limit(params.limit)
.offset(params.offset)
end

memoize def android_records
BuildArtifact
.with_attached_file
.joins(join_step_run_tree)
.includes(step_run: {step: [deployments: :integration]})
.select(:id, :step_run_id)
.where(apps: {id: app.id})
.where(ActiveRecord::Base.sanitize_sql_for_conditions(params.search_by(search_params)))
.where(ActiveRecord::Base.sanitize_sql_for_conditions(params.filter_by(ANDROID_ATTR_MAPPING)))
end

def ios_all
selected_ios_records.to_a.map do |record|
attributes =
record
.attributes
.with_indifferent_access
.merge(deployments: ios_deployments(record))
.except(:id, :deployment_run_ids)

Queries::Build.new(attributes)
end
def count
selected_records.size
end

memoize def selected_ios_records
ios_records
.select(select_attrs(IOS_ATTR_MAPPING.except(:version_code)))
memoize def selected_records
records
.select(select_attrs(BASE_ATTR_MAPPING))
.order(params.sort)
.limit(params.limit)
.offset(params.offset)
end

memoize def ios_records
ExternalRelease
.joins(deployment_run: [join_step_run_tree])
.select("DISTINCT (external_releases.build_number) AS version_code")
.select(distinct_deployment_runs)
memoize def records
Build
.ready
.joins(:workflow_run, release_platform_run: [{release_platform: [train: :app]}])
.includes(:store_submissions)
.select(:id, :workflow_run_id)
.where(apps: {id: app.id})
.where(ActiveRecord::Base.sanitize_sql_for_conditions(params.search_by(search_params)))
.where(ActiveRecord::Base.sanitize_sql_for_conditions(params.filter_by(IOS_ATTR_MAPPING)))
end

def ios_deployments(record)
ios_deployment_runs.filter { |dr| dr.id.in?(record.deployment_run_ids) }.map(&:deployment)
end

memoize def ios_deployment_runs
DeploymentRun.for_ids(selected_ios_records.flat_map(&:deployment_run_ids))
.where(ActiveRecord::Base.sanitize_sql_for_conditions(params.filter_by(BASE_ATTR_MAPPING)))
end

class Queries::Build
Expand All @@ -131,12 +79,10 @@ class Queries::Build
attribute :train_name, :string
attribute :platform, :string
attribute :release_status, :string
attribute :step_name, :string
attribute :step_status, :string
attribute :kind, :string
attribute :ci_link, :string
attribute :download_url, :string
attribute :deployments, array: true, default: []
attribute :external_release_status, :string
attribute :submissions, array: true, default: []

def inspect
format(
Expand All @@ -148,23 +94,13 @@ def inspect

private

def join_step_run_tree
{step_run: [{release_platform_run: [{release_platform: [train: :app]}]}, :step]}
end

def search_params
{StepRun.arel_table => %w[build_version build_number]}
{Build.arel_table => %w[version_name build_number]}
end

def select_attrs(attrs_mapping)
attrs_mapping.map do |attr_name, column|
column.as(attr_name.to_s)
end
end

def distinct_deployment_runs
array_agg = Arel::Nodes::NamedFunction.new "array_agg", [ExternalRelease.arel_table[:deployment_run_id]]
window = Arel::Nodes::Window.new.partition(ExternalRelease.arel_table[:build_number])
array_agg.over(window).as("deployment_run_ids")
end
end
1 change: 1 addition & 0 deletions app/models/build.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Build < ApplicationRecord
belongs_to :workflow_run
has_one :artifact, class_name: "BuildArtifact", dependent: :nullify, inverse_of: :build
has_many :production_releases, dependent: :nullify, inverse_of: :build
has_many :store_submissions, dependent: :nullify, inverse_of: :build
has_one :external_build, dependent: :destroy, inverse_of: :build

scope :internal, -> { joins(:workflow_run).where(workflow_run: {kind: WorkflowRun::KINDS[:internal]}) }
Expand Down
4 changes: 4 additions & 0 deletions app/models/config/submission.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ def display
submission_type.classify.constantize.model_name.human
end

def submission_info
"#{display}#{submission_external.name}"
end

def production_release_submission
if production?
errors.add(:integrable_type, :variant_not_allowed) if integrable_type == "AppVariant"
Expand Down
33 changes: 8 additions & 25 deletions spec/libs/queries/builds_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
app = create(:app, :android)
train = create(:train, app:)
release_platform = create(:release_platform, app:, train:)
step = create(:step, :with_deployment, release_platform:)
step_run = create(:step_run, step:)
create(:build_artifact, step_run:)
release_platform_run = create(:release_platform_run, :on_track, release_platform:)
_build = create(:build, release_platform_run:)

actual = described_class.all(app:, params:).first
expect(actual).to be_a(Queries::Build)
Expand All @@ -24,11 +23,9 @@
app = create(:app, :android)
train = create(:train, app:)
release_platform = create(:release_platform, app:, train:)
step = create(:step, :with_deployment, release_platform:)
step_run1 = create(:step_run, step:)
step_run2 = create(:step_run, step:)
create(:build_artifact, step_run: step_run1)
create(:build_artifact, step_run: step_run2)
release_platform_run = create(:release_platform_run, :on_track, release_platform:)
_build_1 = create(:build, release_platform_run:)
_build_1 = create(:build, release_platform_run:)

actual = described_class.all(app:, params:).size
expect(actual).to eq(2)
Expand All @@ -38,24 +35,10 @@
app = create(:app, :android)
train = create(:train, app:)
release_platform = create(:release_platform, app:, train:)
step = create(:step, :with_deployment, release_platform:)
step_run = create(:step_run, step:)
create(:build_artifact, step_run:)
release_platform_run = create(:release_platform_run, :on_track, release_platform:)
_build = create(:build, release_platform_run:)

expected_keys = [
"version_name",
"version_code",
"built_at",
"release_status",
"step_status",
"train_name",
"platform",
"step_name",
"ci_link",
"deployments",
"download_url",
"external_release_status"
]
expected_keys = %w[version_name version_code built_at release_status train_name platform kind ci_link submissions download_url]

actual = described_class.all(app:, params:).first.attributes.keys
expect(actual).to match_array(expected_keys)
Expand Down

0 comments on commit d9cfd85

Please sign in to comment.