-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introducing changelog generation tool #264
Conversation
bot/tools/changelog/main.go
Outdated
func getLastVersion(baseTag, dir string) (string, error) { | ||
if baseTag != "" { | ||
return baseTag, nil | ||
} | ||
|
||
// get root dir of repo | ||
topDir, err := git.RunCmd(dir, "rev-parse", "--show-toplevel") | ||
if err != nil { | ||
return "", trace.Wrap(err) | ||
} | ||
lastVersion, err := makePrintVersion(topDir) | ||
if err != nil { | ||
return "", trace.Wrap(err) | ||
} | ||
|
||
return lastVersion, nil | ||
} | ||
|
||
// makePrintVersion will run 'make -s print-version' | ||
func makePrintVersion(dir string) (string, error) { | ||
var stdout bytes.Buffer | ||
var stderr bytes.Buffer | ||
|
||
cmd := exec.Command("make", "-s", "print-version") | ||
cmd.Dir = dir | ||
cmd.Stderr = &stderr | ||
cmd.Stdout = &stdout | ||
|
||
err := cmd.Run() | ||
|
||
if err != nil { | ||
return strings.TrimSpace(stderr.String()), trace.Wrap(err, "can't get last released version") | ||
} | ||
out := strings.TrimSpace(stdout.String()) | ||
|
||
return "v" + out, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it would be better to pass this in as a parameter rather than invoking make
. This would allow the tool to be used in other projects without this target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is actually passed in as a flag (--base-tag
). This is just the fallback if that flag isn't passed in. I tried to keep the functionality close to the current implementation. But yeah this would fail if the --base-tag
flag isn't set and the Makefile doesn't exist or have that target making it not so portable.
For now to be clearer e.g. --base-tag was not set, defaulted to invoking 'make version' but failed
. Should be less ambiguous and indicate a way to "fix" it.
go.mod
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fheinecke I added the go.mod
at the top of the directory to get my code in a working state. I wasn't quite sure what the intention was for the Go module. I did see in the file structure that there were some go.mod
files in nested directories. To me that seemed kind of odd because I'd imagine that most of the code would be versioned together (or at least libs
and tools
). With go.mod
setup in different directories we would have to use Go workspaces to manage the dependency between modules.
Oh also the go.sum
is currently messed up a bit I'll have to fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did see in the file structure that there were some go.mod files in nested directories.
I typo'd this in the original PR for that RFD. Each project should have their own go.mod/sum files, though they shouldn't be under the workflows
directory. Generally we don't want all the code in this repo versioned together. It's intended to be used as a collection of unrelated projects, so we don't want that direct coupling. This includes libraries, as we would like to avoid needing to update all dependents immediately if a library interface changes.
libs/gh/pull_request.go
Outdated
var prs []ChangelogPR | ||
query := fmt.Sprintf("base:%s merged:%s -label:no-changelog", opts.Branch, dateRangeFormat(opts.FromDate, opts.ToDate)) | ||
|
||
data, err := RunCmd(dir, "pr", "list", "--search", query, "--limit", "200", "--json", "number,url,title,body") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're moving this to shared-workflows, we should use github package we use in other tools here rather than calling CLI: https://github.com/gravitational/shared-workflows/blob/main/bot/internal/github/github.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something to mention is that packages cannot import internal
unless they're nested in the same parent directory as internal
. I'd imagine that everything under the internal
package would be moved up under libs
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea it'd need to move to a new module under /libs
. Probably just the github package for now though, to avoid too much scope creep.
tools/changelog/main.go
Outdated
|
||
// getBranch will return branch if parsed otherwise will attempt to find it | ||
// Branch should be in the format "branch/v*" | ||
func getBranch(branch, dir string) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can these things (get branch, get forked branch, etc.) be moved into a shared reusable "git" library package, similar to what we have for "github"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At that point it might just be easier to use https://github.com/go-git/go-git and remove the CLI tool dep entirely at the same time. I've used that library on a handful of projects before and it works well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, agreed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup I can do that should be a quick change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw - Be sure to check the go-git compatibility guide. I had to go with the git lib route for a different project due to a lack of support for certain commands.
Updated based on feedback:
|
libs/github/go.mod
Outdated
github.com/cli/go-gh/v2 v2.9.0 | ||
github.com/google/go-github/v37 v37.0.0 | ||
github.com/gravitational/trace v1.3.1 | ||
github.com/shurcooL/githubv4 v0.0.0-20240429030203-be2daab69064 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need 3 different libraries for Github? Can we simplify? In our existing bot we already use github.com/google/go-github.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was using the v4 API for the code but it isn't absolutely necessay so just moved it real quick to use the v3 API. The go-gh
library has a useful function I just stumbled upon that will use look for GITHUB_TOKEN
, github config file, or gh auth
. Useful for running it on developer machines and CI.
I could remove that dependency. I need to update the config to note that GITHUB_TOKEN
is needed anyway. Could have it maybe be a requirement to pass in the token.
355a413
to
9acb082
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@doggydogworld We've been going back-and-forth on this for quite a bit now, I think we should be wrapping this up as it was supposed to be a just quick port from bash to Go. From my side I'd like us to address 3 things before it's good to go:
- Remove go.mod/sum from every package, this is very unnecessary.
- Let's go back to just calling
git
CLI and remove dependency on git library. - Restore PR links in enterprise changes list (I left a comment about this before but it's still unaddressed).
Can you please make these changes and then let's get this ready to merge and start using.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last comment about go.mod, then lgtm.
Also, please don't forget to update make changelog
target in teleport repo to use this tool as a follow up.
go.mod
Outdated
@@ -0,0 +1,27 @@ | |||
module github.com/gravitational/shared-workflows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is correct still. We should have a go.mod per tool I feel, not a single one for the entire repo or one for each package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I think I have a better idea of what is wanted here then. I'm thinking then it should be a module for libs as a whole and a module for each tool.
For example in this change two modules will be created.
github.com/gravitational/shared-workflows/libs
github.com/gravitational/shared-workflows/tools/changelog
Tools are versioned separately. Everything under libs
will be versioned together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw I implemented the above. Check it out and let me know if it seems right.
go.mod
Outdated
github.com/alecthomas/kingpin/v2 v2.4.0 | ||
github.com/cli/go-gh/v2 v2.9.0 | ||
github.com/google/go-github/v37 v37.0.0 | ||
github.com/gravitational/trace v1.4.0 | ||
github.com/stretchr/testify v1.9.0 | ||
golang.org/x/oauth2 v0.21.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks much better as dependency list 👍
FYI created a PR for this just to be ready here |
@r0mant I disagree with using a single Go module under Example 1:We currently have separate "git" and "github" libraries inside the library module. This changelog generation tool depends on both of these libraries (regardless whether they're one or two modules). It is reasonable to expect that at some point we will introduce at least one breaking change to one of these libraries, for example, changing the signature of a function in the github library. It is also reasonable to expect that we may eventually discover a security issue with one of the libraries, for example, a CLI injection vulnerability in the git library. When a breaking change is introduced, we may to avoid updating the changelog generation tool for awhile if the breaking change ends up being difficult to handle without providing a lot of value for this tool. If we defer this update, but we later discover a security issue with one of the other libraries, then we will be forced to take on both the security fix work and breaking change migration work at the same time, for all tools affected by both issues. If we use a separate module for each separate library, then we can avoid this extra work. Example 2:Say we want to add a new feature to this tool, such as pushing these release notes to S3. We add a new library to wrap S3 API calls, which may be needed for things like handling pagination, retries, etc. If there is a breaking change in elsewhere in the library module, then migrating to accommodate this breaking change will now be required to add the new feature. This adds extra work where there otherwise wouldn't be any. Example 3 (experienced with Teleport dependencies):Right now the library module is relatively simple with few dependencies, keeping it small. However, if the module adds a significant number of dependencies (see the above discussion about go-git), and it adds one of the Go reflection footguns (directly or indirectly via a dependency), then the binary size for every tool will explode. Using separate modules negates this issue as only dependencies (and dependencies of dependencies, and so on) that are needed by a given tool will be included. At absolute bare minimum, this Go library module needs to move to a subdirectory of |
This is a rewrite of the
changelog.sh
script to Go. This should make it easier to maintain and to align with the companies preference to write tooling in Go. This PR also includes the following:Enterprise:
if there are no Enterprise changelogs.changelog
is not present in PR body.Some notes for implementation:
gh
package to wrap the calls to thegh
CLI. When looking to implement using the GitHub Web APIs directly I noticed that it would be much simpler with GitHub v4 API than with v3 and since that didn't really fit with our existing v3 library and would over-complicate the PR I figured better to just keep the simple implementation for now.git
package for some encapsulation aroundgit