GitHub App to Freeze activity in your repo!
A GitHub App built in Rust that manages repository freezes through comment commands. Temporarily restrict repository access during deployments, maintenance, or critical operations.
Built with Octofer.
demo.mp4
- Comment-based commands - Control freezes directly from GitHub issues/PRs
- Flexible scheduling - Set freeze duration or schedule for specific times
- Organization-wide freezes - Freeze all repositories at once
- PR unlock system - Selectively allow PRs to merge during freezes
- Audit logging - Track all freeze/unfreeze actions in SQLite database
- Permission system - Role-based access control with configurable permissions
- PR refresh system - Automatically sync PR check runs with freeze status
- Multiple duration formats - Support both simple (2h, 30m) and ISO 8601 formats
- Real-time status updates - Check freeze status across multiple repositories
All commands are used in GitHub issue or PR comments:
/freeze- Freeze current repository/freeze --repo owner/repo1,owner/repo2- Freeze specific repositories/freeze-all- Freeze all repositories in organization/freeze-all --repo owner/repo1,owner/repo2- Freeze specific repositories/unfreeze- Unfreeze current repository/unfreeze-all- Unfreeze all repositories in organization/status- Show current freeze status/unlock-pr- Unlock a specific PR during a freeze
/freeze --duration 2h- Freeze for 2 hours/freeze --reason "Release v1.2.3"- Freeze with reason/freeze --duration 1d --reason "Emergency maintenance"- Combined options/freeze --repo owner/repo1,owner/repo2 --duration 2h- Freeze specific repos for 2 hours/freeze --repo owner/repo1 --repo owner/repo2- Freeze multiple repos using separate flags/freeze-all --repo owner/repo1,owner/repo2- Freeze only specific repos instead of all/schedule-freeze --from "2024-01-15T10:00:00Z" --duration 2h- Schedule freeze/status --repos repo1,repo2- Check status for specific repositories/unlock-pr --pr-number 123- Unlock specific PR by number/unlock-pr --reason "emergency"- Unlock current PR with reason/unfreeze --reason "Issue resolved"- Unfreeze with reason
Branch-based freezes allow you to freeze only PRs targeting a specific branch (e.g., main, develop), while development in other branches continues unaffected.
Usage Examples:
/freeze --branch main- Freeze only PRs merging into the main branch/freeze --branch main --duration 2h --reason "Production deployment"- Freeze main branch for 2 hours/freeze-all --branch main- Freeze main branch across all repositories/unfreeze --branch main- Unfreeze only the main branch/schedule-freeze --from "2024-01-15T10:00:00Z" --duration 2h --branch main- Schedule branch-specific freeze
Important Notes:
- When
--branchis not specified, the freeze applies to all branches (default behavior) - A repository can have multiple active freezes for different branches simultaneously
- Each branch freeze is tracked independently and can be unfrozen separately
- Branch-based freezes work with all freeze commands (
freeze,freeze-all,schedule-freeze)
- Simple:
2h,30m,1d,45s - ISO 8601:
PT2H30M,P1D,PT45S
The /unlock-pr command allows you to temporarily unlock specific pull requests during a repository freeze, enabling them to be merged despite the freeze restrictions.
Usage Examples:
/unlock-pr- Unlock the current PR (when used in a PR comment)/unlock-pr --pr-number 123- Unlock PR #123 (can be used from any issue/PR)/unlock-pr --pr-number 123 --reason "Critical security fix"- Unlock with reason
Important Notes:
- Only works when the repository is currently frozen
- Requires appropriate permissions (maintainer or admin role)
- The unlock remains active until the next freeze starts
- PRs are automatically refreshed with updated check run status
Emergency freeze during incident:
/freeze --duration 2h --reason "Production incident - investigating database issues"
Scheduled maintenance window:
/schedule-freeze --from "2024-12-01T02:00:00Z" --duration 4h --reason "Database maintenance"
Organization-wide code freeze:
/freeze-all --duration 1d --reason "End-of-quarter freeze before major release"
Freeze main branch only (allow development in feature branches):
/freeze --branch main --duration 2h --reason "Production deployment in progress"
Organization-wide freeze of main branches:
/freeze-all --branch main --duration 4h --reason "Critical security patch deployment"
Freeze specific repositories:
/freeze --repo owner/frontend,owner/backend --duration 3h --reason "Deployment in progress"
or using multiple --repo flags:
/freeze-all --repo owner/repo1 --repo owner/repo2 --duration 2h
Quick status check:
/status --repos frontend,backend,api
Emergency PR during freeze:
/unlock-pr --pr-number 456 --reason "Critical hotfix for production issue"
Manual unfreeze:
/unfreeze --reason "Issue resolved"
The PR refresh system ensures that all open pull requests have up-to-date check runs that reflect the current freeze status. This is essential for scheduled freezes and maintaining consistency.
- Scheduled Check - The system queries for active freeze records that should be enforced
- PR Discovery - For each repository with active freezes, it fetches all open pull requests
- Status Evaluation - Determines if the freeze is currently active based on start/end times
- Check Run Update - Creates GitHub check runs with success/failure status based on freeze state
- Error Handling - Logs errors for individual PRs without stopping the entire process
- Rust 1.70+
- SQLite (included with Rust build)
- GitHub App credentials
Finch is a OSS client for docker. Substitute finch with docker in the commands below if you're using docker.
# Using docker/ compose
finch compose up -d
# Or using docker run
finch run --rm \
-e DATABASE_URL="sqlite:/frezze.db" \
-e GITHUB_APP_ID=123456 \
-e GITHUB_PRIVATE_KEY_PATH=/.privatekey.pem \
-e GITHUB_WEBHOOK_SECRET=mysecret \
-e OCTOFER_HOST=0.0.0.0 \
-e OCTOFER_PORT=3000 \
-v ./.privatekey.pem:/.privatekey.pem:ro \
-v ./users.yaml:/users.yaml:ro \
-p 3000:3000 \
--restart unless-stopped \
ghcr.io/abelhristodor/frezze:latest# Clone and build
git clone https://github.com/AbelHristodor/frezze.git
cd frezze
cargo build
# Setup database (SQLite file will be created automatically)
make migrate
# Run application
make runCopy .env.example to .env and configure:
DATABASE_URL=sqlite:frezze.db?mode=rwc
GITHUB_APP_ID=your_app_id
GITHUB_PRIVATE_KEY_PATH=path/to/private-key.pem
WEBHOOK_SECRET=your_webhook_secret
PERMISSIONS_PATH=users.yaml # check PERMISSIONS.md
PORT=3000Make sure to check PERMISSIONS.md for more information regarding the permission system.
make help # Show all available commands
make build # Build the application
make test # Run tests
make run # Start the server
make migrate # Run database migrationssrc/
├── main.rs # Application entry point
├── freezer/ # Core freeze management
│ ├── commands.rs # Command parsing
│ ├── manager.rs # Freeze operations
│ └── pr_refresh.rs # PR check run refresh system
├── github/ # GitHub API integration
├── database/ # Database models and operations
├── server/ # Web server and webhook handlers
└── config/ # Configuration management
- GitHub Webhook - Receives issue/PR comment events
- Command Parsing - Extracts freeze commands from comments using clap parser
- Permission Check - Validates user permissions against YAML configuration
- Branch Protection - Applies/removes GitHub branch protection rules
- Database Logging - Records all freeze/unlock operations in SQLite
- PR Refresh - Updates check runs on all open PRs to reflect freeze status
- PR Unlock Management - Tracks individually unlocked PRs during freezes
- Response - Posts formatted status update as GitHub comment