Skip to content

vxsl/dev-workflow-tools

Repository files navigation

dev-workflow-tools

Interactive Git + Jira + GitLab workflow tools with fzf interfaces.

Installation

cd ~/bin
git clone <repo-url> dev-workflow-tools
cd dev-workflow-tools
cp .env.example .env
# Edit .env with your Jira credentials

Add to ~/.zshrc:

source ~/bin/dev-workflow-tools/shell/dev-workflow.zsh

Dependencies

Required: git, fzf, jq, curl, glab Optional:

  • tmux (for pane management + auto-clear refresh summary)
  • xdotool (Linux X11 only - for auto-clear refresh summary outside tmux)
  • xclip, bat, eza, fd, wmctrl

Configuration

Edit .env:

JIRA_DOMAIN="<your-company>.atlassian.net"
JIRA_PROJECT="<PROJ|DEV|ENG>"
JIRA_EMAIL="your-email@company.com"
JIRA_API_TOKEN="your-api-token"

# Optional - your JIRA username (for branch highlighting in rr)
JIRA_ME="your-jira-username"
TICKET_CREATOR_BOT_TOKEN="xoxb-..."
FZF_PERSIST_MODE=1  # For xmonad scratchpads/tmux popups

# QA Branch Integration (for publish-changes)
JIRA_QA_BRANCH_FIELD="customfield_12345"  # Auto-detected if not set
JIRA_QA_BRANCH_DOMAIN="qa.example.com"    # Single domain or comma/space-separated list

Get Jira API token: https://id.atlassian.com/manage-profile/security/api-tokens

Required Jira API Token Scopes

When creating your API token, select these granular scopes:

Scope Used for
read:jira-work Searching/reading issues, projects, statuses, priorities
write:jira-work Creating issues, adding comments, transitioning statuses, updating fields
read:jira-user Reading current user info (/myself endpoint)
read:board:jira-software Fetching boards for sprint assignment (create-jira-ticket)
read:sprint:jira-software Fetching active sprints (create-jira-ticket)
write:sprint:jira-software Adding issues to sprints (create-jira-ticket)

Note: If classic scopes are available, read:jira-work + write:jira-work + read:jira-user cover everything except Agile board/sprint features.

Slack Bot Token

The TICKET_CREATOR_BOT_TOKEN is used by oneshot to post ticket and MR links to Slack threads. The bot requires these OAuth scopes:

  • chat:write - Post messages to channels/threads
  • channels:read - Verify bot membership in public channels
  • groups:read - Verify bot membership in private channels

To add these scopes:

  1. Go to https://api.slack.com/apps → Your App → OAuth & Permissions
  2. Add the scopes under "Bot Token Scopes"
  3. Reinstall the app to your workspace
  4. Copy the "Bot User OAuth Token" (starts with xoxb-) to .env

Note: The bot must be added to channels before it can post. Use /invite @your-bot-name in the channel.

QA Branch Integration

When creating a merge request with publish-changes, the tool can automatically set a "QA Branch" field in your Jira ticket. This is useful if your workflow includes deploying feature branches to QA environments.

Configuration:

  • JIRA_QA_BRANCH_DOMAIN - The domain(s) where QA branches are deployed (e.g., "qa.example.com")
    • Supports multiple domains: "qa1.example.com,qa2.example.com" or "qa1.example.com qa2.example.com"
    • Multiple domains will show an fzf menu to select which one to use
    • The branch name will be formatted as: branch-name.qa.example.com
  • JIRA_QA_BRANCH_FIELD - The custom field ID in Jira (e.g., "customfield_12345")
    • If not set, the tool will auto-detect fields matching "QA Branch" or "Branch QA"

Example:

JIRA_QA_BRANCH_DOMAIN="qa.example.com"
# When you create an MR from branch "PROJ-123", Jira will show: PROJ-123.qa.example.com

FZF Persist Mode

By default, fzf tools exit after selection (normal CLI behavior). Set FZF_PERSIST_MODE=1 if using xmonad scratchpads or tmux popups to keep the interface open after actions.

Worktree Customization

Automatically customize new worktrees when created via create-wt or rr's F2/F3 keybindings.

Exclude Build Artifacts (skip copying large directories):

