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 or Claude.`,
}
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, or hexai; amp is tried first if available)")
}
|