Skip to content

Commit f0c570c

Browse files
edmundmillerclaude
andcommitted
feat: add bugwarrior integration with automated sync
- Set up bugwarrior for Apple Reminders and GitHub sync - Configure 1Password integration for secure credential management - Add launchd jobs for automated sync (taskwarrior every 15min, bugwarrior every 30min) - Create setup scripts for easy configuration - Add comprehensive documentation - Configure GitHub sync to pull only assigned issues 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 85c3ce8 commit f0c570c

13 files changed

Lines changed: 914 additions & 1 deletion

bin/setup-bugwarrior

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Setup bugwarrior integration with taskwarrior
4+
#
5+
6+
set -euo pipefail
7+
8+
BUGWARRIOR_CONFIG="$HOME/.config/dotfiles/config/bugwarrior/bugwarriorrc"
9+
TASKWARRIOR_CONFIG="$HOME/.config/dotfiles/config/taskwarrior/taskrc"
10+
11+
echo "🔧 Setting up bugwarrior integration..."
12+
13+
# Step 1: Create symlink to bugwarrior config
14+
echo "📁 Creating bugwarrior config symlink..."
15+
mkdir -p "$HOME/.config/bugwarrior"
16+
if [[ ! -L "$HOME/.config/bugwarrior/bugwarriorrc" ]]; then
17+
ln -sf "$BUGWARRIOR_CONFIG" "$HOME/.config/bugwarrior/bugwarriorrc"
18+
echo "✅ Linked bugwarrior config"
19+
else
20+
echo "✅ Bugwarrior config already linked"
21+
fi
22+
23+
# Step 2: Set up taskwarrior UDAs
24+
echo "⚙️ Setting up taskwarrior User Defined Attributes..."
25+
if command -v bugwarrior-uda &> /dev/null; then
26+
echo "Running bugwarrior-uda to configure taskwarrior fields..."
27+
bugwarrior-uda
28+
echo "✅ Taskwarrior UDAs configured"
29+
else
30+
echo "❌ bugwarrior-uda command not found"
31+
echo "Make sure bugwarrior is installed: uv tool install bugwarrior"
32+
exit 1
33+
fi
34+
35+
# Step 3: Verify 1Password integration
36+
echo "🔐 Testing 1Password integration..."
37+
if command -v op &> /dev/null; then
38+
echo "✅ 1Password CLI found"
39+
40+
# Test if we can access the items (without printing sensitive data)
41+
if op item list --categories Login | grep -q "Seqera Jira\|GitHub Token"; then
42+
echo "✅ Found bugwarrior 1Password items"
43+
else
44+
echo "⚠️ 1Password items not found. Run 'setup-bugwarrior-credentials' first"
45+
fi
46+
else
47+
echo "❌ 1Password CLI not found"
48+
echo "Install from: https://developer.1password.com/docs/cli/get-started"
49+
fi
50+
51+
# Step 4: Test bugwarrior configuration
52+
echo "🧪 Testing bugwarrior configuration..."
53+
if bugwarrior-pull --dry-run 2>/dev/null; then
54+
echo "✅ Bugwarrior configuration is valid"
55+
else
56+
echo "❌ Bugwarrior configuration has issues"
57+
echo "Check the config at: $BUGWARRIOR_CONFIG"
58+
echo "Run: bugwarrior-pull --dry-run"
59+
fi
60+
61+
echo ""
62+
echo "🎉 Bugwarrior setup complete!"
63+
echo ""
64+
echo "Usage:"
65+
echo " bugwarrior-pull # Sync issues from Jira & GitHub"
66+
echo " bugwarrior-pull --dry-run # Test without importing"
67+
echo " setup-bugwarrior-sync # Add to cron for automation"
68+
echo ""
69+
echo "Config locations:"
70+
echo " ~/.config/bugwarrior/bugwarriorrc -> $BUGWARRIOR_CONFIG"
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Quick setup for bugwarrior 1Password items
4+
#
5+
6+
set -euo pipefail
7+
8+
echo "🔐 Setting up 1Password items for bugwarrior..."
9+
echo ""
10+
echo "This will help you create the required 1Password items."
11+
echo "You'll need:"
12+
echo " 1. Your Jira email and API token"
13+
echo " 2. Your GitHub username and personal access token(s)"
14+
echo ""
15+
16+
# Function to test 1Password item
17+
test_item() {
18+
local item_name="$1"
19+
if op item get "$item_name" --fields label=username &>/dev/null; then
20+
echo "✅ Found: $item_name"
21+
return 0
22+
else
23+
echo "❌ Missing: $item_name"
24+
return 1
25+
fi
26+
}
27+
28+
# Check existing items
29+
echo "Checking existing 1Password items..."
30+
echo ""
31+
32+
items_needed=()
33+
test_item "Seqera Jira" || items_needed+=("jira")
34+
test_item "GitHub Token" || items_needed+=("github-work")
35+
test_item "GitHub Personal Token" || items_needed+=("github-personal")
36+
37+
if [ ${#items_needed[@]} -eq 0 ]; then
38+
echo ""
39+
echo "✅ All required 1Password items found!"
40+
exit 0
41+
fi
42+
43+
echo ""
44+
echo "Let's create the missing items..."
45+
echo ""
46+
47+
# Create Jira item if needed
48+
if [[ " ${items_needed[@]} " =~ " jira " ]]; then
49+
echo "📋 Seqera Jira Setup"
50+
echo "Get your API token from: https://seqera.atlassian.net/secure/ViewProfile.jspa"
51+
echo "Go to 'Personal Access Tokens' and create one"
52+
echo ""
53+
read -p "Jira email: " jira_user
54+
read -s -p "Jira API token: " jira_token
55+
echo ""
56+
57+
op item create \
58+
--category=login \
59+
--title="Seqera Jira" \
60+
username="$jira_user" \
61+
password="$jira_token" \
62+
--vault=Private || echo "Failed to create Jira item"
63+
fi
64+
65+
# Create GitHub work token if needed
66+
if [[ " ${items_needed[@]} " =~ " github-work " ]]; then
67+
echo ""
68+
echo "🐙 GitHub Token Setup (for Seqera repos)"
69+
echo "Create token at: https://github.com/settings/tokens"
70+
echo "Required scopes: repo (full control)"
71+
echo ""
72+
read -p "GitHub username: " github_user
73+
read -s -p "GitHub personal access token: " github_token
74+
echo ""
75+
76+
op item create \
77+
--category=login \
78+
--title="GitHub Token" \
79+
username="$github_user" \
80+
password="$github_token" \
81+
--vault=Private || echo "Failed to create GitHub Token item"
82+
fi
83+
84+
# Create GitHub personal token if needed
85+
if [[ " ${items_needed[@]} " =~ " github-personal " ]]; then
86+
echo ""
87+
echo "🐙 GitHub Personal Token Setup (for personal repos)"
88+
echo "You can use the same token as above or create a separate one"
89+
echo ""
90+
read -p "Use same token as work? (y/n): " use_same
91+
92+
if [[ "$use_same" == "y" ]]; then
93+
op item create \
94+
--category=login \
95+
--title="GitHub Personal Token" \
96+
username="$github_user" \
97+
password="$github_token" \
98+
--vault=Private || echo "Failed to create GitHub Personal Token item"
99+
else
100+
read -p "GitHub username: " github_personal_user
101+
read -s -p "GitHub personal access token: " github_personal_token
102+
echo ""
103+
104+
op item create \
105+
--category=login \
106+
--title="GitHub Personal Token" \
107+
username="$github_personal_user" \
108+
password="$github_personal_token" \
109+
--vault=Private || echo "Failed to create GitHub Personal Token item"
110+
fi
111+
fi
112+
113+
echo ""
114+
echo "🎉 Setup complete!"
115+
echo ""
116+
echo "Next steps:"
117+
echo "1. Test with: bugwarrior-pull --dry-run"
118+
echo "2. Run full sync: bugwarrior-pull"

bin/setup-bugwarrior-credentials

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Setup 1Password items for bugwarrior authentication
4+
#
5+
6+
set -euo pipefail
7+
8+
echo "🔐 Setting up 1Password items for bugwarrior..."
9+
10+
# Check if op is available
11+
if ! command -v op &> /dev/null; then
12+
echo "❌ Error: 1Password CLI (op) is not installed"
13+
echo "Install it from: https://developer.1password.com/docs/cli/get-started"
14+
exit 1
15+
fi
16+
17+
# Check if user is signed in
18+
if ! op account list &> /dev/null; then
19+
echo "❌ Error: Not signed in to 1Password"
20+
echo "Run: op signin"
21+
exit 1
22+
fi
23+
24+
create_item() {
25+
local title="$1"
26+
local username_prompt="$2"
27+
local password_prompt="$3"
28+
local additional_info="$4"
29+
30+
echo ""
31+
echo "Creating 1Password item: $title"
32+
echo "$additional_info"
33+
echo ""
34+
35+
read -p "Username/Login: " username
36+
read -s -p "Password/Token: " password
37+
echo ""
38+
39+
# Create the item
40+
if op item create \
41+
--category Login \
42+
--title "$title" \
43+
username="$username" \
44+
password="$password" \
45+
--vault Private 2>/dev/null; then
46+
echo "✅ Created: $title"
47+
else
48+
echo "⚠️ Item '$title' may already exist, skipping..."
49+
fi
50+
}
51+
52+
echo "This script will create the following 1Password items:"
53+
echo "1. Seqera Jira - For Jira API access"
54+
echo "2. GitHub Token - For Seqera organization repos"
55+
echo "3. GitHub Personal Token - For your personal repos"
56+
echo ""
57+
read -p "Continue? (y/N): " -n 1 -r
58+
echo ""
59+
60+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
61+
echo "❌ Setup cancelled"
62+
exit 0
63+
fi
64+
65+
# Create Seqera Jira item
66+
create_item \
67+
"Seqera Jira" \
68+
"Jira username/email" \
69+
"Jira API token" \
70+
"For Seqera Jira access. Get API token from: https://seqera.atlassian.net/secure/ViewProfile.jspa -> Personal Access Tokens"
71+
72+
# Create GitHub Token item
73+
create_item \
74+
"GitHub Token" \
75+
"GitHub username" \
76+
"GitHub personal access token" \
77+
"For Seqera organization repos. Create token at: https://github.com/settings/tokens
78+
Minimum scopes: repo (for private repos) or public_repo (for public only)"
79+
80+
# Create GitHub Personal Token item
81+
create_item \
82+
"GitHub Personal Token" \
83+
"GitHub username" \
84+
"GitHub personal access token" \
85+
"For your personal repos. Can use same token as above or create a separate one.
86+
Create token at: https://github.com/settings/tokens"
87+
88+
echo ""
89+
echo "🎉 1Password items created!"
90+
echo ""
91+
echo "Next steps:"
92+
echo "1. Run 'setup-bugwarrior' to configure taskwarrior UDAs"
93+
echo "2. Run 'bugwarrior-pull' to test the setup"
94+
echo "3. Add 'bugwarrior-pull' to your cron/scheduled tasks"

bin/setup-bugwarrior-sync

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Setup automated bugwarrior syncing
4+
#
5+
6+
set -euo pipefail
7+
8+
echo "⏰ Setting up automated bugwarrior syncing..."
9+
10+
# Create a wrapper script for safe syncing
11+
SYNC_SCRIPT="$HOME/.local/bin/bugwarrior-sync"
12+
mkdir -p "$(dirname "$SYNC_SCRIPT")"
13+
14+
cat > "$SYNC_SCRIPT" << 'EOF'
15+
#!/usr/bin/env bash
16+
#
17+
# Safe bugwarrior sync with logging
18+
#
19+
20+
set -euo pipeFail
21+
22+
LOG_FILE="$HOME/.local/share/bugwarrior/sync.log"
23+
mkdir -p "$(dirname "$LOG_FILE")"
24+
25+
echo "$(date): Starting bugwarrior sync..." >> "$LOG_FILE"
26+
27+
# Ensure 1Password session is available
28+
if ! op account list &> /dev/null; then
29+
echo "$(date): ERROR - Not signed in to 1Password" >> "$LOG_FILE"
30+
exit 1
31+
fi
32+
33+
# Run bugwarrior with error handling
34+
if bugwarrior-pull 2>&1 >> "$LOG_FILE"; then
35+
echo "$(date): Sync completed successfully" >> "$LOG_FILE"
36+
else
37+
echo "$(date): ERROR - Sync failed" >> "$LOG_FILE"
38+
exit 1
39+
fi
40+
EOF
41+
42+
chmod +x "$SYNC_SCRIPT"
43+
echo "✅ Created sync script at $SYNC_SCRIPT"
44+
45+
# Add to user's PATH if needed
46+
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
47+
echo ""
48+
echo "⚠️ Add ~/.local/bin to your PATH:"
49+
echo "echo 'set PATH \$HOME/.local/bin \$PATH' >> ~/.config/fish/config.fish"
50+
fi
51+
52+
# Create launchd plist for macOS automation
53+
PLIST_DIR="$HOME/Library/LaunchAgents"
54+
PLIST_FILE="$PLIST_DIR/com.user.bugwarrior.plist"
55+
56+
echo ""
57+
echo "Setting up automated sync (every 30 minutes)..."
58+
read -p "Create launchd job for automatic syncing? (y/N): " -n 1 -r
59+
echo ""
60+
61+
if [[ $REPLY =~ ^[Yy]$ ]]; then
62+
mkdir -p "$PLIST_DIR"
63+
64+
cat > "$PLIST_FILE" << EOF
65+
<?xml version="1.0" encoding="UTF-8"?>
66+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
67+
<plist version="1.0">
68+
<dict>
69+
<key>Label</key>
70+
<string>com.user.bugwarrior</string>
71+
<key>ProgramArguments</key>
72+
<array>
73+
<string>$SYNC_SCRIPT</string>
74+
</array>
75+
<key>StartInterval</key>
76+
<integer>1800</integer>
77+
<key>RunAtLoad</key>
78+
<false/>
79+
<key>StandardOutPath</key>
80+
<string>$HOME/.local/share/bugwarrior/launchd.log</string>
81+
<key>StandardErrorPath</key>
82+
<string>$HOME/.local/share/bugwarrior/launchd-error.log</string>
83+
</dict>
84+
</plist>
85+
EOF
86+
87+
# Load the launchd job
88+
launchctl load "$PLIST_FILE"
89+
echo "✅ Created and loaded launchd job"
90+
echo "📁 Logs: ~/.local/share/bugwarrior/"
91+
else
92+
echo "ℹ️ Manual sync: run 'bugwarrior-sync' or 'bugwarrior-pull'"
93+
fi
94+
95+
echo ""
96+
echo "🎉 Bugwarrior sync automation setup complete!"
97+
echo ""
98+
echo "Commands:"
99+
echo " bugwarrior-sync # Safe sync with logging"
100+
echo " bugwarrior-pull # Direct bugwarrior command"
101+
echo " launchctl unload $PLIST_FILE # Disable automation"
102+
echo ""
103+
echo "Logs:"
104+
echo " ~/.local/share/bugwarrior/sync.log"
105+
echo " ~/.local/share/bugwarrior/launchd.log"

0 commit comments

Comments
 (0)