Skip to content

Commit

Permalink
feat: use new Kilnfile to construct GitHub client
Browse files Browse the repository at this point in the history
Co-authored-by: Joe Eltgroth <jeltgroth@vmware.com>

story: TPCF-26493

this is required for generating tile release notes
  • Loading branch information
crhntr committed Aug 16, 2024
1 parent b840a4f commit b2ce0ba
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 103 deletions.
43 changes: 30 additions & 13 deletions internal/commands/release_notes.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import (
"text/template"
"time"

"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-git/v5"
"github.com/google/go-github/v50/github"
"github.com/pivotal-cf/jhanda"

"github.com/pivotal-cf/kiln/internal/baking"
"github.com/pivotal-cf/kiln/internal/gh"
"github.com/pivotal-cf/kiln/pkg/notes"
)
Expand All @@ -27,13 +29,15 @@ const releaseDateFormat = "2006-01-02"

type ReleaseNotes struct {
Options struct {
ReleaseDate string `long:"release-date" short:"d" description:"release date of the tile"`
TemplateName string `long:"template" short:"t" description:"path to template"`
GithubToken string `long:"github-token" short:"g" description:"auth token for fetching issues merged between releases" env:"GITHUB_TOKEN"`
GithubHost string `long:"github-host" description:"set this when you are using GitHub enterprise" env:"GITHUB_HOST"`
Kilnfile string `long:"kilnfile" short:"k" description:"path to Kilnfile"`
DocsFile string `long:"update-docs" short:"u" description:"path to docs file to update"`
Window string `long:"window" short:"w" description:"GA window for release notes" default:"ga"`
ReleaseDate string `long:"release-date" short:"d" description:"release date of the tile"`
TemplateName string `long:"template" short:"t" description:"path to template"`
GithubToken string `long:"github-token" short:"g" description:"auth token for fetching issues merged between releases" env:"GITHUB_TOKEN"`
GithubHost string `long:"github-host" description:"set this when you are using GitHub enterprise" env:"GITHUB_HOST"`
Kilnfile string `long:"kilnfile" short:"k" description:"path to Kilnfile"`
DocsFile string `long:"update-docs" short:"u" description:"path to docs file to update"`
Window string `long:"window" short:"w" description:"GA window for release notes" default:"ga"`
VariableFiles []string `long:"variables-file" short:"vf" description:"path to a file containing variables to interpolate"`
Variables []string `long:"variable" short:"vr" description:"key value pairs of variables to interpolate"`
notes.IssuesQuery
notes.TrainstatQuery
}
Expand All @@ -43,19 +47,21 @@ type ReleaseNotes struct {
stat func(name string) (fs.FileInfo, error)
io.Writer

fetchNotesData FetchNotesData
fetchNotesData FetchNotesData
variablesService baking.TemplateVariablesService

repoOwner, repoName string
}

type FetchNotesData func(ctx context.Context, repo *git.Repository, client *github.Client, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision string, issuesQuery notes.IssuesQuery, trainstatClient notes.TrainstatNotesFetcher) (notes.Data, error)
type FetchNotesData func(ctx context.Context, repo *git.Repository, client *github.Client, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision string, issuesQuery notes.IssuesQuery, trainstatClient notes.TrainstatNotesFetcher, variables map[string]any) (notes.Data, error)

func NewReleaseNotesCommand() (ReleaseNotes, error) {
return ReleaseNotes{
fetchNotesData: notes.FetchData,
readFile: os.ReadFile,
Writer: os.Stdout,
stat: os.Stat,
variablesService: baking.NewTemplateVariablesService(osfs.New(".")),
fetchNotesData: notes.FetchData,
readFile: os.ReadFile,
Writer: os.Stdout,
stat: os.Stat,
}, nil
}

Expand All @@ -73,6 +79,16 @@ func (r ReleaseNotes) Execute(args []string) error {
return err
}

templateVariables, err := r.variablesService.FromPathsAndPairs(r.Options.VariableFiles, r.Options.Variables)
if err != nil {
return fmt.Errorf("failed to parse template variables: %s", err)
}
if varValue, ok := templateVariables["github_token"]; !ok && r.Options.GithubToken != "" {
templateVariables["github_token"] = r.Options.GithubToken
} else if ok && r.Options.GithubToken == "" {
r.Options.GithubToken = varValue.(string)
}

ctx := context.Background()

if err := r.initRepo(); err != nil {
Expand Down Expand Up @@ -101,6 +117,7 @@ func (r ReleaseNotes) Execute(args []string) error {
nonFlagArgs[0], nonFlagArgs[1],
r.Options.IssuesQuery,
&trainstatClient,
templateVariables,
)
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/release_notes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestReleaseNotes_Execute(t *testing.T) {
repoOwner: "bunch",
repoName: "banana",
readFile: readFileFunc,
fetchNotesData: func(c context.Context, repo *git.Repository, ghc *github.Client, tro, trn, kfp, ir, fr string, iq notes.IssuesQuery, _ notes.TrainstatNotesFetcher) (notes.Data, error) {
fetchNotesData: func(c context.Context, repo *git.Repository, ghc *github.Client, tro, trn, kfp, ir, fr string, iq notes.IssuesQuery, _ notes.TrainstatNotesFetcher, __ map[string]any) (notes.Data, error) {
ctx, repository, client = c, repo, ghc
tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision = tro, trn, kfp, ir, fr
issuesQuery = iq
Expand All @@ -94,7 +94,7 @@ func TestReleaseNotes_Execute(t *testing.T) {
{BOSHReleaseTarballLock: cargo.BOSHReleaseTarballLock{Name: "lemon", Version: "1.1.0"}},
},
Bumps: cargo.BumpList{
{Name: "banana", FromVersion: "1.1.0", ToVersion: "1.2.0"},
{Name: "banana", From: cargo.BOSHReleaseTarballLock{Version: "1.1.0"}, To: cargo.BOSHReleaseTarballLock{Version: "1.2.0"}},
},
TrainstatNotes: []string{
"* **[Feature]** this is a feature.",
Expand Down
19 changes: 4 additions & 15 deletions internal/component/github_release_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

"github.com/Masterminds/semver/v3"
"github.com/google/go-github/v50/github"
"golang.org/x/oauth2"

"github.com/pivotal-cf/kiln/internal/gh"
"github.com/pivotal-cf/kiln/pkg/cargo"
Expand All @@ -38,26 +37,16 @@ func NewGithubReleaseSource(c cargo.ReleaseSourceConfig) *GithubReleaseSource {
if c.Type != "" && c.Type != ReleaseSourceTypeGithub {
panic(panicMessageWrongReleaseSourceType)
}
if c.GithubToken == "" {
if c.GithubToken == "" { // TODO remove this
panic("no token passed for github release source")
}
if c.Org == "" {
panic("no github org passed for github release source")
}
ctx := context.TODO()
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: c.GithubToken})
tokenClient := oauth2.NewClient(ctx, tokenSource)
var githubClient *github.Client
if c.Endpoint != "" {
var err error
githubClient, err = github.NewEnterpriseClient(c.Endpoint, c.Endpoint, tokenClient)
if err != nil {
panic(err)
}
} else {
githubClient = github.NewClient(tokenClient)
githubClient, err := c.GitHubClient(context.TODO())
if err != nil {
panic(err)
}

return &GithubReleaseSource{
ReleaseSourceConfig: c,
Token: c.GithubToken,
Expand Down
61 changes: 45 additions & 16 deletions pkg/cargo/bump.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cargo

import (
"context"
"fmt"
"slices"
"sort"
"strings"
Expand All @@ -14,7 +15,8 @@ import (
)

type Bump struct {
Name, FromVersion, ToVersion string
Name string
From, To BOSHReleaseTarballLock

Releases []*github.RepositoryRelease
}
Expand All @@ -34,6 +36,9 @@ func (bump Bump) ReleaseNotes() string {
return strings.TrimSpace(s.String())
}

func (bump Bump) ToVersion() string { return bump.To.Version }
func (bump Bump) FromVersion() string { return bump.From.Version }

func deduplicateReleasesWithTheSameTagName(bump Bump) Bump {
updated := bump
updated.Releases = slices.Clone(bump.Releases)
Expand Down Expand Up @@ -67,9 +72,9 @@ func CalculateBumps(current, previous []BOSHReleaseTarballLock) []Bump {
continue
}
bumps = append(bumps, Bump{
Name: c.Name,
FromVersion: p.Version,
ToVersion: c.Version,
Name: c.Name,
From: p,
To: c,
})
}
return bumps
Expand All @@ -78,20 +83,20 @@ func CalculateBumps(current, previous []BOSHReleaseTarballLock) []Bump {
func WinfsVersionBump(bumped bool, version string, bumps []Bump) []Bump {
if bumped {
bumps = append(bumps, Bump{
Name: "windowsfs-release",
ToVersion: version,
Name: "windowsfs-release",
To: BOSHReleaseTarballLock{Version: version},
})
}
return bumps
}

func (bump Bump) toFrom() (to, from *semver.Version, _ error) {
var err error
from, err = semver.NewVersion(bump.FromVersion)
from, err = semver.NewVersion(bump.From.Version)
if err != nil {
return nil, nil, err
}
to, err = semver.NewVersion(bump.ToVersion)
to, err = semver.NewVersion(bump.To.Version)
if err != nil {
return nil, nil, err
}
Expand All @@ -107,9 +112,9 @@ func (list BumpList) ForLock(lock BOSHReleaseTarballLock) Bump {
}
}
return Bump{
Name: lock.Name,
FromVersion: lock.Version,
ToVersion: lock.Version,
Name: lock.Name,
From: lock,
To: lock,
}
}

Expand All @@ -121,9 +126,12 @@ type repositoryReleaseLister interface {
ListReleases(ctx context.Context, owner, repo string, opts *github.ListOptions) ([]*github.RepositoryRelease, *github.Response, error)
}

type RepositoryReleaseLister = repositoryReleaseLister
type (
RepositoryReleaseLister = repositoryReleaseLister
githubClientFunc func(Kilnfile, BOSHReleaseTarballLock) (repositoryReleaseLister, error)
)

func ReleaseNotes(ctx context.Context, repoService RepositoryReleaseLister, kf Kilnfile, list BumpList) (BumpList, error) {
func releaseNotes(ctx context.Context, kf Kilnfile, list BumpList, client githubClientFunc) (BumpList, error) {
const workerCount = 10

type fetchReleaseNotesForBump struct {
Expand All @@ -143,7 +151,7 @@ func ReleaseNotes(ctx context.Context, repoService RepositoryReleaseLister, kf K
go func() {
defer wg.Done()
for j := range in {
j.bump = fetchReleasesForBump(ctx, repoService, kf, j.bump)
j.bump = fetchReleasesForBump(ctx, kf, j.bump, client)
results <- j
}
}()
Expand Down Expand Up @@ -174,6 +182,23 @@ func ReleaseNotes(ctx context.Context, repoService RepositoryReleaseLister, kf K
return list, nil
}

func ReleaseNotes(ctx context.Context, kf Kilnfile, list BumpList) (BumpList, error) {
return releaseNotes(ctx, kf, list, func(kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) {
i := slices.IndexFunc(kf.ReleaseSources, func(config ReleaseSourceConfig) bool {
return BOSHReleaseTarballSourceID(config) == lock.RemoteSource
})
if i < 0 {
return nil, fmt.Errorf("release source with id %s not found", lock.RemoteSource)
}
source := kf.ReleaseSources[i]
client, err := source.GitHubClient(ctx)
if err != nil {
return nil, err
}
return client.Repositories, err
})
}

func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLister, repository string, from, to *semver.Version) []*github.RepositoryRelease {
owner, repo, err := gh.RepositoryOwnerAndNameFromPath(repository)
if err != nil {
Expand All @@ -196,7 +221,11 @@ func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLis
return result
}

func fetchReleasesForBump(ctx context.Context, repoService RepositoryReleaseLister, kf Kilnfile, bump Bump) Bump {
func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, client githubClientFunc) Bump {
lister, err := client(kf, bump.To)
if err != nil {
return bump
}
spec, err := kf.BOSHReleaseTarballSpecification(bump.Name)
if err != nil {
return bump
Expand All @@ -208,7 +237,7 @@ func fetchReleasesForBump(ctx context.Context, repoService RepositoryReleaseList
}

if spec.GitHubRepository != "" {
releases := fetchReleasesFromRepo(ctx, repoService, spec.GitHubRepository, from, to)
releases := fetchReleasesFromRepo(ctx, lister, spec.GitHubRepository, from, to)
bump.Releases = append(bump.Releases, releases...)
}

Expand Down
Loading

0 comments on commit b2ce0ba

Please sign in to comment.