https://github.com/mihaigiurgeanu/pr-tools
Decentralized git pull request and code review flows
https://github.com/mihaigiurgeanu/pr-tools
cli code-review git pull-request
Last synced: 4 months ago
JSON representation
Decentralized git pull request and code review flows
- Host: GitHub
- URL: https://github.com/mihaigiurgeanu/pr-tools
- Owner: mihaigiurgeanu
- License: bsd-3-clause
- Created: 2025-07-16T23:56:38.000Z (12 months ago)
- Default Branch: master
- Last Pushed: 2025-08-02T16:41:21.000Z (11 months ago)
- Last Synced: 2025-10-21T13:59:30.368Z (9 months ago)
- Topics: cli, code-review, git, pull-request
- Language: Haskell
- Homepage:
- Size: 123 KB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 18
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# PR Tools
A set of command-line tools for managing descentralized git pull requests and code review workflows. These tools help with creating PR snapshots, sending notifications to Slack, tracking approvals, merging PRs, reviewing changes, and viewing annotated diffs.
Please read the [motivation](https://copilot.microsoft.com/shares/pages/VKL8KZ8pMhsYY68x7TZsr) for a more in-depth info about the purpose of these tools.
## Features
- **pr-snapshot**: Generate a Markdown snapshot of the PR including commits and diff summary.
- **pr-send**: Send the PR snapshot to a Slack channel for review.
- **pr-track**: Track PR approvals, status, and commit history.
- **pr-merge**: Merge approved PRs with various strategies and update changelog.
- **pr-review**: Interactive code review tool with comment management.
- **pr-view**: View annotated diffs with review comments.
- **pr-fix**: Fix comments received in a review.
- **pr-init**: Interactively generate configuration file for pr-tools.
## Installation
This project is built with Haskell and Cabal. To install:
1. Ensure you have [GHC](https://www.haskell.org/ghc/) and [Cabal](https://www.haskell.org/cabal/) installed. Use [GHCup](https://www.haskell.org/ghcup/) for easy installation.
- For Windows, you can use the [Haskell Platform](https://www.haskell.org/platform/).
- For macOS, you can install GHC and Cabal via Homebrew:
```
brew install ghc cabal-install
```
2. Clone the repository:
```
git clone
cd pr-tools
```
3. Build and install the executables:
```
cabal update
cabal install
```
This will install the binaries in `~/.cabal/bin` (or equivalent). Add this directory to your PATH if necessary.
## How to upgrade from source
Update the source tree and reinstall:
cd pr-tools
git checkout master && git pull && cabal install --overwrite-policy=always
## Configuration
## Slack Configurations
PR Tools supports two Slack integration methods: Incoming Webhooks for simple text messages and Slack API Tokens for advanced features like file attachments. Webhooks are easier to set up and sufficient for basic notifications, while API Tokens enable uploading detailed content as files, improving readability for long messages (e.g., reviews or snapshots). If both are configured, the tool prioritizes API Tokens for commands that benefit from attachments; otherwise, it falls back to webhooks.
### Webhook Configuration
Webhooks allow posting plain text messages to a Slack channel. This is ideal for short notifications but may truncate or clutter long content.
To obtain a webhook:
1. Go to [Slack Apps](https://api.slack.com/apps) and create a new app.
2. Enable "Incoming Webhooks" under "Add features & functionality".
3. Activate webhooks and add one to a channel, copying the generated URL (starts with `https://hooks.slack.com/services/`).
Add to your `.pr-tools.yaml`:
```yaml
slack-webhook: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
```
If not set, commands like `pr-send` will fail, and others (e.g., `pr-merge`) will skip notifications.
### Slack API Token Configuration
API Tokens enable file attachments, allowing detailed messages (e.g., from `pr-review send`, `pr-fix send`, `pr-send`) to be uploaded as .md files with a short summary message. This requires a bot token with `files:write` scope.
To obtain a token:
1. Go to [Slack Apps](https://api.slack.com/apps) and create a new app.
2. Under "Add features & functionality", select "Bots" and create a bot user.
3. Under "OAuth & Permissions", add the `files:write` scope (and optionally `chat:write` for messages).
4. Install the app to your workspace, granting permissions.
5. Copy the "Bot User OAuth Token" (starts with `xoxb-`).
6. Find the channel ID: In Slack, right-click the channel, select "View channel details", and copy the ID (starts with `C` or `G`).
7. Invite the `pr-tools` bot to the channel:
```
/invite @pr-tools
```
Add to your `.pr-tools.yaml`:
```yaml
slack-token: "xoxb-your-bot-token"
slack-channel: "C0123456789" # Channel ID
```
### Base Branch and Slack Configuration
Use `pr-init` or manually create a `.pr-tools.yaml` file in the project root with:
```yaml
base-branch: main # or your default base branch
slack-webhook: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX" # optional
slack-token: "xoxb-your-bot-token" # optional for attachments
slack-channel: "C0123456789" # required if using token
```
### Recommended .gitignore Entries
To avoid committing temporary files generated by pr-tools, add the following to your `.gitignore` file:
```
.pr-drafts/
.pr-reviews/
.pr-fixes/
.pr-state.yaml
.pr-tools.yaml # Optional, if you don't want to commit the config
```
## Usage
### pr-snapshot
Generate a Markdown snapshot of the PR including commits and diff summary. The snapshot is saved in .pr-drafts/.md. If no message is provided, it opens an editor to enter the description.
```
pr-snapshot [BRANCH] [--base-branch BASE] [--message MESSAGE]
```
- `BRANCH`: The feature branch (default: current branch).
- `--base-branch BASE`: Override the configured base branch.
- `--message MESSAGE`, `-m MESSAGE`: Provide the PR description directly without opening an editor.
### pr-send
Send the PR snapshot to a Slack channel for review. Requires slack-webhook configured.
```
pr-send [BRANCH]
```
- `BRANCH`: The feature branch (default: current branch).
### pr-track
Track PR approvals and status.
Subcommands:
```
pr-track approve [BRANCH] --by NAME
pr-track status [BRANCH]
pr-track record [BRANCH]
pr-track update [BRANCH]
pr-track list
pr-track rebase --old-commit HASH [--branch BRANCH] [--new-commit HASH]
```
- `approve [BRANCH] --by NAME`: Approve the PR by the given name. `BRANCH` defaults to current.
- `status [BRANCH]`: Get the status, approvals, review status, and merge status for the PR. Checks if commits are merged into the base branch, validates approvals against current content, and shows if the current content has been reviewed. `BRANCH` defaults to current.
- `record [BRANCH]`: Record or update the commit snapshot for the PR. Synonyms: update, u, r, rec. `BRANCH` defaults to current.
- `list`: List all tracked PRs with status and approval counts.
- `rebase --old-commit HASH [--branch BRANCH] [--new-commit HASH]`: Transfer approvals after a rebase if the content hasn't changed. `BRANCH` defaults to current, `--new-commit` defaults to current HEAD.
### pr-merge
Merge approved PRs with various strategies and update changelog. Optionally sends notification to Slack.
```
pr-merge [BRANCH] [--strategy {fast-forward|squash|rebase}] [--base-branch BASE]
```
- `BRANCH`: The feature branch (default: current).
- `--strategy STRATEGY`: Merge strategy (default: fast-forward).
- `--base-branch BASE`: Override the configured base branch.
### pr-review
Interactive code review tool with comment management.
Subcommands:
```
pr-review [--all] start [--base-branch BASE]
pr-review [--all] next
pr-review [--all] previous
pr-review [--all] open
pr-review files
pr-review changes
pr-review comment --file FILE --line LINE --text "COMMENT"
pr-review resolve --id ID
pr-review end
pr-review list
pr-review send
pr-review comments [--all] [--with-context]
```
- `start [--base-branch BASE]`: Start or resume a review session. `--base-branch` overrides configured base.
- `next`: Move to the next file and open in editor for commenting.
- `previous`: Move to the previous file and open in editor.
- `open`: Open the current file in editor for commenting.
- `files`: List files with changes, indicating current.
- `changes`: Show the git diff.
- `comment --file FILE --line LINE --text "COMMENT"`: Add a comment via CLI.
- `resolve --id ID`: Mark a comment as resolved.
- `end`: End the review session and record the content hash of the reviewed commits.
- `list`: List all review sessions.
- `send`: Send the review comments to Slack.
- `comments [--with-context] [--all]`: List comments,By default, shows unresolved comments. Use `--all` for all, or `--resolved` for only resolved. `--with-context` adds surrounding code.
### pr-view
View annotated diff or comments.
Subcommands:
```
pr-view diff [BRANCH] [--base-branch BASE] [--full]
pr-view comments [BRANCH]
```
- `diff [BRANCH] [--base-branch BASE] [--full]`: Show annotated diff with comments. `--full` shows complete files including unchanged areas. `BRANCH` defaults to current.
- `comments [BRANCH]`: List all comments with context. `BRANCH` defaults to current.
- `--base-branch BASE`: Override the configured base branch.
### pr-fix
Manage fix sessions for review comments.
Subcommands:
```
pr-fix start
pr-fix comments [--with-context]
pr-fix files
pr-fix open
pr-fix next
pr-fix previous
pr-fix resolve --id ID --status STATUS [--answer "Explanation"]
pr-fix end
pr-fix send
```
- `start`: Start a fix session by pasting review comments into an editor.
- `comments [--with-context]`: Display comments, optionally with context.
- `files`: List files with comments, indicating current.
- `open`: Open current file with comments inserted for editing and updating status/answers.
- `next`: Move to next file and open.
- `previous`: Move to previous file and open.
- `resolve --id ID --status STATUS [--answer "EXPLANATION"]`: Update comment status (e.g., solved, not-solved, will-not-solve) and optional answer via CLI.
- `end`: End the fix session, requires changes to be committed.
- `send`: Send fix summary to Slack.
### pr-init
Interactively generate or update configuration file (.pr-tools.yaml) for pr-tools, prompting for base-branch, optional slack-webhook, slack-token, slack-channel, and stale-days (with current values as defaults if updating). Also updates .gitignore with recommended entries.
```
pr-init
```
No additional flags.
## Sample Workflow
1. **Create a Feature Branch**: Developer creates a branch, makes changes, and commits.
2. **Generate Snapshot**: Run `pr-snapshot` to create a Markdown description of the PR.
3. **Send to Slack**: Run `pr-send` to notify the team via Slack.
4. **Track Approvals**: Team members approve using `pr-track approve ` or Slack reactions.
5. **Conduct Review**: Reviewer runs `pr-review start`, navigates files with `next`/`open`, adds comments, then `pr-review send` to send compact review to Slack.
6. **Fix Comments**: Developer runs `pr-fix start`, pastes the Slack review message, navigates with `pr-fix next`/`open` to edit files and mark comments (solved/not-solved/will-not-solve), adds answers, or use `pr-fix resolve` for CLI updates, then `pr-fix end` to commit changes, and `pr-fix send` to report back via Slack.
7. **View Annotated Diff**: Anyone can run `pr-view ` to see changes with comments (use --full for full files or `pr-view comments` for comment list).
8. **Handle Rebases**: If you need to rebase before merging, run `pr-track rebase --old-commit ` after rebasing to transfer approvals if content hasn't changed.
9. **Merge PR**: Once approved, run `pr-merge ` to merge and update changelog.
This workflow enables collaborative reviews without committing review files to the repo, using Slack for communication. The approval system now handles rebases intelligently by tracking both commit IDs and content hashes.
## Contributing
Contributions are welcome! Please open an issue or submit a pull request.
## License
This project is licensed under the BSD-3-Clause License.