Skip to content

Commit a367c4d

Browse files
committed
Integrate commitfest status
This commit adds a script to scrape the commitfest website, and mirror some data in our database. This script is executed each day for open commitfests, and once manually at the beginning for all. Based on this info, we can link the commitfest patch pages and display commitfest status even on the topic index.
1 parent 8362f33 commit a367c4d

23 files changed

+892
-14
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ gem "stimulus-rails"
2121
gem "jbuilder"
2222
gem "slim"
2323
gem "kaminari"
24+
gem "nokogiri"
2425

2526
# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
2627
gem "bcrypt", "~> 3.1"

Gemfile.lock

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ DEPENDENCIES
493493
kaminari
494494
letter_opener
495495
letter_opener_web
496+
nokogiri
496497
omniauth
497498
omniauth-google-oauth2
498499
omniauth-rails_csrf_protection
@@ -517,4 +518,4 @@ DEPENDENCIES
517518
web-console
518519

519520
BUNDLED WITH
520-
2.6.9
521+
4.0.3

app/assets/stylesheets/components/sidebar.css

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,66 @@
107107
.sidebar .attachment-names {
108108
color: var(--color-text-secondary);
109109
}
110+
111+
.sidebar .commitfest-list {
112+
display: flex;
113+
flex-direction: column;
114+
gap: var(--spacing-3);
115+
}
116+
117+
.sidebar .commitfest-entry-header {
118+
display: flex;
119+
justify-content: space-between;
120+
gap: var(--spacing-2);
121+
align-items: baseline;
122+
}
123+
124+
.sidebar .commitfest-link,
125+
.sidebar .commitfest-patch-link {
126+
color: var(--color-text-link);
127+
text-decoration: none;
128+
font-weight: var(--font-weight-semibold);
129+
}
130+
131+
.sidebar .commitfest-link:hover,
132+
.sidebar .commitfest-patch-link:hover {
133+
text-decoration: underline;
134+
}
135+
136+
.sidebar .commitfest-status {
137+
color: var(--color-text-secondary);
138+
font-size: var(--font-size-sm);
139+
white-space: nowrap;
140+
}
141+
142+
.sidebar .commitfest-patch {
143+
margin-top: var(--spacing-1);
144+
color: var(--color-text-secondary);
145+
}
146+
147+
.sidebar .commitfest-tags {
148+
display: flex;
149+
flex-wrap: wrap;
150+
gap: var(--spacing-2);
151+
margin-top: var(--spacing-2);
152+
}
153+
154+
.sidebar .commitfest-tag {
155+
background: var(--color-gray-100);
156+
padding: 2px 8px;
157+
border-radius: var(--border-radius-sm);
158+
font-size: var(--font-size-xs);
159+
color: var(--color-text-secondary);
160+
}
161+
162+
.sidebar .commitfest-reviewers,
163+
.sidebar .commitfest-committers {
164+
list-style: none;
165+
padding-left: 0;
166+
margin: 0;
167+
}
168+
169+
.sidebar .commitfest-reviewers li + li,
170+
.sidebar .commitfest-committers li + li {
171+
margin-top: var(--spacing-1);
172+
}

app/assets/stylesheets/components/topics.css

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,61 @@
237237
margin-bottom: 0;
238238
}
239239