# Skip Rust's target/ directory (can be hundreds of MB)
WORKTREE_COPY_EXCLUDE="target/"

# Multiple patterns
WORKTREE_COPY_EXCLUDE="target/ build/ dist/ *.log"

VS Code Settings (simple JSON merge):

# Disable Rust analyzer in all new worktrees
VSCODE_WORKSPACE_SETTINGS='{"rust-analyzer.enable": false}'

# Multiple settings
VSCODE_WORKSPACE_SETTINGS='{"rust-analyzer.enable": false, "editor.formatOnSave": true}'

Post-Worktree Hook (arbitrary customization):

POST_WORKTREE_HOOK="/home/username/bin/my-worktree-setup.sh"

See WORKTREE_CUSTOMIZATION.md for detailed examples and use cases.

Tools

jira-fzf

Browse/search Jira tickets, create new tickets, checkout branches, create MRs.

Usage: jira-fzf [--persist] [--one-shot] [--dry-run] [--labels "bug,ui"]

  • --persist - Keep open after actions (for scratchpads/tmux popups)
  • --one-shot - Exit after selection (default)

Keys: <CR> maximize | ^y copy | ^o open | ^t new ticket | ^g create MR | ^c checkout | ^s sort | ^r refresh

create-jira-ticket

Create Jira tickets with interactive prompts.

create-jira-ticket                       # Interactive
create-jira-ticket --summary "Fix bug"   # Quick
create-jira-ticket --slack-url URL       # Link to Slack

oneshot (alias: os)

One-shot workflow: staged changes → branch → commit → MR.

oneshot                    # Interactive
oneshot PROJ-1234          # Use ticket
oneshot https://slack...   # From Slack thread

publish-changes

Create GitLab MRs with Jira integration.

publish-changes                # Interactive
publish-changes PROJ-1234      # With ticket
publish-changes --draft        # Draft MR

rr.sh (alias: r)

Recent branches with Jira info.

r           # Recent local branches
r -o        # Remote branches
r -r        # Refresh cache

Keys: ^l load more | ^o toggle local/remote | ^r refresh (shows summary for 2.5s, auto-clears) | F2 new worktree | F3 new branch+wt | F8 delete wt

Refresh Auto-Clear: The refresh summary automatically clears after 2.5 seconds when using:

  • tmux - Works in any tmux session
  • macOS - Uses built-in osascript (no extra install needed)
  • Linux X11 - Requires xdotool package

If auto-clear is unavailable, the summary will show installation instructions or indicate it will persist.

Display Columns:

  1. Branch - Branch name with indicators
  2. Title - JIRA ticket summary
  3. Status - JIRA ticket status
  4. Assignee - JIRA ticket assignee
  5. Checked - When you last checked out this branch/worktree
  6. Committed - When the last commit was made

Branch Emphasis (requires JIRA_ME in .env):

  • ★ Bright purple - Your authoritative branch (exact ticket: UB-6493)
  • · Dimmed purple - Your variant branch (ticket + suffix: UB-6493-wip)
  • Gray (no symbol) - Other branches (not assigned to you)

Visual Indicators:

  • Worktree exists
  • Worktree status (green=clean, orange=dirty)

Tmux Pane Management (Optional)

You can configure rr to manage specific tmux panes (e.g., dev server, tsc-watch) across worktrees. When enabled, you can switch which worktree is active for each pane with a single keystroke.

Configuration in .env:

# Enable pane management
RR_PANE_MGMT_ENABLED=true

# Dev server pane (format: session:window.pane)
RR_DEV_SERVER_PANE="tmuxa-1:0.1"
RR_DEV_SERVER_COMMAND="yarn install && yarn run-p tailwind dev"

# TypeScript watch pane (optional)
RR_TSC_WATCH_PANE="tmuxa-1:0.2"
RR_TSC_WATCH_COMMAND="yarn tsc-watch"

Usage:

  1. In rr, select a worktree with an existing worktree (marked with ⚡⌘)
  2. Press F4 to set it as the dev server target
  3. Press F5 to set it as the tsc-watch target
  4. The script will automatically:
    • Kill the current process in the pane (Ctrl-C)
    • cd to the selected worktree
    • Run the configured command

