summaryrefslogtreecommitdiff
path: root/internal/cli/release.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/cli/release.go')
-rw-r--r--internal/cli/release.go101
1 files changed, 81 insertions, 20 deletions
diff --git a/internal/cli/release.go b/internal/cli/release.go
index c882677..3254fe6 100644
--- a/internal/cli/release.go
+++ b/internal/cli/release.go
@@ -1,6 +1,7 @@
package cli
import (
+ "encoding/json"
"fmt"
"os"
"path/filepath"
@@ -59,8 +60,16 @@ func HandleCheckReleasesForRepo(cfg *config.Config, flags *Flags, repoName strin
func HandleCheckReleasesForRepos(cfg *config.Config, flags *Flags, repositories []string) int {
releaseManager := release.NewManager(flags.WorkDir)
- // Cache for AI release notes to avoid regenerating for the same repo/tag
- aiReleaseNotesCache := make(map[string]string) // key: "repoName:tag"
+ // Load persistent AI release notes cache
+ cacheFile := filepath.Join(flags.WorkDir, ".gitsyncer-ai-release-notes-cache.json")
+ aiReleaseNotesCache := loadAIReleaseNotesCache(cacheFile)
+
+ // Defer saving the cache when we're done
+ defer func() {
+ if err := saveAIReleaseNotesCache(cacheFile, aiReleaseNotesCache); err != nil {
+ fmt.Printf("Warning: Failed to save AI release notes cache: %v\n", err)
+ }
+ }()
// Set tokens from config with fallback to environment variables and files
githubOrg := cfg.FindGitHubOrg()
@@ -192,22 +201,27 @@ func HandleCheckReleasesForRepos(cfg *config.Config, flags *Flags, repositories
// Generate release notes
var releaseNotes string
if flags.AIReleaseNotes {
- // Check cache first
+ // Check cache first (unless --force is used)
cacheKey := fmt.Sprintf("%s:%s", repoName, tag)
- if cachedNotes, exists := aiReleaseNotesCache[cacheKey]; exists {
+ if cachedNotes, exists := aiReleaseNotesCache[cacheKey]; exists && !flags.Force {
fmt.Printf(" Using cached AI release notes for %s\n", tag)
releaseNotes = cachedNotes
} else {
- fmt.Printf(" Generating AI release notes for %s...\n", tag)
+ if flags.Force && aiReleaseNotesCache[cacheKey] != "" {
+ fmt.Printf(" Force regenerating AI release notes for %s (ignoring cache)\n", tag)
+ } else {
+ fmt.Printf(" Generating AI release notes for %s...\n", tag)
+ }
aiNotes, err := releaseManager.GenerateAIReleaseNotes(repoPath, repoName, tag, localTags, commits)
if err != nil {
fmt.Printf(" Warning: Failed to generate AI release notes: %v\n", err)
fmt.Printf(" Falling back to standard release notes\n")
releaseNotes = releaseManager.GenerateReleaseNotes(repoPath, tag, localTags)
+ // Don't cache on failure
} else {
releaseNotes = aiNotes
- aiReleaseNotesCache[cacheKey] = aiNotes // Cache the result
- fmt.Printf(" AI release notes generated successfully\n")
+ aiReleaseNotesCache[cacheKey] = aiNotes // Cache only on success
+ fmt.Printf(" AI release notes generated successfully and cached\n")
}
}
} else {
@@ -253,22 +267,27 @@ func HandleCheckReleasesForRepos(cfg *config.Config, flags *Flags, repositories
// Generate release notes
var releaseNotes string
if flags.AIReleaseNotes {
- // Check cache first
+ // Check cache first (unless --force is used)
cacheKey := fmt.Sprintf("%s:%s", repoName, tag)
- if cachedNotes, exists := aiReleaseNotesCache[cacheKey]; exists {
+ if cachedNotes, exists := aiReleaseNotesCache[cacheKey]; exists && !flags.Force {
fmt.Printf(" Using cached AI release notes for %s\n", tag)
releaseNotes = cachedNotes
} else {
- fmt.Printf(" Generating AI release notes for %s...\n", tag)
+ if flags.Force && aiReleaseNotesCache[cacheKey] != "" {
+ fmt.Printf(" Force regenerating AI release notes for %s (ignoring cache)\n", tag)
+ } else {
+ fmt.Printf(" Generating AI release notes for %s...\n", tag)
+ }
aiNotes, err := releaseManager.GenerateAIReleaseNotes(repoPath, repoName, tag, localTags, commits)
if err != nil {
fmt.Printf(" Warning: Failed to generate AI release notes: %v\n", err)
fmt.Printf(" Falling back to standard release notes\n")
releaseNotes = releaseManager.GenerateReleaseNotes(repoPath, tag, localTags)
+ // Don't cache on failure
} else {
releaseNotes = aiNotes
- aiReleaseNotesCache[cacheKey] = aiNotes // Cache the result
- fmt.Printf(" AI release notes generated successfully\n")
+ aiReleaseNotesCache[cacheKey] = aiNotes // Cache only on success
+ fmt.Printf(" AI release notes generated successfully and cached\n")
}
}
} else {
@@ -324,21 +343,25 @@ func HandleCheckReleasesForRepos(cfg *config.Config, flags *Flags, repositories
// Generate AI release notes
if flags.AIReleaseNotes {
- // Check cache first
+ // Check cache first (unless --force is used)
cacheKey := fmt.Sprintf("%s:%s", repoName, tag)
var aiNotes string
- if cachedNotes, exists := aiReleaseNotesCache[cacheKey]; exists {
+ if cachedNotes, exists := aiReleaseNotesCache[cacheKey]; exists && !flags.Force {
fmt.Printf(" Using cached AI release notes for existing release %s\n", tag)
aiNotes = cachedNotes
} else {
- fmt.Printf(" Generating AI release notes for existing release %s...\n", tag)
+ if flags.Force && aiReleaseNotesCache[cacheKey] != "" {
+ fmt.Printf(" Force regenerating AI release notes for existing release %s (ignoring cache)\n", tag)
+ } else {
+ fmt.Printf(" Generating AI release notes for existing release %s...\n", tag)
+ }
var err error
aiNotes, err = releaseManager.GenerateAIReleaseNotes(repoPath, repoName, tag, localTags, commits)
if err != nil {
fmt.Printf(" Warning: Failed to generate AI release notes: %v\n", err)
continue
}
- aiReleaseNotesCache[cacheKey] = aiNotes // Cache the result
+ aiReleaseNotesCache[cacheKey] = aiNotes // Cache only on success
}
// Print release notes to stdout
@@ -389,21 +412,25 @@ func HandleCheckReleasesForRepos(cfg *config.Config, flags *Flags, repositories
// Generate AI release notes
if flags.AIReleaseNotes {
- // Check cache first
+ // Check cache first (unless --force is used)
cacheKey := fmt.Sprintf("%s:%s", repoName, tag)
var aiNotes string
- if cachedNotes, exists := aiReleaseNotesCache[cacheKey]; exists {
+ if cachedNotes, exists := aiReleaseNotesCache[cacheKey]; exists && !flags.Force {
fmt.Printf(" Using cached AI release notes for existing release %s\n", tag)
aiNotes = cachedNotes
} else {
- fmt.Printf(" Generating AI release notes for existing release %s...\n", tag)
+ if flags.Force && aiReleaseNotesCache[cacheKey] != "" {
+ fmt.Printf(" Force regenerating AI release notes for existing release %s (ignoring cache)\n", tag)
+ } else {
+ fmt.Printf(" Generating AI release notes for existing release %s...\n", tag)
+ }
var err error
aiNotes, err = releaseManager.GenerateAIReleaseNotes(repoPath, repoName, tag, localTags, commits)
if err != nil {
fmt.Printf(" Warning: Failed to generate AI release notes: %v\n", err)
continue
}
- aiReleaseNotesCache[cacheKey] = aiNotes // Cache the result
+ aiReleaseNotesCache[cacheKey] = aiNotes // Cache only on success
}
// Print release notes to stdout
@@ -438,4 +465,38 @@ func HandleCheckReleasesForRepos(cfg *config.Config, flags *Flags, repositories
}
return 0
+}
+
+// loadAIReleaseNotesCache loads the AI release notes cache from disk
+func loadAIReleaseNotesCache(cacheFile string) map[string]string {
+ cache := make(map[string]string)
+
+ data, err := os.ReadFile(cacheFile)
+ if err != nil {
+ // Cache file doesn't exist yet, return empty cache
+ return cache
+ }
+
+ if err := json.Unmarshal(data, &cache); err != nil {
+ fmt.Printf("Warning: Failed to parse AI release notes cache: %v\n", err)
+ return make(map[string]string)
+ }
+
+ fmt.Printf("Loaded AI release notes cache with %d entries\n", len(cache))
+ return cache
+}
+
+// saveAIReleaseNotesCache saves the AI release notes cache to disk
+func saveAIReleaseNotesCache(cacheFile string, cache map[string]string) error {
+ data, err := json.MarshalIndent(cache, "", " ")
+ if err != nil {
+ return fmt.Errorf("failed to marshal cache: %w", err)
+ }
+
+ if err := os.WriteFile(cacheFile, data, 0644); err != nil {
+ return fmt.Errorf("failed to write cache file: %w", err)
+ }
+
+ fmt.Printf("Saved AI release notes cache with %d entries to %s\n", len(cache), cacheFile)
+ return nil
} \ No newline at end of file