Skip to content

Commit 17e5f5d

Browse files
committed
feat: add watch daemon with watching list mechanism
✨ New Feature: Watch Daemon - Automatically monitor PRs and update Jira when merged - Smart watching list: only track PRs created with qkflow - Multi-repository support without configuration - Intelligent scheduling (15min daytime, 2:00/6:00 night) - Auto-start on login (launchd on macOS) - Desktop notifications - Auto cleanup after processing 🔧 Implementation: - Create watching_list.go for PR tracking - Refactor checker.go to use watching list - Auto-add PRs to watching list on creation - Remove github_owner/repo requirement - Add comprehensive watch commands (install/status/log/history) 📦 New Files: - internal/watcher/watching_list.go - internal/watcher/daemon.go - internal/watcher/scheduler.go - internal/watcher/checker.go - internal/watcher/processor.go - internal/watcher/state.go - internal/watcher/logger.go - internal/watcher/notifier.go - internal/watcher/launchd.go - cmd/qkflow/commands/watch.go 🎯 Usage: qkflow pr create PROJ-123 # Auto-added to watching list qkflow watch install # Start daemon with auto-start qkflow watch status # Check daemon status qkflow watch history # View processed PRs
1 parent e786c81 commit 17e5f5d

15 files changed

Lines changed: 2551 additions & 40 deletions

File tree

go-version/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ This is a complete rewrite of the original Shell-based quick-workflow tool in Go
2828
- **PR Merging** - Merge PRs and clean up branches automatically
2929
- **Quick Update** - Commit and push with PR title as commit message
3030
- **Jira Integration** - Automatically update Jira status and add PR links
31+
- **Watch Daemon** - 🆕 Automatically monitor PRs and update Jira when merged ⚡
3132
- **Interactive CLI** - Beautiful prompts and progress indicators
3233
- **Configuration Management** - Simple setup with `qkflow init`
3334
- **iCloud Sync** - Seamlessly sync configs across all your Mac devices ☁️
@@ -173,6 +174,50 @@ qkflow update
173174

174175
This is perfect for quick updates to an existing PR!
175176

177+
### Watch Daemon (Auto-update Jira)
178+
179+
**NEW!** Automatically monitor your PRs and update Jira when they're merged.
180+
181+
```bash
182+
# Install and start watch daemon (with auto-start on login)
183+
qkflow watch install
184+
185+
# Check daemon status
186+
qkflow watch status
187+
188+
# View processing history
189+
qkflow watch history
190+
191+
# View logs
192+
qkflow watch log
193+
qkflow watch log --follow
194+
195+
# Manual check (without daemon)
196+
qkflow watch check
197+
198+
# Stop/Start daemon
199+
qkflow watch stop
200+
qkflow watch start
201+
202+
# Uninstall daemon
203+
qkflow watch uninstall
204+
```
205+
206+
**What it does:**
207+
- ✅ Monitors YOUR PRs every 15 minutes (8:30-24:00)
208+
- ✅ Night mode: checks at 2:00 and 6:00 only
209+
- ✅ Auto-updates Jira status when PR is merged
210+
- ✅ Desktop notifications (macOS)
211+
- ✅ Auto-start on login (launchd on macOS)
212+
- ✅ Logs all activities
213+
- ✅ No manual intervention needed!
214+
215+
**Prerequisites:**
216+
1. Run `qkflow jira setup` first to configure Jira status mappings
217+
2. Make sure "PR Merged" status is configured (default: "In Review")
218+
219+
📖 See [Jira Status Config Guide](JIRA_STATUS_CONFIG.md) for setup details.
220+
176221
### Other Commands
177222

