diff --git a/app/assets/stylesheets/modules/gem.css b/app/assets/stylesheets/modules/gem.css index 71a6dd657e0..e4b3aac0099 100644 --- a/app/assets/stylesheets/modules/gem.css +++ b/app/assets/stylesheets/modules/gem.css @@ -267,21 +267,147 @@ } .gem__attestation { + align-items: center; display: flex; flex-direction: row; - margin-top: 16px; } - .gem__attestation__built_on { - flex-grow: 1; } + gap: 10px; + padding: 0; +} + +.gem__attestation:not(:first-child) { + margin-top: 16px; +} + +.gem__attestation__built_on { + border: 1px solid #d7dee3; + border-radius: 8px; + box-shadow: 2px 2px 7px 0 #00000008; + display: flex; + flex-shrink: 0; + gap: 16px; + padding: 20px; +} + +.gem__attestation__built_on__github_actions { + align-items: center; + aspect-ratio: 1/1; + background: #ffeedd; + background-color: #f0f2f5; + border: 1px solid #f74c27; + border-radius: 7px; + box-sizing: border-box; + display: flex; + flex: none; + flex-direction: row; + flex-grow: 0; + gap: 10px; + min-width: 72px; + order: 0; + padding: 12px; +} + +.gem__attestation__built_on__info { + align-items: flex-start; + + /* Frame 1197136313 */ + + /* Auto layout */ + display: flex; + flex-direction: column; + font-size: 12px; + font-weight: 400; + gap: 4px; + height: fit-content; + line-height: 24px; + padding: 0; + text-align: left; + text-decoration-skip-ink: none; + text-underline-position: from-font; +} + +.gem__attestation__built_on__info em { + font-size: 16px; + font-style: normal; + font-weight: 600; + color: #333a45; +} + +.gem__attestation__built_on__info a { + color: #f74c27; + text-decoration: underline; +} + +.gem__attestation__grid { + box-sizing: border-box; + display: flex; + flex: 1; + flex-direction: column; + gap: 10px; + padding: 20px; + width: 100%; +} + +.gem__attestation__grid > div { + align-items: baseline; + display: flex; + flex-direction: row; + gap: 16px; + place-content: space-between; +} + +.gem__attestation__grid p { + font-size: 14px; + font-weight: 600; + height: 100%; +} + +.gem__attestation__grid a { + align-items: center; + color: var(--gem-version-color); + display: flex; + flex-direction: row; + font-size: 14px; + font-weight: 400; + height: 100%; + text-align: end; + text-decoration: none; + width: 100%; +} + +.gem__attestation__grid a::after { + content: url('data:image/svg+xml;utf8,'); + display: inline-block; + height: 1rem; + vertical-align: middle; +} + +@media (width <= 929px) { .gem__attestation__grid { - display: grid; - grid-template-rows: repeat(3, 1rem); - grid-row-gap: 18px; - grid-column-gap: 16px; } - .gem__attestation__grid p { - height: 100%; - display: block; } - .gem__attestation__grid__left { - grid-template-columns: 24px max-content; } - .gem__attestation__grid__right { - grid-template-columns: max-content 1fr; } + padding: 10px; + } + + .gem__attestation__grid > div { + flex-direction: column; + gap: 16px; + } + + .gem__attestation { + align-items: flex-start; + flex-direction: column; + gap: 16px; + width: 100%; + } + .gem__attestation__grid a { + justify-content: space-between; + } + + .gem__attestation__grid p { + width: 100%; + } + + .gem__attestation__built_on { + box-sizing: border-box; + width: 100%; + } +} \ No newline at end of file diff --git a/app/models/attestation.rb b/app/models/attestation.rb index e85eac9e770..0328cba3345 100644 --- a/app/models/attestation.rb +++ b/app/models/attestation.rb @@ -37,9 +37,10 @@ def display_data # rubocop:disable Metrics/MethodLength build_file_string = ::Regexp.last_match(1) { ci_platform: "GitHub Actions", - source_commit_string: "github.com/#{repo}@#{commit[0, 7]}", + source_commit_string: "#{repo}@#{commit[0, 7]}", source_commit_url: "https://github.com/#{repo}/tree/#{commit}", - build_file_string:, build_file_url: + build_file_string:, build_file_url:, + build_summary_url: "https://github.com/#{repo}/actions/runs/#{build_file_string}" } else raise "Unhandled issuer: #{issuer.inspect}" diff --git a/app/views/components/version/provenance_component.rb b/app/views/components/version/provenance_component.rb index fb454d5acc1..bcacbc2f25a 100644 --- a/app/views/components/version/provenance_component.rb +++ b/app/views/components/version/provenance_component.rb @@ -8,25 +8,51 @@ class Version::ProvenanceComponent < ApplicationComponent def view_template display_data = @attestation.display_data - div(class: "gem__attestation") do + div(class: "gem__attestation", id: "gem__attestation") do div(class: "gem__attestation__built_on") do - div(class: "gem__attestation__grid gem__attestation__grid__left") do - p - p { plain "Built and signed on" } - p { "✅" } - p { display_data[:ci_platform] } + provider_box(display_data) + end + div(class: "gem__attestation__grid gem__attestation__grid__right") do + div do + p { plain "Source Commit" } + p { link_to display_data[:source_commit_string], display_data[:source_commit_url] } + end + div do + p { plain "Build File" } + p { link_to display_data[:build_file_string], display_data[:build_file_url] } + end + div do p - p { link_to "Build summary", display_data[:build_summary_url], target: "_blank", rel: "noopener" } + p { link_to "transparency log entry", "https://search.sigstore.dev/?logIndex=#{display_data[:log_index]}" } end end - div(class: "gem__attestation__grid gem__attestation__grid__right") do - p { plain "Source Commit" } - p { link_to display_data[:source_commit_string], display_data[:source_commit_url] } - p { plain "Build File" } - p { link_to display_data[:build_file_string], display_data[:build_file_url] } - p { plain "Public Ledger" } - p { link_to "Transparency log entry", "https://search.sigstore.dev/?logIndex=#{display_data[:log_index]}" } + end + end + + def provider_box(display_data) + case display_data[:ci_platform] + when "GitHub Actions" + div(class: "gem__attestation__built_on__github_actions") do + unsafe_raw <<~SVG + + + + + + + + + + + SVG end + else + "Unknown" + end + div(class: "gem__attestation__built_on__info") do + p { plain "Built and signed on" } + p { em { display_data[:ci_platform] } } + p { link_to "Build summary", display_data[:build_summary_url], target: "_blank", rel: "noopener" } end end end diff --git a/test/components/previews/version/provenance_component_preview.rb b/test/components/previews/version/provenance_component_preview.rb new file mode 100644 index 00000000000..c52f1a217a6 --- /dev/null +++ b/test/components/previews/version/provenance_component_preview.rb @@ -0,0 +1,7 @@ +class Version::ProvenanceComponentPreview < Lookbook::Preview + def default + render Version::ProvenanceComponent.new( + attestation: FactoryBot.build(:attestation) + ) + end +end