Skip to content

Commit

Permalink
Allow setting review assignment limit
Browse files Browse the repository at this point in the history
  • Loading branch information
apiraino committed Nov 6, 2024
1 parent 5575174 commit e701af8
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 27 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,32 @@ gh webhook forward --repo=ehuss/triagebot-test --events=* \

Where the value in `--secret` is the secret value you place in `GITHUB_WEBHOOK_SECRET` in the `.env` file, and `--repo` is the repo you want to test against.

You can test webhooks with `cURL`. For example to test the Zulip hooks (commands sent to the
Triagebot from the Rust lang Zulip), you start the triagebot on localhost:8000 and then simulate a
Zulip hook payload:
``` sh
curl http://localhost:8000/zulip-hook \
-H "Content-Type: application/json" \
-d '{
"data": "<CMD>",
"token": "<ZULIP_TOKEN>",
"message": {
"sender_id": <YOUR_ID>,
"recipient_id": <YOUR_ID>,
"sender_full_name": "Randolph Carter",
"sender_email": "[email protected]",
"type": "stream"
}
}'
```

Where:
- `CMD` is the exact command you would issue @triagebot on Zulip (ex. open a direct chat with the
bot and send "work show")
- `ZULIP_TOKEN`: can be anything. Must correspond to the env var `$ZULIP_TOKEN` on your workstation
- `YOUR_ID`: your GitHub user ID. Must be existing in your local triagebot database (table `users` and as
foreign key also in `review_prefs`)

#### ngrok

The following is an example of using <https://ngrok.com/> to provide webhook forwarding.
Expand Down
1 change: 1 addition & 0 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,5 @@ CREATE EXTENSION IF NOT EXISTS intarray;",
"
CREATE UNIQUE INDEX IF NOT EXISTS review_prefs_user_id ON review_prefs(user_id);
",
"ALTER TABLE review_prefs ADD COLUMN max_assigned_prs INT DEFAULT NULL;",
];
18 changes: 8 additions & 10 deletions src/handlers/pull_requests_assignment_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,16 @@ WHERE r.user_id = $1;";
pub async fn set_review_prefs(
db: &DbClient,
user_id: u64,
max: u32,
) -> anyhow::Result<ReviewPrefs> {
pref_max_prs: u32,
) -> anyhow::Result<u64, anyhow::Error> {
let q = "
UPDATE review_prefs r
SET max_assigned_prs = $2
SET max_assigned_prs = $1
FROM users u
WHERE r.user_id=$1 AND u.user_id=r.user_id
RETURNING u.username, r.*";
let row = db
.query_one(q, &[&(max as i32), &(user_id as i64)])
WHERE r.user_id=$2 AND u.user_id=r.user_id;";
let res = db
.execute(q, &[&(pref_max_prs as i32), &(user_id as i64)])
.await
.context("Error retrieving review preferences")
.unwrap();
Ok(row.into())
.context("Error setting review preferences")?;
Ok(res)
}
17 changes: 14 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,27 @@ pub struct ReviewPrefs {
pub username: String,
pub user_id: i64,
pub assigned_prs: Vec<i32>,
pub max_assigned_prs: Option<u32>,
}

impl ReviewPrefs {
fn to_string(&self) -> String {
impl fmt::Display for ReviewPrefs {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let prs = self
.assigned_prs
.iter()
.map(|pr| format!("#{}", pr))
.collect::<Vec<String>>()
.join(", ");
format!("Username: {}\nAssigned PRs: {}", self.username, prs)
let max = if self.max_assigned_prs.is_none() {
"<not set>"
} else {
&format!("{}", self.max_assigned_prs.expect("NaN"))
};
write!(
f,
"Username: {}\nAssigned PRs: {}\nCurrent review capacity: {}",
self.username, prs, max
)
}
}

Expand All @@ -152,6 +162,7 @@ impl From<tokio_postgres::row::Row> for ReviewPrefs {
username: row.get("username"),
user_id: row.get("user_id"),
assigned_prs: row.get("assigned_prs"),
max_assigned_prs: row.get("max_assigned_prs"),
}
}
}
Expand Down
27 changes: 13 additions & 14 deletions src/zulip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,34 +264,33 @@ async fn query_pr_assignments(

let db_client = ctx.db.get().await;

let record = match subcommand {
let reply = match subcommand {
"show" => {
let rec = get_review_prefs(&db_client, gh_id).await;
if rec.is_err() {
anyhow::bail!("No preferences set.")
}
rec?
let rec = get_review_prefs(&db_client, gh_id)
.await
.context("Could not query review preferences")?;
rec.to_string()
}
"set" => {
let max = match words.next() {
let pref_max_prs = match words.next() {
Some(max_value) => {
if words.next().is_some() {
anyhow::bail!("Too many parameters.");
}
max_value
.parse::<u32>()
.context("Wrong parameter format. Must be a positive integer.")?
max_value.parse::<u32>().context(
"Wrong parameter format. Must be a positive integer (and fit a u32).",
)?
}
None => anyhow::bail!("Missing parameter."),
};
set_review_prefs(&db_client, gh_id, max)
set_review_prefs(&db_client, gh_id, pref_max_prs)
.await
.context("Error occurred while setting review preferences.")?
.context("Could not set review preferences")?;
format!("Review capacity set to {}", pref_max_prs)
}
_ => anyhow::bail!("Invalid subcommand."),
};

Ok(Some(record.to_string()))
Ok(Some(reply))
}

// This does two things:
Expand Down

0 comments on commit e701af8

Please sign in to comment.