Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tooling: add dapr-bot - assign issue functionality #131

Merged
merged 8 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/dapr-bot-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: dapr-bot-test

on:
push:
paths: # Explicitly declare which paths (could potentially be combined into dapr-bot*
- ".github/workflows/dapr-bot.yml"
- ".github/workflows/dapr-bot-test.yml"
- ".github/workflows/dapr-bot/*"
pull_request:
branches:
- master
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to main

paths: # Explicitly declare which paths (could potentially be combined into dapr-bot*
- ".github/workflows/dapr-bot.yml"
- ".github/workflows/dapr-bot-test.yml"
- ".github/workflows/dapr-bot/*"

env:
CARGO_TERM_COLOR: always

jobs:

test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./.github/workflows/dapr-bot
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable

- uses: swatinem/rust-cache@v2
- name: Cargo clippy
run: |
cargo clippy -- -W warnings

- name: Cargo fmt
run: |
cargo fmt -- --check --color ${{ env.CARGO_TERM_COLOR }}

- name: Cargo test
run: |
cargo test

- name: Cargo build
run: |
cargo build
21 changes: 21 additions & 0 deletions .github/workflows/dapr-bot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: dapr-bot
on:
issue_comment:
types: [created]
env:
CARGO_TERM_COLOR: always
jobs:
run:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./.github/workflows/dapr-bot
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
- name: Cargo run
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
cargo run
15 changes: 15 additions & 0 deletions .github/workflows/dapr-bot/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "dapr-bot"
authors = ["[email protected]"]
license-file = "LICENSE"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
exitcode = "1.1.2"
octocrab = "0.34.1"
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"
tokio = { version = "1.36.0", features = ["full"] }
28 changes: 28 additions & 0 deletions .github/workflows/dapr-bot/src/github/issues.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use super::GitHub;

impl GitHub {
pub async fn create_comment(
&self,
owner: &str,
repo: &str,
number: u64,
comment: String,
) -> std::result::Result<octocrab::models::issues::Comment, octocrab::Error> {
self.client
.issues(owner, repo)
.create_comment(number, comment)
.await
}
pub async fn add_assignee(
&self,
owner: &str,
repo: &str,
number: u64,
assignee: String,
) -> std::result::Result<octocrab::models::issues::Issue, octocrab::Error> {
self.client
.issues(owner, repo)
.add_assignees(number, &[&assignee])
.await
}
}
18 changes: 18 additions & 0 deletions .github/workflows/dapr-bot/src/github/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use octocrab::Octocrab;

pub mod issues;

pub struct GitHub {
client: Octocrab,
}

impl GitHub {
pub fn new_client(token: String) -> GitHub {
match Octocrab::builder().personal_token(token).build() {
Ok(client) => GitHub { client },
Err(e) => {
panic!("Unable to create client: {:?}", e)
}
}
}
}
94 changes: 94 additions & 0 deletions .github/workflows/dapr-bot/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
mod github;

use core::panic;
use std::{error::Error, fs::File, io::BufReader, path::Path, process::exit};

use octocrab::models;

use github::GitHub;

// Defining the repo explicitly as the octocrab model for the event doesn't deserialize a
// owner/repo.
const OWNER: &str = "dapr";
const REPOSITORY: &str = "rust-sdk";

const GITHUB_TOKEN: &str = "GITHUB_TOKEN";

const GITHUB_EVENT_PATH: &str = "GITHUB_EVENT_PATH";
const GITHUB_EVENT_NAME: &str = "GITHUB_EVENT_NAME";

const ISSUE_COMMENT_EVENT_NAME: &str = "issue_comment";

fn get_payload<P: AsRef<Path>>(
path: P,
) -> Result<models::events::payload::IssueCommentEventPayload, Box<dyn Error>> {
// Open the file in read-only mode with buffer.
let file = File::open(path)?;
let reader = BufReader::new(file);

// Read the JSON contents of the file as an instance.
let event = serde_json::from_reader(reader)?;

// Return the event.
Ok(event)
}

#[tokio::main]
async fn main() -> octocrab::Result<()> {
let github_event_path: String =
std::env::var(GITHUB_EVENT_PATH).expect("GITHUB_EVENT_PATH env missing");
let github_event_name: String =
std::env::var(GITHUB_EVENT_NAME).expect("GITHUB_EVENT_NAME env missing");
let github_token: String = std::env::var(GITHUB_TOKEN).expect("GITHUB_TOKEN env missing");

if github_event_name != ISSUE_COMMENT_EVENT_NAME {
println!("Event is not an issue_comment, the app will now exit.");
exit(exitcode::TEMPFAIL);
}

// deserialize event payload
let event = get_payload(github_event_path).unwrap();

// check the issue body
if !event.clone().comment.body.unwrap().starts_with("/assign") {
println!("Event does not start with /assign");
exit(exitcode::TEMPFAIL);
}

let assignee: String = event.comment.user.login;

let issue: u64 = event.issue.number;

// spawn a client
let github_client = GitHub::new_client(github_token);

// assign the user
match github_client
.add_assignee(OWNER, REPOSITORY, issue, assignee.clone())
.await
{
Ok(_) => {
match github_client
.create_comment(
OWNER,
REPOSITORY,
issue,
format!("🚀 issue assigned to you {assignee}"),
)
.await
{
Ok(_) => {
println!("Comment on assign successful")
}
Err(e) => {
panic!("Comment on assign failed: {:?}", e)
}
}
}
Err(e) => {
panic!("Failed to assign issue: {:?}", e)
}
}

Ok(())
}
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ This section describes the guidelines for contributing code / docs to Dapr.
All contributions come through pull requests. To submit a proposed change, we recommend following this workflow:

1. Make sure there's an issue (bug or proposal) raised, which sets the expectations for the contribution you are about to make.
- Assign yourself to the issue by commenting with `/assign`
1. Fork the relevant repo and create a new branch
1. Create your change
- Code changes require tests
Expand Down
Loading