Skip to content

Commit

Permalink
Update header for pre-prod release steps (#715)
Browse files Browse the repository at this point in the history
Show a small timeline, the workflow and a drawer for build insights
  • Loading branch information
kitallis authored Jan 7, 2025
1 parent c258784 commit 3e89d6e
Show file tree
Hide file tree
Showing 19 changed files with 264 additions and 294 deletions.
6 changes: 6 additions & 0 deletions app/assets/images/lightbulb.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 14 additions & 1 deletion app/components/timeline_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,21 @@
<div class="absolute w-3 h-3 <%= event_color(event) %> rounded-full mt-1.5 -start-1.5 border"></div>
<time class="mb-1 text-xs font-normal leading-none text-secondary-50 dark:text-secondary"><%= event[:timestamp] %></time>
<h5 class="heading-5"><%= event[:title] %></h5>
<p class="text-xs font-normal text-secondary dark:text-secondary-50"><%= raw(event[:description]) %></p>
<p class="overflow-hidden line-clamp-2 text-xs font-normal text-secondary dark:text-secondary-50"><%= raw(event[:description]) %></p>
</li>
<% end %>

<li class="mt-6 last:mb-0 ms-4 text-secondary text-xs">
<%= render V2::ButtonComponent.new(label: "View all events",
scheme: :link,
type: :link_external,
options: view_all_link,
html_options: { class: "text-xs" },
authz: false,
size: :none,
arrow: :none) do |b|
b.with_icon("v2/activity.svg", size: :sm)
end %>
</li>
</ol>
<% end %>
17 changes: 15 additions & 2 deletions app/components/timeline_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,33 @@
class TimelineComponent < ViewComponent::Base
include ApplicationHelper

DEFAULT_TRUNCATE = 2
EVENT_TYPE = {
success: "bg-green-500 border-white dark:border-main-900 dark:bg-green-500",
error: "bg-red-500 border-white dark:border-main-900 dark:bg-red-500",
neutral: "bg-main-200 border-white dark:border-main-900 dark:bg-main-700",
notice: "bg-sky-500 border-white dark:border-sky-900 dark:bg-sky-700"
}

def initialize(events:)
def initialize(events:, truncate: false, view_all_link: nil)
raise ArgumentError, "you must supply a 'view all' link when truncate is on" if truncate && view_all_link.nil?

@events = events
@truncate = truncate
@view_all_link = view_all_link
end

attr_reader :events
attr_reader :truncate, :view_all_link

def event_color(event)
EVENT_TYPE.fetch(event[:type] || :neutral)
end

def events
if truncate
@events.take(DEFAULT_TRUNCATE)
else
@events
end
end
end
3 changes: 1 addition & 2 deletions app/components/v2/build_health_component.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# frozen_string_literal: true

class V2::BuildHealthComponent < ViewComponent::Base
def initialize(release_platform_run:, builds:)
@release_platform_run = release_platform_run
def initialize(builds)
@builds = builds
end

Expand Down
68 changes: 30 additions & 38 deletions app/components/v2/live_release/internal_builds_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,42 @@
<% container.with_back_button %>
<% container.with_tab(title: "Internal Builds", icon:) do %>
<%= render V2::PlatformViewComponent.new(release) do |component| %>
<% component.runs do |release_platform_run| %>
<% if configured?(release_platform_run) %>
<%= render V2::LiveRelease::SubmissionConfigComponent.new(configuration(release_platform_run), internal_workflow_config(release_platform_run), release_platform_run:) %>
<% else %>
<%= render V2::EmptyStateComponent.new(
title: "No internal build step configured",
text: "Please configure an internal build step for the train to see the build status.",
banner_image: "v2/drill.svg",
type: :subdued) %>
<% end %>
<% end %>

<% component.runs do |run| %>
<% latest_release = latest_internal_release(run) %>
<% if latest_release.present? %>
<%= render V2::LiveRelease::PreProdRelease::CurrentReleaseComponent.new(latest_release) %>
<% elsif configured?(run) %>
<% if run.hotfix? && run.active? %>
<%= render V2::AlertComponent.new(kind: :announcement, type: :announce, title: "Changes were not automatically applied for the hotfix") do |ann| %>
<% ann.with_announcement_button(label: "Create internal build",
scheme: :default,
type: :button,
options: pre_prod_internal_run_path(run),
size: :xxs,
html_options: html_opts(:post, "Are you sure you want to create the internal build?")) %>
<div class="flex flex-col gap-2">
<%= render V2::CommitComponent.new(commit: applicable_commit(run), detailed: false) %>
<span class="text-sm">Internal builds are not automatically triggered for hotfixes. But you can manually apply the latest commit and kickoff the build.</span>
</div>
<div class="flex flex-col gap-5">
<% if configured?(run) %>
<% latest_release = latest_internal_release(run) %>
<%= render V2::LiveRelease::PreProdRelease::InternalHeaderComponent.new(run, latest_release) %>

<% if latest_release.present? %>
<%= render V2::LiveRelease::PreProdRelease::CurrentReleaseComponent.new(latest_release) %>
<% elsif run.hotfix? && run.active? %>
<%= render V2::AlertComponent.new(kind: :announcement, type: :announce, title: "Changes were not automatically applied for the hotfix") do |ann| %>
<% ann.with_announcement_button(label: "Create internal build",
scheme: :default,
type: :button,
options: pre_prod_internal_run_path(run),
size: :xxs,
html_options: html_opts(:post, "Are you sure you want to create the internal build?")) %>
<div class="flex flex-col gap-2">
<%= render V2::CommitComponent.new(commit: applicable_commit(run), detailed: false) %>
<span class="text-sm">Internal builds are not automatically triggered for hotfixes. But you can manually apply the latest commit and kickoff the build.</span>
</div>
<% end %>
<% else %>
<%= render V2::EmptyStateComponent.new(
title: "Not ready yet",
text: "Please wait for changes to be applied before starting.",
banner_image: icon,
type: :subdued) %>
<% end %>
<% else %>
<%= render V2::EmptyStateComponent.new(
title: "Not ready yet",
text: "Please wait for changes to be applied before starting.",
banner_image: icon,
title: "No internal build step configured",
text: "Please configure an internal build step for the train to see the build status.",
banner_image: "v2/drill.svg",
type: :subdued) %>
<% end %>
<% else %>
<div><!-- grid maintenance --></div>
<% end %>
<% end %>

<% component.runs do |run| %>
<%= render partial: "pre_prod_releases/build_insights", locals: {builds: builds(run), run:} %>
</div>
<% end %>

<% component.runs do |release_platform_run| %>
Expand Down
8 changes: 0 additions & 8 deletions app/components/v2/live_release/internal_builds_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ def configured?(run)
configuration(run).present?
end

def internal_workflow_config(run)
run.conf.pick_internal_workflow
end

def configuration(run)
run.conf.internal_release
end
Expand All @@ -36,8 +32,4 @@ def latest_internal_release(run)
def previous_internal_releases(run)
run.older_internal_releases
end

def builds(run)
run.internal_builds.includes(:external_build)
end
end
2 changes: 1 addition & 1 deletion app/components/v2/live_release/metadata_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<%= render V2::ButtonComponent.new(label: "App Store Connect metadata requirements",
scheme: :link,
type: :link_external,
options: "/",
options: "https://help.apple.com/asc/appsspec/en.lproj/static.html",
html_options: { class: "text-sm" },
authz: false,
size: :none,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<div class="<%= grids %> item-gap-default">
<div>
<% if events.present? %>
<%= render TimelineComponent.new(events:, truncate: true, view_all_link: timeline_release_path(pre_prod_release.release)) %>
<% end %>
</div>

<div class="flex flex-col justify-start gap-1">
<div class="flex flex-wrap flex-row justify-end gap-2">
<div class="flex gap-1 items-center text-secondary text-sm">
<% icon = V2::IconComponent.new("v2/info_full.svg", size: :base) %>
<% icon.with_tooltip("", placement: "bottom", type: :detailed) do |tooltip| %>
<% tooltip.with_detailed_text do %>
The build will be created from this workflow. Once the workflow completes and Tramline is able to find
the build, Tramline will send the build to the configured submission channels automatically or otherwise
(based on your settings).
<% end %>
<% end %>

<%= render icon %>

Workflow
</div>

<div class="last:border-0 border-l border-solid border-main-300"></div>

<div>
<%= render V2::BadgeComponent.new(text: workflow_config.name, kind: :badge) do |badge| %>
<% badge.with_icon(ci_cd_provider_logo) %>
<% end %>
</div>
</div>

<div class="flex justify-end">
<%= render V2::ModalComponent.new(title: "Build Insights", size: :lg, type: :drawer, authz: false) do |modal| %>
<% button = modal.with_button(label: "Build Insights", scheme: :supporting, size: :xxs, type: :action) %>
<% button.with_icon("lightbulb.svg", size: :md) %>
<% modal.with_body do %>
<%= render partial: "pre_prod_releases/build_insights", locals: { builds: } %>
<% end %>
<% end %>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

class V2::LiveRelease::PreProdRelease::HeaderComponent < V2::BaseComponent
include Memery

def initialize(release_platform_run, pre_prod_release)
@release_platform_run = release_platform_run
@pre_prod_release = pre_prod_release
end

attr_reader :release_platform_run, :pre_prod_release
delegate :latest_events, to: :pre_prod_release, allow_nil: true

memoize def events
return [] unless latest_events
latest_events.flat_map do |event|
{
type: event.kind.to_sym,
description: event.message,
timestamp: time_format(event.event_timestamp, with_year: false)
}
end
end

def grids
return "grid grid-cols-2" if events.present?
"grid grid-cols-1"
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class V2::LiveRelease::PreProdRelease::InternalHeaderComponent < V2::LiveRelease::PreProdRelease::HeaderComponent
def workflow_config
release_platform_run.conf.pick_internal_workflow
end

def builds
release_platform_run.internal_builds.includes(:external_build)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class V2::LiveRelease::PreProdRelease::RcHeaderComponent < V2::LiveRelease::PreProdRelease::HeaderComponent
def workflow_config
release_platform_run.conf.release_candidate_workflow
end

def builds
release_platform_run.rc_builds.includes(:external_build)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,21 @@
<% container.with_back_button %>
<% container.with_tab(title: "Release Candidate", icon: live_release_tab_configuration.dig(:stability, :release_candidate, :icon)) do %>
<%= render V2::PlatformViewComponent.new(release) do |component| %>
<% component.runs do |release_platform_run| %>
<%= render V2::LiveRelease::SubmissionConfigComponent.new(configuration(release_platform_run), workflow_config(release_platform_run), release_platform_run:) %>
<% end %>
<% component.runs do |run| %>
<div class="flex flex-col gap-5">
<% beta_release = latest_beta_release(run) %>
<%= render V2::LiveRelease::PreProdRelease::RcHeaderComponent.new(run, beta_release) %>

<% component.runs do |release_platform_run| %>
<% beta_release = latest_beta_release(release_platform_run) %>
<% if beta_release.present? %>
<%= render V2::LiveRelease::PreProdRelease::CurrentReleaseComponent.new(beta_release) %>
<% else %>
<%= render V2::LiveRelease::PreProdRelease::PrepareReleaseCandidateComponent.new(release_platform_run) %>
<% end %>
<% if beta_release.present? %>
<%= render V2::LiveRelease::PreProdRelease::CurrentReleaseComponent.new(beta_release) %>
<% else %>
<%= render V2::LiveRelease::PreProdRelease::PrepareReleaseCandidateComponent.new(run) %>
<% end %>
</div>
<% end %>

<% component.runs do |run| %>
<%= render partial: "pre_prod_releases/build_insights", locals: {builds: builds(run), run:} %>
<% end %>

<% component.runs do |release_platform_run| %>
<% previous_betas = previous_beta_releases(release_platform_run) %>
<% previous_betas = previous_beta_releases(run) %>
<% if previous_betas.present? %>
<%= render V2::SectionComponent.new(title: "Other builds (#{previous_betas.size})", style: :titled, size: :compact) do %>
<div class="flex flex-col item-gap-default">
Expand Down
12 changes: 0 additions & 12 deletions app/components/v2/live_release/release_candidates_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,11 @@ def initialize(release)

attr_reader :release

def configuration(release_platform_run)
release_platform_run.conf.beta_release
end

def workflow_config(release_platform_run)
release_platform_run.conf.release_candidate_workflow
end

def latest_beta_release(release_platform_run)
release_platform_run.latest_beta_release
end

def previous_beta_releases(release_platform_run)
release_platform_run.older_beta_releases
end

def builds(run)
run.rc_builds.includes(:external_build)
end
end

This file was deleted.

11 changes: 0 additions & 11 deletions app/components/v2/live_release/submission_config_component.rb

This file was deleted.

Loading

0 comments on commit 3e89d6e

Please sign in to comment.