240+
.commitfest-icon {
241+
background: var(--color-bg-icon);
242+
color: var(--color-text-secondary);
243+
}
244+
245+
.commitfest-icon.commitfest-committed {
246+
color: var(--color-success);
247+
}
248+
249+
.commitfest-hover {
250+
display: flex;
251+
flex-direction: column;
252+
gap: var(--spacing-2);
253+
}
254+
255+
.commitfest-hover-title {
256+
display: flex;
257+
justify-content: space-between;
258+
gap: var(--spacing-2);
259+
font-weight: var(--font-weight-semibold);
260+
}
261+
262+
.commitfest-hover-title a {
263+
color: var(--color-text-link);
264+
text-decoration: none;
265+
}
266+
267+
.commitfest-hover-title a:hover {
268+
text-decoration: underline;
269+
}
270+
271+
.commitfest-hover-status {
272+
color: var(--color-text-secondary);
273+
font-size: var(--font-size-sm);
274+
white-space: nowrap;
275+
}
276+
277+
.commitfest-hover-row {
278+
display: flex;
279+
gap: var(--spacing-2);
280+
align-items: baseline;
281+
}
282+
283+
.commitfest-hover-label {
284+
color: var(--color-text-muted);
285+
font-size: var(--font-size-xs);
286+
text-transform: uppercase;
287+
letter-spacing: 0.04em;
288+
}
289+
290+
.commitfest-hover-value {
291+
color: var(--color-text-primary);
292+
font-size: var(--font-size-sm);
293+
}
294+
240295
.topic-meta {
241296
& span {
242297
padding-right: var(--spacing-2);

app/controllers/topics_controller.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ def index
77
base_query = apply_filters(Topic.includes(:creator))
88

99
apply_cursor_pagination(base_query)
10+
preload_commitfest_summaries
1011
@new_topics_count = 0
1112
@page_cache_key = topics_page_cache_key
1213

@@ -42,6 +43,7 @@ def show
4243

4344
build_participants_sidebar_data(messages_scope)
4445
build_thread_outline(messages_scope)
46+
load_commitfest_sidebar
4547
load_notes if user_signed_in?
4648
end
4749

@@ -101,6 +103,7 @@ def search
101103
@new_topics_count = 0
102104
end
103105

106+
preload_commitfest_summaries
104107
preload_participation_flags if user_signed_in?
105108

106109
respond_to do |format|
@@ -157,6 +160,7 @@ def user_state_frame
157160
preload_topic_states
158161
preload_note_counts
159162
preload_participation_flags
163+
preload_commitfest_summaries
160164

161165
respond_to do |format|
162166
format.turbo_stream
@@ -700,6 +704,37 @@ def load_cached_search_results
700704
@new_topics_count = 0
701705
end
702706

707+
def preload_commitfest_summaries
708+
topic_ids = @topics.map(&:id)
709+
@commitfest_summaries = Topic.commitfest_summaries(topic_ids)
710+
end
711+
712+
def load_commitfest_sidebar
713+
entries = CommitfestPatchCommitfest
714+
.joins(commitfest_patch: :commitfest_patch_topics)
715+
.includes(:commitfest, commitfest_patch: :commitfest_tags)
716+
.where(commitfest_patch_topics: { topic_id: @topic.id })
717+
.order("commitfests.end_date DESC, commitfests.start_date DESC")
718+
719+
@commitfest_sidebar_entries = entries.map do |entry|
720+
patch = entry.commitfest_patch
721+
{
722+
commitfest_name: entry.commitfest.name,
723+
commitfest_external_id: entry.commitfest.external_id,
724+
patch_external_id: patch.external_id,
725+
patch_title: patch.title,
726+
status: entry.status,
727+
tags: patch.commitfest_tags.map(&:name)
728+
}
729+
end
730+
731+
reviewers = entries.flat_map { |entry| Topic.parse_csv_list(entry.commitfest_patch.reviewers) }
732+
@commitfest_reviewers = reviewers.uniq
733+
734+
committers = entries.map { |entry| entry.commitfest_patch.committer.to_s.strip }.reject(&:blank?).uniq
735+
@commitfest_committers = committers
736+
end
737+
703738
def slice_cached_entries(entries, cursor_param)
704739
return { entries: entries.first(25) } unless cursor_param.present?
705740

app/helpers/application_helper.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,24 @@ def message_id_anchor(message)
3636
"message-id-#{CGI.escape(message.message_id)}"
3737
end
3838

39+
def commitfest_ci_label(summary)
40+
case summary[:ci_status]
41+
when "not_processed"
42+
"Not processed"
43+
when "needs_rebase"
44+
"Needs rebase"
45+
when "score"
46+
"CI score: #{summary[:ci_score].to_i}/10"
47+
end
48+
end
49+
50+
def commitfest_icon_class(summary)
51+
return "fa-circle-check" if summary[:committed]
52+
return "fa-magnifying-glass" if summary[:status] == "Needs review"
53+
54+
"fa-code-branch"
55+
end
56+
3957
def read_visibility_seconds
4058
5
4159
end

app/models/commitfest.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
class Commitfest < ApplicationRecord
4+
has_many :commitfest_patch_commitfests, dependent: :destroy
5+
has_many :commitfest_patches, through: :commitfest_patch_commitfests
6+
7+
validates :external_id, :name, :status, :start_date, :end_date, presence: true
8+
end

app/models/commitfest_patch.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
3+
class CommitfestPatch < ApplicationRecord
4+
has_many :commitfest_patch_commitfests, dependent: :destroy
5+
has_many :commitfests, through: :commitfest_patch_commitfests
6+
has_many :commitfest_patch_tags, dependent: :destroy
7+
has_many :commitfest_tags, through: :commitfest_patch_tags
8+
has_many :commitfest_patch_messages, dependent: :destroy
9+
has_many :commitfest_patch_topics, dependent: :destroy
10+
has_many :topics, through: :commitfest_patch_topics
11+
12+
validates :external_id, :title, presence: true
13+
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
class CommitfestPatchCommitfest < ApplicationRecord
4+
belongs_to :commitfest
5+
belongs_to :commitfest_patch
6+
7+
validates :status, presence: true
8+
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
class CommitfestPatchMessage < ApplicationRecord
4+
belongs_to :commitfest_patch
5+
belongs_to :message, optional: true, foreign_key: :message_record_id
6+
7+
validates :message_id, presence: true
8+
end

0 commit comments

Comments
 (0)