Skip to content
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

Merged
merged 28 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
97a64c0
Introducing changelog
doggydogworld Jul 1, 2024
47c7d92
Moving things around
doggydogworld Jul 1, 2024
7d016de
Fixing typo
doggydogworld Jul 2, 2024
d8046e7
Changing licenses on new files
doggydogworld Jul 2, 2024
2bfafc1
Moving to multi-module
doggydogworld Jul 3, 2024
62d5e67
Moved to github SDK
doggydogworld Jul 5, 2024
eb0adee
Removing some unecessary code
doggydogworld Jul 5, 2024
9f091be
Requiring dir to be passed in to simplify code
doggydogworld Jul 5, 2024
cc60d0d
Initial refactor to go-git lib
doggydogworld Jul 5, 2024
d604039
Removing more git execs for native go git
doggydogworld Jul 5, 2024
de6e47e
Fixing some typos
doggydogworld Jul 5, 2024
6d34444
More refactors for git module
doggydogworld Jul 5, 2024
7ce3d02
Moving another function to git module
doggydogworld Jul 5, 2024
3d7f69d
Fixing typo
doggydogworld Jul 5, 2024
6b00945
Updating an error string
doggydogworld Jul 5, 2024
7ffa993
Restoring bot module deps
doggydogworld Jul 5, 2024
d3a4a52
Moving around a file
doggydogworld Jul 5, 2024
f7c537f
Updating docs for git module
doggydogworld Jul 5, 2024
9acb082
Using v3 API for search
doggydogworld Jul 6, 2024
6e67e79
Cleaning up multi-module and adding links back to ent cl
doggydogworld Jul 9, 2024
d48641f
Using git CLI
doggydogworld Jul 9, 2024
207e590
Even prettier changelog
doggydogworld Jul 9, 2024
a6692fb
Go moduling changelog and libs
doggydogworld Jul 10, 2024
c94b5c0
Using cl for template name
doggydogworld Jul 10, 2024
f4a6950
Fixing changelog mod
doggydogworld Jul 10, 2024
62ba564
Updating govulncheck to use latest go version
doggydogworld Jul 15, 2024
2c75aae
Using more secure version of go-github
doggydogworld Jul 15, 2024
86a40ae
New dependencies
doggydogworld Jul 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions bot/go.mod
doggydogworld marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ require (
)

require (
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
)

