Skip to content

Commit f7abe55

Browse files
authored
Fix issue closing vote (#399)
Signed-off-by: Sergio Castaño Arteaga <[email protected]>
1 parent 9a577ed commit f7abe55

File tree

3 files changed

+63
-29
lines changed

3 files changed

+63
-29
lines changed

src/db.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
cfg::CfgProfile,
33
cmd::{CheckVoteInput, CreateVoteInput},
4-
github::{split_full_name, DynGH},
4+
github::{self, split_full_name, DynGH},
55
results::{self, Vote, VoteResults},
66
};
77
use anyhow::Result;
@@ -28,7 +28,7 @@ pub(crate) trait DB {
2828
) -> Result<Option<Uuid>>;
2929

3030
/// Close any pending finished vote.
31-
async fn close_finished_vote(&self, gh: DynGH) -> Result<Option<(Vote, VoteResults)>>;
31+
async fn close_finished_vote(&self, gh: DynGH) -> Result<Option<(Vote, Option<VoteResults>)>>;
3232

3333
/// Get open vote (if available) in the issue/pr provided.
3434
async fn get_open_vote(
@@ -84,6 +84,7 @@ impl PgDB {
8484
from vote
8585
where current_timestamp > ends_at
8686
and closed = false
87+
order by random()
8788
for update of vote skip locked
8889
limit 1
8990
",
@@ -98,7 +99,7 @@ impl PgDB {
9899
async fn store_vote_results(
99100
tx: &Transaction<'_>,
100101
vote_id: Uuid,
101-
results: &VoteResults,
102+
results: &Option<VoteResults>,
102103
) -> Result<()> {
103104
tx.execute(
104105
"
@@ -141,7 +142,7 @@ impl DB for PgDB {
141142
}
142143

143144
/// [DB::close_finished_vote]
144-
async fn close_finished_vote(&self, gh: DynGH) -> Result<Option<(Vote, VoteResults)>> {
145+
async fn close_finished_vote(&self, gh: DynGH) -> Result<Option<(Vote, Option<VoteResults>)>> {
145146
// Get pending finished vote (if any) from database
146147
let mut db = self.pool.get().await?;
147148
let tx = db.transaction().await?;
@@ -151,7 +152,18 @@ impl DB for PgDB {
151152

152153
// Calculate results
153154
let (owner, repo) = split_full_name(&vote.repository_full_name);
154-
let results = results::calculate(gh, owner, repo, &vote).await?;
155+
let results = match results::calculate(gh, owner, repo, &vote).await {
156+
Ok(results) => Some(results),
157+
Err(err) => {
158+
if github::is_not_found_error(&err) {
159+
// Vote comment was deleted. We still want to proceed and
160+
// close the vote so that we don't try again to close it.
161+
None
162+
} else {
163+
return Err(err);
164+
}
165+
}
166+
};
155167

156168
// Store results in database
157169
PgDB::store_vote_results(&tx, vote.vote_id, &results).await?;

src/github.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cfg::CfgProfile;
2-
use anyhow::Result;
2+
use anyhow::{Error, Result};
33
use async_trait::async_trait;
44
use axum::http::HeaderValue;
55
#[cfg(test)]
@@ -595,3 +595,17 @@ pub(crate) fn split_full_name(full_name: &str) -> (&str, &str) {
595595
let mut parts = full_name.split('/');
596596
(parts.next().unwrap(), parts.next().unwrap())
597597
}
598+
599+
/// Check if the provided error is a "Not Found" error from GitHub.
600+
pub(crate) fn is_not_found_error(err: &Error) -> bool {
601+
if let Some(octocrab::Error::GitHub {
602+
source,
603+
backtrace: _,
604+
}) = err.downcast_ref::<octocrab::Error>()
605+
{
606+
if source.message == "Not Found" {
607+
return true;
608+
}
609+
}
610+
false
611+
}

src/processor.rs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -424,32 +424,40 @@ impl Processor {
424424
// Record vote_id as part of the current span
425425
tracing::Span::current().record("vote_id", &vote.vote_id.to_string());
426426

427-
// Post vote closed comment on the issue/pr
427+
// Post vote closed comment on the issue/pr if results were returned
428+
// (i.e. if the vote comment was removed, the vote will be closed but
429+
// no results will be received)
428430
let inst_id = vote.installation_id as u64;
429431
let (owner, repo) = split_full_name(&vote.repository_full_name);
430-
let body = tmpl::VoteClosed::new(&results).render()?;
431-
self.gh
432-
.post_comment(inst_id, owner, repo, vote.issue_number, &body)
433-
.await?;
432+
if let Some(results) = &results {
433+
let body = tmpl::VoteClosed::new(results).render()?;
434+
self.gh
435+
.post_comment(inst_id, owner, repo, vote.issue_number, &body)
436+
.await?;
437+
}
434438

435439
// Create check run if the vote is on a pull request
436440
if vote.is_pull_request {
437-
let (conclusion, summary) = if results.passed {
438-
(
439-
"success",
440-
format!(
441-
"The vote passed! {} out of {} voted in favor.",
442-
results.in_favor, results.allowed_voters
443-
),
444-
)
441+
let (conclusion, summary) = if let Some(results) = &results {
442+
if results.passed {
443+
(
444+
"success",
445+
format!(
446+
"The vote passed! {} out of {} voted in favor.",
447+
results.in_favor, results.allowed_voters
448+
),
449+
)
450+
} else {
451+
(
452+
"failure",
453+
format!(
454+
"The vote did not pass. {} out of {} voted in favor.",
455+
results.in_favor, results.allowed_voters
456+
),
457+
)
458+
}
445459
} else {
446-
(
447-
"failure",
448-
format!(
449-
"The vote did not pass. {} out of {} voted in favor.",
450-
results.in_favor, results.allowed_voters
451-
),
452-
)
460+
("success", "The vote was cancelled".to_string())
453461
};
454462
let check_details = CheckDetails {
455463
status: "completed".to_string(),
@@ -1194,7 +1202,7 @@ mod tests {
11941202
db.expect_close_finished_vote().returning(move |_| {
11951203
Box::pin(future::ready(Ok(Some((
11961204
setup_test_vote(),
1197-
results_copy.clone(),
1205+
Some(results_copy.clone()),
11981206
)))))
11991207
});
12001208
let mut gh = MockGH::new();
@@ -1222,7 +1230,7 @@ mod tests {
12221230
db.expect_close_finished_vote().returning(move |_| {
12231231
let mut vote = setup_test_vote();
12241232
vote.is_pull_request = true;
1225-
Box::pin(future::ready(Ok(Some((vote, results_copy.clone())))))
1233+
Box::pin(future::ready(Ok(Some((vote, Some(results_copy.clone()))))))
12261234
});
12271235
let mut gh = MockGH::new();
12281236
gh.expect_post_comment()
@@ -1266,7 +1274,7 @@ mod tests {
12661274
db.expect_close_finished_vote().returning(move |_| {
12671275
let mut vote = setup_test_vote();
12681276
vote.is_pull_request = true;
1269-
Box::pin(future::ready(Ok(Some((vote, results_copy.clone())))))
1277+
Box::pin(future::ready(Ok(Some((vote, Some(results_copy.clone()))))))
12701278
});
12711279
let mut gh = MockGH::new();
12721280
gh.expect_post_comment()

0 commit comments

Comments
 (0)