From b0d096d0ea6adb229cbafafa64f7ca2e6b1c572d Mon Sep 17 00:00:00 2001 From: Kayvan Sylvan Date: Sun, 20 Jul 2025 20:33:23 -0700 Subject: [PATCH] feat: change push behavior from opt-out to opt-in with GitHub token auth ## CHANGES - Change `NoPush` config field to `Push` boolean - Update CLI flag from `--no-push` to `--push` - Add GitHub token authentication for push operations - Import `os` and HTTP transport packages - Reverse push logic to require explicit enable - Update documentation for new push behavior - Add automatic GitHub repository detection for auth --- .../internal/changelog/processing.go | 4 +- .../internal/config/config.go | 2 +- cmd/generate_changelog/internal/git/walker.go | 39 ++++++++++++++++++- cmd/generate_changelog/main.go | 2 +- docs/Automated-ChangeLog.md | 9 +++-- docs/Automated-Changelog-Usage.md | 18 +++++---- 6 files changed, 59 insertions(+), 15 deletions(-) diff --git a/cmd/generate_changelog/internal/changelog/processing.go b/cmd/generate_changelog/internal/changelog/processing.go index bf1e1c16..a91d9c0a 100644 --- a/cmd/generate_changelog/internal/changelog/processing.go +++ b/cmd/generate_changelog/internal/changelog/processing.go @@ -266,8 +266,8 @@ func (g *Generator) commitAndPushIncoming(prNumber int, filename string) error { return fmt.Errorf("failed to commit changes: %w", err) } - // Push to remote if not disabled - if !g.cfg.NoPush { + // Push to remote if enabled + if g.cfg.Push { if err := g.gitWalker.PushToRemote(); err != nil { return fmt.Errorf("failed to push to remote: %w", err) } diff --git a/cmd/generate_changelog/internal/config/config.go b/cmd/generate_changelog/internal/config/config.go index a0c91896..be70f8d7 100644 --- a/cmd/generate_changelog/internal/config/config.go +++ b/cmd/generate_changelog/internal/config/config.go @@ -15,5 +15,5 @@ type Config struct { IncomingPR int ProcessPRs bool IncomingDir string - NoPush bool + Push bool } diff --git a/cmd/generate_changelog/internal/git/walker.go b/cmd/generate_changelog/internal/git/walker.go index 7f31a502..f58e06a6 100644 --- a/cmd/generate_changelog/internal/git/walker.go +++ b/cmd/generate_changelog/internal/git/walker.go @@ -2,6 +2,7 @@ package git import ( "fmt" + "os" "regexp" "strconv" "strings" @@ -11,6 +12,7 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/go-git/go-git/v5/plumbing/transport/http" ) var ( @@ -505,8 +507,43 @@ func (w *Walker) CommitChanges(message string) (plumbing.Hash, error) { } // PushToRemote pushes the current branch to the remote repository +// It automatically detects GitHub repositories and uses token authentication when available func (w *Walker) PushToRemote() error { - err := w.repo.Push(&git.PushOptions{}) + pushOptions := &git.PushOptions{} + + // Check if we have a GitHub token for authentication + if githubToken := os.Getenv("GITHUB_TOKEN"); githubToken != "" { + // Get remote URL to check if it's a GitHub repository + remotes, err := w.repo.Remotes() + if err == nil && len(remotes) > 0 { + // Get the origin remote (or first remote if origin doesn't exist) + var remote *git.Remote + for _, r := range remotes { + if r.Config().Name == "origin" { + remote = r + break + } + } + if remote == nil { + remote = remotes[0] + } + + // Check if this is a GitHub repository + urls := remote.Config().URLs + if len(urls) > 0 { + url := urls[0] + if strings.Contains(url, "github.com") { + // Use token authentication for GitHub repositories + pushOptions.Auth = &http.BasicAuth{ + Username: "token", // GitHub expects "token" as username + Password: githubToken, + } + } + } + } + } + + err := w.repo.Push(pushOptions) if err != nil { return fmt.Errorf("failed to push: %w", err) } diff --git a/cmd/generate_changelog/main.go b/cmd/generate_changelog/main.go index 30f683de..c6ec60cc 100644 --- a/cmd/generate_changelog/main.go +++ b/cmd/generate_changelog/main.go @@ -40,7 +40,7 @@ func init() { rootCmd.Flags().IntVar(&cfg.IncomingPR, "incoming-pr", 0, "Pre-process PR for changelog (provide PR number)") rootCmd.Flags().BoolVar(&cfg.ProcessPRs, "process-prs", false, "Process all incoming PR files for release") rootCmd.Flags().StringVar(&cfg.IncomingDir, "incoming-dir", "./cmd/generate_changelog/incoming", "Directory for incoming PR files") - rootCmd.Flags().BoolVar(&cfg.NoPush, "no-push", false, "Disable automatic git push after creating an incoming entry") + rootCmd.Flags().BoolVar(&cfg.Push, "push", false, "Enable automatic git push after creating an incoming entry") } func run(cmd *cobra.Command, args []string) error { diff --git a/docs/Automated-ChangeLog.md b/docs/Automated-ChangeLog.md index a4d7bc3b..c6d57730 100644 --- a/docs/Automated-ChangeLog.md +++ b/docs/Automated-ChangeLog.md @@ -89,7 +89,7 @@ graph TD 4. **Auto-commit**: - Commit file with message: `chore: incoming 1672 changelog entry` - - Push to current branch + - Optionally push to current branch (use `--push` flag) (The PR is now completely ready to be merged with integrated CHANGELOG entry updating) @@ -274,8 +274,11 @@ Update `.github/workflows/update-version-and-create-tag.yml`. 1. **During Development**: ```bash - # After PR is ready for review - generate_changelog --incoming-pr 1672 + # After PR is ready for review (commit locally only) + generate_changelog --incoming-pr 1672 --ai-summarize + + # Or to automatically push to remote + generate_changelog --incoming-pr 1672 --ai-summarize --push ``` 2. **Validation**: diff --git a/docs/Automated-Changelog-Usage.md b/docs/Automated-Changelog-Usage.md index 0b00e303..55b82f94 100644 --- a/docs/Automated-Changelog-Usage.md +++ b/docs/Automated-Changelog-Usage.md @@ -44,7 +44,7 @@ The tool will: 1. Create `./cmd/generate_changelog/incoming/1672.txt` 2. Generate an AI-enhanced summary (if `--ai-summarize` is enabled) -3. Auto-commit and push the file to your branch (unless `--no-push` is used) +3. Auto-commit the file to your branch (use `--push` to also push to remote) Review the generated file and edit if needed: @@ -104,11 +104,13 @@ Enable AI-enhanced summaries using Fabric integration. **Usage**: `./generate_changelog --incoming-pr 1672 --ai-summarize` -### `--no-push` +### `--push` -Disable automatic git push after creating an incoming entry. The commit will be created locally but not pushed to the remote repository. +Enable automatic git push after creating an incoming entry. By default, the commit is created locally but not pushed to the remote repository. -**Usage**: `./generate_changelog --incoming-pr 1672 --no-push` +**Usage**: `./generate_changelog --incoming-pr 1672 --push` + +**Note**: When using `--push`, ensure you have proper authentication configured (SSH keys or GITHUB_TOKEN environment variable). ## Troubleshooting @@ -171,13 +173,15 @@ When a release is created: ./generate_changelog --incoming-pr 1672 --no-cache ``` -### Disable Auto-Push +### Enable Auto-Push ```bash -./generate_changelog --incoming-pr 1672 --no-push +./generate_changelog --incoming-pr 1672 --push ``` -This creates the commit locally but doesn't push to the remote repository, allowing you to review changes before pushing manually. +This creates the commit locally and pushes it to the remote repository. By default, commits are only created locally, allowing you to review changes before pushing manually. + +**Authentication**: The tool automatically detects GitHub repositories and uses the GITHUB_TOKEN environment variable for authentication when pushing. For SSH repositories, ensure your SSH keys are properly configured. ## Integration with Existing Workflow