Visual Indicators:

  • (green) - This worktree is running the dev server
  • (cyan) - This worktree is running tsc-watch

Finding your pane IDs:

# List all tmux panes with their IDs
tmux list-panes -a -F "#{session_name}:#{window_index}.#{pane_index} - #{pane_title}"

fzedit

Interactive file finder/editor.

Keys: <CR> nvim | ^o cursor | ^s shell | ^r refresh | ^c copy path

restage

Unstage two WIP commits, keeping oldest staged.

apply_staged_to_commit

Apply staged changes to a commit via fixup+autosquash.

apply_staged_to_commit <commit-sha>

slack-react-notify

Get pinged when people react to your Slack messages — something Slack doesn't do natively. A small cross-platform (Linux/macOS) Socket Mode daemon: it listens for reaction_added events, keeps only the ones on messages you authored, and DMs you on Slack. That Slack DM fires Slack's own desktop and mobile notification (a message you send yourself wouldn't), so you're reached on every device. Set SLACK_REACT_DELIVERY=desktop for a local notify-send/osascript popup instead, or both for both.

slack-react-notify             # run in the foreground
slack-react-notify --check     # validate tokens + identity, then exit
slack-react-notify --help      # full Slack-app setup walkthrough
slack-react-notify --print-manifest                  # paste into "Create New App"
slack-react-notify --print-service systemd|launchd   # run it on login

Fastest setup: slack-react-notify --print-manifest, paste it into https://api.slack.com/appsCreate New App → From a manifest. Then generate an App-Level Token (connections:write) → SLACK_REACT_APP_TOKEN, install the app, and copy both the User OAuth Token → SLACK_REACT_TOKEN (reaction events + reads) and the Bot User OAuth Token → SLACK_REACT_BOT_TOKEN (DMs you). Run --check to confirm.

Runs as its own dedicated Slack app, independent of ticket-bot — don't share tokens, since Slack load-balances events across simultaneous Socket Mode connections on one app. The user-token reaction_added subscription ("on behalf of users") covers every channel and DM you're in with no bot invites; the bot token is used only to send you the DM. See the Slack Reaction Notifications block in .env.example for the full scope list and steps.

Run it on login:

# Linux (systemd user service)
slack-react-notify --print-service systemd > ~/.config/systemd/user/slack-react-notify.service
systemctl --user daemon-reload && systemctl --user enable --now slack-react-notify

# macOS (launchd agent)
slack-react-notify --print-service launchd > ~/Library/LaunchAgents/com.dev-workflow-tools.slack-react-notify.plist
launchctl load -w ~/Library/LaunchAgents/com.dev-workflow-tools.slack-react-notify.plist

Shell Integration

The shell/dev-workflow.zsh provides:

Keybindings

  • Ctrl+G - Commit message history widget (with ^f/^x/^r/^o for conventional commit types)

Functions

  • gcm "message" - Commit with message (saves to history)
  • nvgcm "message" - Commit without verification hooks

Aliases

Commits:

  • wip - Quick WIP commit (no hooks)
  • gca - Amend last commit (no edit)
  • reword - Amend commit message

Branches:

  • r - Recent branches (uses rr.sh)
  • gc - Switch branch with preview
  • gcb - Create and checkout branch

Reset:

  • soft / so - Soft reset HEAD~1 + unstage
  • rho / gr / gru - Hard reset to upstream

Stash:

  • gs - Stash changes
  • gsk - Stash with untracked
  • gsp - Stash pop
  • swip - Add all + WIP + status

Fetch/Pull:

  • p / pull - Pull changes
  • gf - Fetch all remotes
  • gfpa - Fetch with prune

Rebase:

  • grom - Rebase onto origin/main
  • gfgrom - Fetch + rebase origin/main
  • grc - Continue rebase
  • gra - Abort rebase

Cherry-pick:

  • gcpc - Continue cherry-pick
  • gcpa - Abort cherry-pick

Other:

  • push / mush - Push changes
  • os - Alias for oneshot

Troubleshooting

"JIRA_EMAIL and JIRA_API_TOKEN must be set" → Create .env from .env.example

"glab CLI not found" → Install from https://gitlab.com/gitlab-org/cli

Jira tickets not showing → Check credentials, verify JIRA_PROJECT, try r -r

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors