summaryrefslogtreecommitdiff
path: root/internal/cmd/release.go
blob: 656f4a67443ba25249d9b5dc1bfa4fb036ca7262 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package cmd

import (
	"os"

	"codeberg.org/snonux/gitsyncer/internal/cli"
	"github.com/spf13/cobra"
)

var (
	autoRelease    bool
	noAINotes      bool
	updateExisting bool
	templatePath   string
	aiTool         string
)

var releaseCmd = &cobra.Command{
	Use:   "release",
	Short: "Manage releases across platforms",
	Long: `Check for version tags without releases and create them across 
GitHub and Codeberg. Supports AI-generated release notes via amp (stdin pipeline),
with fallback to hexai, Claude, or aichat.`,
}

var releaseCheckCmd = &cobra.Command{
	Use:   "check [repo]",
	Short: "Check for missing releases",
	Long: `Check for version tags that don't have corresponding releases.
If no repository is specified, checks all configured repositories.`,
	Args: cobra.MaximumNArgs(1),
	Example: `  # Check all repositories
  gitsyncer release check
  
  # Check specific repository
  gitsyncer release check myproject
  
  # Check with dry-run
  gitsyncer release check --dry-run`,
	Run: func(cmd *cobra.Command, args []string) {
		flags := buildFlags()
		flags.CheckReleases = true

		if len(args) > 0 {
			// Check specific repo
			exitCode := cli.HandleCheckReleasesForRepo(cfg, flags, args[0])
			os.Exit(exitCode)
		} else {
			// Check all repos
			exitCode := cli.HandleCheckReleases(cfg, flags)
			os.Exit(exitCode)
		}
	},
}

var releaseCreateCmd = &cobra.Command{
	Use:   "create [repo]",
	Short: "Create releases for version tags",
	Long: `Create releases for version tags that don't have them.
If no repository is specified, processes all configured repositories.`,
	Args: cobra.MaximumNArgs(1),
	Example: `  # Create releases (AI notes enabled by default)
  gitsyncer release create
  
  # Auto-create without prompts
  gitsyncer release create --auto
  
  # Create without AI-generated notes
  gitsyncer release create --no-ai-notes
  
  # Update existing releases with AI notes
  gitsyncer release create --update-existing
  
  # Create for specific repository without AI
  gitsyncer release create myproject --no-ai-notes
  
  # Use amp for AI release notes
gitsyncer release create --ai-tool amp`,
	Run: func(cmd *cobra.Command, args []string) {
		flags := buildFlags()
		flags.CheckReleases = true
		flags.AutoCreateReleases = autoRelease
		flags.AIReleaseNotes = !noAINotes
		flags.UpdateReleases = updateExisting
		flags.AITool = aiTool

		if len(args) > 0 {
			// Create releases for specific repo
			exitCode := cli.HandleCheckReleasesForRepo(cfg, flags, args[0])
			os.Exit(exitCode)
		} else {
			// Create releases for all repos
			exitCode := cli.HandleCheckReleases(cfg, flags)
			os.Exit(exitCode)
		}
	},
}

func init() {
	rootCmd.AddCommand(releaseCmd)
	releaseCmd.AddCommand(releaseCheckCmd)
	releaseCmd.AddCommand(releaseCreateCmd)

	// Release flags
	releaseCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "preview what releases would be created")

	// Create-specific flags
	releaseCreateCmd.Flags().BoolVar(&autoRelease, "auto", false, "skip confirmation prompts")
	releaseCreateCmd.Flags().BoolVar(&noAINotes, "no-ai-notes", false, "disable AI-generated release notes (AI notes are enabled by default)")
	releaseCreateCmd.Flags().BoolVar(&updateExisting, "update-existing", false, "update existing releases with new AI-generated notes")
	releaseCreateCmd.Flags().StringVar(&templatePath, "template", "", "custom template for release notes")
	releaseCreateCmd.Flags().StringVar(&aiTool, "ai-tool", "amp", "AI tool to use for release notes (amp, claude, aichat, or hexai; amp is tried first if available)")
}