Skip to content

Commit e504b54

Browse files
tegiozcynthia-sg
andauthored
Add audit page (#656)
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com> Signed-off-by: Cintia Sánchez García <cynthiasg@icloud.com> Co-authored-by: Cintia Sánchez García <cynthiasg@icloud.com>
1 parent 3bc4f5e commit e504b54

9 files changed

Lines changed: 1499 additions & 38 deletions

File tree

Cargo.lock

Lines changed: 119 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ askama = { version = "0.14.0", features = ["serde_json"] }
1212
async-channel = "2.5.0"
1313
async-trait = "0.1.89"
1414
axum = { version = "0.8.4", features = ["macros"] }
15+
cached = { version = "0.56.0", features = ["async"] }
1516
clap = { version = "4.5.48", features = ["derive"] }
1617
deadpool-postgres = { version = "0.14.1", features = ["serde"] }
1718
figment = { version = "0.10.19", features = ["yaml", "env"] }

docs/config/.gitvote.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,29 @@
66
# - At the root of the .github repository, for organization wide configuration
77
#
88

9+
# Audit (optional)
10+
#
11+
# The audit page lists all the votes recorded for the repository. It can be
12+
# useful to provide transparency on the voting history of a repository. By
13+
# default, the audit page is disabled. To enable it, the audit section must be
14+
# included in the configuration file, with the `enabled` field set to true.
15+
#
16+
# Please note that this page is publicly accessible, so anyone will be able
17+
# to see all votes recorded for the repository.
18+
#
19+
# Once you have enabled it, the audit page will be available at:
20+
#
21+
# https://gitvote.com/audit/OWNER/REPO
22+
#
23+
# (it can take up to 15 minutes for the audit page to be available after
24+
# enabling it)
25+
#
26+
# audit:
27+
# enabled: true
28+
#
29+
audit:
30+
enabled: false
31+
932
# Automation (optional)
1033
#
1134
# Create votes automatically on PRs when any of the files affected by the PR

src/cfg_repo.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ type ProfileName = String;
2424
/// `GitVote` configuration.
2525
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
2626
pub(crate) struct Cfg {
27+
pub profiles: HashMap<ProfileName, CfgProfile>,
28+
29+
#[serde(skip_serializing_if = "Option::is_none")]
30+
pub audit: Option<Audit>,
2731
#[serde(skip_serializing_if = "Option::is_none")]
2832
pub automation: Option<Automation>,
29-
pub profiles: HashMap<ProfileName, CfgProfile>,
3033
}
3134

3235
impl Cfg {
@@ -48,6 +51,12 @@ impl Cfg {
4851
}
4952
}
5053

54+
/// Audit configuration.
55+
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
56+
pub(crate) struct Audit {
57+
pub enabled: bool,
58+
}
59+
5160
/// Automation configuration.
5261
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
5362
pub(crate) struct Automation {

src/db.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ pub(crate) trait DB {
4545
/// Check if the issue/pr provided already has a vote open.
4646
async fn has_vote_open(&self, repository_full_name: &str, issue_number: i64) -> Result<bool>;
4747

48+
/// List all votes stored for the provided repository.
49+
async fn list_votes(&self, repository_full_name: &str) -> Result<Vec<Vote>>;
50+
4851
/// Store the vote provided in the database.
4952
async fn store_vote(
5053
&self,
@@ -280,6 +283,26 @@ impl DB for PgDB {
280283
Ok(has_vote_open)
281284
}
282285

286+
/// [`DB::list_votes`]
287+
async fn list_votes(&self, repository_full_name: &str) -> Result<Vec<Vote>> {
288+
let db = self.pool.get().await?;
289+
let votes = db
290+
.query(
291+
"
292+
select *
293+
from vote
294+
where repository_full_name = $1::text
295+
order by created_at desc
296+
",
297+
&[&repository_full_name],
298+
)
299+
.await?
300+
.iter()
301+
.map(Vote::from)
302+
.collect();
303+
Ok(votes)
304+
}
305+
283306
/// [`DB::store_vote`]
284307
async fn store_vote(
285308
&self,

src/github.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ pub(crate) trait GH {
123123
/// Get pull request files.
124124
async fn get_pr_files(&self, inst_id: u64, owner: &str, repo: &str, pr_number: i64) -> Result<Vec<File>>;
125125

126+
/// Get repository installation identifier.
127+
async fn get_repository_installation_id(&self, owner: &str, repo: &str) -> Result<u64>;
128+
126129
/// Get all members of the provided team.
127130
#[allow(dead_code)]
128131
async fn get_team_members(
@@ -378,6 +381,12 @@ impl GH for GHApi {
378381
Ok(files)
379382
}
380383

384+
/// [`GH::get_repository_installation_id`]
385+
async fn get_repository_installation_id(&self, owner: &str, repo: &str) -> Result<u64> {
386+
let inst = self.app_client.apps().get_repository_installation(owner, repo).await?;
387+
Ok(inst.id.0)
388+
}
389+
381390
/// [`GH::get_team_members`]
382391
async fn get_team_members(
383392
&self,

0 commit comments

Comments
 (0)