178223
```bash

go-version/cmd/qkflow/commands/pr_create.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/Wangggym/quick-workflow/internal/github"
1212
"github.com/Wangggym/quick-workflow/internal/jira"
1313
"github.com/Wangggym/quick-workflow/internal/ui"
14+
"github.com/Wangggym/quick-workflow/internal/watcher"
1415
"github.com/Wangggym/quick-workflow/pkg/config"
1516
"github.com/spf13/cobra"
1617
)
@@ -289,6 +290,34 @@ func runPRCreate(cmd *cobra.Command, args []string) {
289290
}
290291
}
291292

293+
// 添加到 watching list
294+
watchingList, err := watcher.NewWatchingList()
295+
if err != nil {
296+
ui.Warning(fmt.Sprintf("Failed to load watching list: %v", err))
297+
} else {
298+
// Extract Jira tickets
299+
jiraTickets := make([]string, 0)
300+
if jiraTicket != "" {
301+
jiraTickets = append(jiraTickets, jiraTicket)
302+
}
303+
304+
watchingPR := watcher.WatchingPR{
305+
PRNumber: pr.Number,
306+
Owner: owner,
307+
Repo: repo,
308+
Branch: branchName,
309+
Title: commitMessage,
310+
PRURL: pr.HTMLURL,
311+
JiraTickets: jiraTickets,
312+
}
313+
314+
if err := watchingList.Add(watchingPR); err != nil {
315+
ui.Warning(fmt.Sprintf("Failed to add PR to watching list: %v", err))
316+
} else {
317+
ui.Info("✅ Added PR to watching list for auto Jira updates")
318+
}
319+
}
320+
292321
// 复制 URL 到剪贴板
293322
copyToClipboard(pr.HTMLURL)
294323

go-version/cmd/qkflow/commands/pr_merge.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,21 @@ func runPRMerge(cmd *cobra.Command, args []string) {
6767
if err == nil && currentBranch != "" {
6868
ui.Info(fmt.Sprintf("Checking for PR from current branch: %s", currentBranch))
6969

70-
// 先尝试 open 状态的 PR
71-
prs, err := ghClient.ListPullRequests(owner, repo, "open")
72-
if err == nil {
73-
for _, pr := range prs {
74-
if pr.Head == currentBranch {
75-
prNumber = pr.Number
76-
ui.Success(fmt.Sprintf("Found PR #%d: %s", pr.Number, pr.Title))
77-
break
78-
}
70+
// 先尝试 open 状态的 PR
71+
prs, err := ghClient.ListPullRequests(owner, repo, "open", "")
72+
if err == nil {
73+
for _, pr := range prs {
74+
if pr.Head == currentBranch {
75+
prNumber = pr.Number
76+
ui.Success(fmt.Sprintf("Found PR #%d: %s", pr.Number, pr.Title))
77+
break
7978
}
8079
}
81-
82-
// 如果没找到,尝试所有状态的 PR
83-
if prNumber == 0 {
84-
allPRs, err := ghClient.ListPullRequests(owner, repo, "all")
80+
}
81+
82+
// 如果没找到,尝试所有状态的 PR
83+
if prNumber == 0 {
84+
allPRs, err := ghClient.ListPullRequests(owner, repo, "all", "")
8585
if err == nil {
8686
for _, pr := range allPRs {
8787
if pr.Head == currentBranch {
@@ -109,13 +109,13 @@ func runPRMerge(cmd *cobra.Command, args []string) {
109109
}
110110
}
111111

112-
// 如果用户选择手动输入或没有当前分支
113-
if prNumber == 0 {
114-
prs, err := ghClient.ListPullRequests(owner, repo, "open")
115-
if err != nil {
116-
ui.Error(fmt.Sprintf("Failed to list PRs: %v", err))
117-
return
118-
}
112+
// 如果用户选择手动输入或没有当前分支
113+
if prNumber == 0 {
114+
prs, err := ghClient.ListPullRequests(owner, repo, "open", "")
115+
if err != nil {
116+
ui.Error(fmt.Sprintf("Failed to list PRs: %v", err))
117+
return
118+
}
119119

120120
if len(prs) == 0 {
121121
ui.Error("No open pull requests found")

go-version/cmd/qkflow/commands/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func init() {
7070
rootCmd.AddCommand(configCmd)
7171
rootCmd.AddCommand(jiraCmd)
7272
rootCmd.AddCommand(updateCmd)
73+
rootCmd.AddCommand(watchCmd)
7374
}
7475

7576
var versionCmd = &cobra.Command{

0 commit comments

Comments
 (0)