require (
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
Expand Down
7 changes: 7 additions & 0 deletions bot/go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
Expand Down Expand Up @@ -69,10 +73,13 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand Down
18 changes: 18 additions & 0 deletions go.mod
Copy link
Contributor Author

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.

Copy link
Contributor

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.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module github.com/gravitational/shared-workflows
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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 1.22.4

require (
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/gravitational/trace v1.4.0
github.com/stretchr/testify v1.9.0
)

require (
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
golang.org/x/net v0.17.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
1,543 changes: 1,543 additions & 0 deletions go.sum

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions libs/gh/gh.go
doggydogworld marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package gh

import (
"bytes"
"os/exec"
"strings"

"github.com/gravitational/trace"
)

// IsAvailable returns status of git
func IsAvailable() error {
_, err := exec.LookPath("gh")
return err
}

// RunCmd runs the GitHub CLI returns output (stdout/stderr, depends on the cmd result) and error
func RunCmd(dir string, args ...string) (string, error) {
var stdout bytes.Buffer
var stderr bytes.Buffer

cmd := exec.Command("gh", args...)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
cmd.Dir = dir

err := cmd.Run()

if err != nil {
return strings.TrimSpace(stderr.String()), trace.Wrap(err)
}

return strings.TrimSpace(stdout.String()), nil
}
51 changes: 51 additions & 0 deletions libs/gh/pull_request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package gh

import (
"context"
"encoding/json"
"fmt"
"strings"

"github.com/gravitational/trace"
)

// ChangelogPR contains all the data necessary for a changelog from the PR
type ChangelogPR struct {
Body string `json:"body,omitempty"`
Number int `json:"number,omitempty"`
Title string `json:"title,omitempty"`
URL string `json:"url,omitempty"`
}

// ListChangelogPullRequestsOpts contains options for searching for changelog pull requests.
type ListChangelogPullRequestsOpts struct {
Branch string
FromDate string
ToDate string
}

// ListChangelogPullRequests will search for pull requests that provide changelog information.
func ListChangelogPullRequests(ctx context.Context, dir string, opts *ListChangelogPullRequestsOpts) ([]ChangelogPR, error) {
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")
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

@fheinecke fheinecke Jul 2, 2024

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.

if err != nil {
return prs, trace.Wrap(err)
}

dec := json.NewDecoder(strings.NewReader(data))
if err := dec.Decode(&prs); err != nil {
return prs, trace.Wrap(err)
}
return prs, nil
}

// dateRangeFormat takes in a date range and will format it for GitHub search syntax.
// to can be empty and the format will be to search everything after from
func dateRangeFormat(from, to string) string {
if to == "" {
return fmt.Sprintf(">%s", from)
}
return fmt.Sprintf("%s..%s", from, to)
}
52 changes: 52 additions & 0 deletions libs/git/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package git

import (
"bytes"
"os/exec"
"strings"

"github.com/gravitational/trace"
)

// IsAvailable returns status of git
func IsAvailable() error {
_, err := exec.LookPath("git")
return err
}

// RunCmd runs git and returns output (stdout/stderr, depends on the cmd result) and error
func RunCmd(dir string, args ...string) (string, error) {
var stdout bytes.Buffer
var stderr bytes.Buffer

cmd := exec.Command("git", args...)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
cmd.Dir = dir

err := cmd.Run()

if err != nil {
return strings.TrimSpace(stderr.String()), trace.Wrap(err)
}

return strings.TrimSpace(stdout.String()), nil
}
75 changes: 75 additions & 0 deletions tools/changelog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# changelog

This script generates a changelog for a release.

## Usage

```
usage: changelog [<flags>]

Flags:
--[no-]help Show context-sensitive help (also try --help-long and --help-man).
--base-branch=BASEBRANCH The base release branch to generate the changelog for. It will be of the form branch/v* ($BASE_BRANCH)
--base-tag=BASETAG The tag/version to generate the changelog from. It will be of the form vXX.Y.Z, e.g. v15.1.1 ($BASE_TAG)
```

It can optionally take two input variables: BASE_BRANCH: The base release
branch to generate the changelog for. It will be of the form "branch/v*".
BASE_TAG: The tag/version to generate the changelog from. It will be of the
form "vXX.Y.Z", e.g. "v15.1.1"


If neither are provided, the values will be automatically determined if
possible:
* The current branch will be used as the base branch if it matches the
pattern branch/v*
* If the current branch is forked from a base branch, the base branch will be
used. e.g. if you create release/15.1.1 from branch/v15, the branch/v15
will be the base branch.
* The base tag will be determined by running "make print-version" from the
root of the repo.


Enterprise PR changelogs will be listed after the OSS changelogs. You need to
determine if it is suitable to include them. If you do, remove the markdown
link from each changelog when adding the changelog to CHANGELOG.md. These
links won't work for the general public. Keep the links when adding the
changelog to the release PR so that the enterprise PRs will link to the
release PR.

If you reword changelogs, it is best to go to the source PR and change it
there and then regenerate the changelog.


Caveats:
* If you update the "e" ref in your release PR, and you also run `make
changelog` from the release PR branch, if you have already updated the
version in the makefile, you will need to run `make changelog
BASE_TAG=X.Y.Z` as this script will determine the base tag to be the
current release version not the last released version.


One preferred way of using this script is to run `make changelog` from the
base branch and save it: `make changelog > /tmp/changelog`. If any PRs are
merged to the base branch after you have created your release PR but before
you have merged it, you can see any new entries with:

```
git checkout branch/vNN
diff -u /tmp/changelog $(make changelog)
```
If there are changes, you can update your changelog and rebase your branch:
```
git pull on branch/vNN
make changelog > /tmp/changelog
git checkout release/XX.Y.Z
git rebase branch/vNN
<include /tmp/changelog in CHANGELOG.md>
git add CHANGELOG.md && git commit --amend --no-edit && git push -f
```

Ensure you update the PR body with the new changelog, doable on the command
line with `gh`:
```
gh pr edit --body-file /tmp/changelog
```
Loading
Loading