4 releases
| 0.1.0 | Oct 7, 2025 |
|---|---|
| 0.0.3 | Sep 22, 2025 |
| 0.0.2 | Sep 19, 2025 |
| 0.0.1 | Sep 19, 2025 |
#466 in HTTP server
179 downloads per month
1.5MB
2K
SLoC
Octofer
A framework for building GitHub Apps, in Rust
⚠️ Under Development - This framework is currently in active development and may have bugs and issues.
A framework for building GitHub Apps in Rust, inspired by Probot. Octofer provides a clean, type-safe way to build GitHub Apps with minimal boilerplate and automatic webhook handling.
What is Octofer?
Octofer simplifies GitHub App development by:
- Handling webhook events - Automatically receives and routes GitHub webhook events
- Managing authentication - Handles GitHub App authentication and installation tokens
- Providing type safety - Full Rust type safety for GitHub API interactions
- Offering simple APIs - Clean, intuitive event handler registration
🛠️ Looking for a full production-ready example? Check out frezze! A bot that you can use to schedule "freeze" periods for your repo, blocking all PR merges for specific periods of time!
Available Event Handlers
GitHub webhook events supported by Octofer (depends on octocrab):
Issues & Pull Requests
on_issue()- Issue events (opened, closed, edited, etc.)on_issue_comment()- Issue comment events (created, edited, deleted)on_pull_request()- Pull request events (opened, closed, merged, etc.)on_pull_request_review()- Pull request review eventson_pull_request_review_comment()- Pull request review comment eventson_pull_request_review_thread()- Pull request review thread events
Repository & Git
on_push()- Push eventson_create()- Branch/tag createdon_delete()- Branch/tag deletedon_fork()- Repository forkedon_commit_comment()- Comment on commiton_gollum()- Wiki page updateon_public()- Repository made publicon_repository()- Repository eventson_repository_dispatch()- Repository dispatchon_repository_import()- Repository importon_branch_protection_rule()- Branch protection rule events
Workflows & Actions
on_workflow_run()- Workflow run eventson_workflow_job()- Workflow job eventson_workflow_dispatch()- Workflow dispatch eventson_status()- Commit status events
Checks & Security
on_check_run()- Check run eventson_check_suite()- Check suite eventson_code_scanning_alert()- Code scanning alertson_secret_scanning_alert()- Secret scanning alertson_secret_scanning_alert_location()- Secret scanning alert locationon_dependabot_alert()- Dependabot alertson_repository_vulnerability_alert()- Repository vulnerability alertson_security_advisory()- Security advisory eventson_repository_advisory()- Repository advisory eventson_security_and_analysis()- Security and analysis events
Deployments
on_deployment()- Deployment eventson_deployment_status()- Deployment status eventson_deploy_key()- Deploy key eventson_deployment_protection_rule()- Deployment protection rule events
Discussions
on_discussion()- Discussion eventson_discussion_comment()- Discussion comment events
Projects
on_project()- Project (classic) eventson_project_card()- Project card eventson_project_column()- Project column eventson_projects_v2()- Projects v2 eventson_projects_v2_item()- Projects v2 item events
Teams & Organizations
on_team()- Team eventson_team_add()- Team add eventson_member()- Member eventson_membership()- Membership eventson_organization()- Organization eventson_org_block()- Org block events
Releases & Packages
on_release()- Release eventson_package()- Package eventson_registry_package()- Registry package events
Installations & Apps
on_installation()- Installation eventson_installation_repositories()- Installation repositories eventson_installation_target()- Installation target eventson_github_app_authorization()- GitHub App authorization eventson_personal_access_token_request()- Personal access token request events
Miscellaneous
on_label()- Label eventson_milestone()- Milestone eventson_watch()- Watch (star) eventson_star()- Star eventson_ping()- Ping eventson_meta()- Meta eventson_page_build()- Page build eventson_schedule()- Schedule eventson_sponsorship()- Sponsorship eventson_marketplace_purchase()- Marketplace purchase eventson_merge_group()- Merge group events
Quick Example
Check the examples directory or the example below:
use std::sync::Arc;
use octofer::{Octofer, Config};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let config = Config::from_env().unwrap_or_default();
config.init_logging();
let mut app = Octofer::new(config).await.unwrap_or_else(|_| {
Octofer::new_default()
});
// Handle issue comments
app.on_issue_comment(
|context, _| async move {
println!("Issue comment event received!");
println!("Event type: {}", context.kind());
if let Some(client) = &context.github_client {
// Use GitHub API client here
println!("GitHub client available for API calls");
}
Ok(())
},
Arc::new(()),
).await;
app.start().await?;
Ok(())
}
Configuration
Octofer uses a centralized configuration system that loads from environment variables:
# Required for GitHub App authentication
export GITHUB_APP_ID=your_app_id
export GITHUB_PRIVATE_KEY_PATH=path/to/private-key.pem
# OR
export GITHUB_PRIVATE_KEY_BASE64=base64_encoded_key
# Webhook
export GITHUB_WEBHOOK_SECRET=your_webhook_secret
# Server configuration (optional)
export OCTOFER_HOST=127.0.0.1 # Default: 127.0.0.1
export OCTOFER_PORT=8000 # Default: 8000
# Logging configuration (optional)
export OCTOFER_LOG_LEVEL=info # Default: info (trace, debug, info, warn, error)
export OCTOFER_LOG_FORMAT=compact # Default: compact (compact, pretty, json)
export OCTOFER_LOG_WITH_TARGET=false # Default: false (show target module)
export OCTOFER_LOG_WITH_FILE=false # Default: false (show file and line info)
export OCTOFER_LOG_WITH_THREAD_IDS=false # Default: false (show thread IDs)
You can also create configuration programmatically:
use octofer::Config;
let config = Config::new(
123456, // app_id
Some("path/to/private-key.pem".to_string()), // private_key_path
None, // private_key_base64
"your-webhook-secret".to_string(), // webhook_secret
std::net::Ipv4Addr::LOCALHOST, // host
8000, // port
)?;
// Initialize logging with the configuration
config.init_logging();
Development
Build all components:
cargo build
Run tests:
cargo test
Code Quality
Format code:
cargo fmt
Run linting:
cargo clippy -- -D warnings
Features
- Centralized Configuration: All configuration managed through a single
Configstruct - Environment Variable Support: Automatic loading from environment variables
- GitHub Client Access: Direct access to authenticated GitHub clients from event handlers
- Modular Architecture: Clean separation of concerns across modules
- Type Safety: Full Rust type safety for GitHub API interactions
- Automatic Token Management: GitHub App installation token caching and refresh
- Middleware Support: HMAC verification and event processing middleware
Event Handler Context
Event handlers receive a Context object that provides access to:
- Event data:
context.payload()- The full GitHub webhook payload - Event:
context.event()- The full GitHub webhook event - Event type:
context.kind()- The type of event (e.g., "issues", "issue_comment") - Installation ID:
context.installation_id()- GitHub App installation ID - GitHub client:
context.github()- Authenticated GitHub API client - Installation client:
context.installation_client()- Installation-specific authenticated client
Examples
The repository includes several examples:
basic.rs- Simple GitHub App with event handlers.github_client.rs- Direct GitHub API client usage
License
MIT
Dependencies
~16–32MB
~445K SLoC