From 173c1aa6b2059577ddde0bdf6dbeb029c1a70245 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Thu, 15 Aug 2024 12:25:15 -0700 Subject: [PATCH 01/16] feat: support GitHub enterprise for BOSH Releases story: TPCF-26493 Co-authored-by: Joe Eltgroth --- .../workflows/scenario/step_funcs_github.go | 5 +++- internal/commands/release_notes.go | 6 ++++- internal/component/github_release_source.go | 12 +++++++-- internal/gh/client.go | 8 ++++-- internal/gh/client_test.go | 25 ++++++++++++++----- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/internal/acceptance/workflows/scenario/step_funcs_github.go b/internal/acceptance/workflows/scenario/step_funcs_github.go index 8f048a3d2..e68dae33a 100644 --- a/internal/acceptance/workflows/scenario/step_funcs_github.go +++ b/internal/acceptance/workflows/scenario/step_funcs_github.go @@ -13,7 +13,10 @@ func githubRepoHasReleaseWithTag(ctx context.Context, repoOrg, repoName, tag str if err != nil { return err } - ghAPI := gh.Client(ctx, accessToken) + ghAPI, err := gh.Client(ctx, "", accessToken) + if err != nil { + return fmt.Errorf("failed to setup github client: %w", err) + } _, response, err := ghAPI.Repositories.GetReleaseByTag(ctx, repoOrg, repoName, tag) if err != nil { return err diff --git a/internal/commands/release_notes.go b/internal/commands/release_notes.go index dc732deb0..8a1d703e9 100644 --- a/internal/commands/release_notes.go +++ b/internal/commands/release_notes.go @@ -30,6 +30,7 @@ type ReleaseNotes 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"` @@ -85,7 +86,10 @@ func (r ReleaseNotes) Execute(args []string) error { var client *github.Client if r.Options.GithubToken != "" { - client = gh.Client(ctx, r.Options.GithubToken) + client, err = gh.Client(ctx, r.Options.GithubHost, r.Options.GithubToken) + if err != nil { + return fmt.Errorf("failed to setup github client: %w", err) + } } trainstatClient := notes.NewTrainstatClient(r.Options.TrainstatQuery.TrainstatURL) diff --git a/internal/component/github_release_source.go b/internal/component/github_release_source.go index 8fba53e16..999d5a20c 100644 --- a/internal/component/github_release_source.go +++ b/internal/component/github_release_source.go @@ -44,11 +44,19 @@ func NewGithubReleaseSource(c cargo.ReleaseSourceConfig) *GithubReleaseSource { 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) - githubClient := github.NewClient(tokenClient) + 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) + } return &GithubReleaseSource{ ReleaseSourceConfig: c, diff --git a/internal/gh/client.go b/internal/gh/client.go index 861009bed..5263c525b 100644 --- a/internal/gh/client.go +++ b/internal/gh/client.go @@ -7,6 +7,10 @@ import ( "golang.org/x/oauth2" ) -func Client(ctx context.Context, accessToken string) *github.Client { - return github.NewClient(oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: accessToken}))) +func Client(ctx context.Context, host, accessToken string) (*github.Client, error) { + client := oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: accessToken})) + if host == "" { + return github.NewClient(client), nil + } + return github.NewEnterpriseClient(host, host, client) } diff --git a/internal/gh/client_test.go b/internal/gh/client_test.go index c86606b48..bcb97fab3 100644 --- a/internal/gh/client_test.go +++ b/internal/gh/client_test.go @@ -4,14 +4,27 @@ import ( "context" "testing" - "github.com/stretchr/testify/require" - "github.com/pivotal-cf/kiln/internal/gh" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestClient(t *testing.T) { - ctx := context.Background() - token := "xxx" - ghClient := gh.Client(ctx, token) - require.NotNil(t, ghClient.Client()) + t.Run("when the host is empty", func(t *testing.T) { + ctx := context.Background() + token := "xxx" + ghClient, err := gh.Client(ctx, "", token) + require.NoError(t, err) + require.NotNil(t, ghClient.Client()) + assert.Contains(t, ghClient.BaseURL.String(), "https://api.github.com") + }) + + t.Run("when the host is not empty", func(t *testing.T) { + ctx := context.Background() + token := "xxx" + ghClient, err := gh.Client(ctx, "https://example.com", token) + require.NoError(t, err) + require.NotNil(t, ghClient.Client()) + assert.Contains(t, ghClient.BaseURL.String(), "https://example.com") + }) } From b840a4f78ef2d3dac6c43391853ca1ef88a00702 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Fri, 16 Aug 2024 16:04:13 -0700 Subject: [PATCH 02/16] bump go-github to v50 --- internal/commands/release_notes.go | 2 +- internal/commands/release_notes_test.go | 2 +- internal/component/fakes/release_by_tag_getter.go | 2 +- .../component/fakes/release_by_tag_getter_asset_downloader.go | 2 +- internal/component/fakes/releases_lister.go | 2 +- .../fakes_internal/release_by_tag_getter_asset_downloader.go | 2 +- internal/component/fakes_internal/repository_release_lister.go | 2 +- internal/component/github_release_source.go | 2 +- internal/component/github_release_source_internal_test.go | 2 +- internal/component/github_release_source_test.go | 2 +- internal/gh/client.go | 2 +- pkg/cargo/bump.go | 2 +- pkg/cargo/bump_internal_test.go | 2 +- pkg/cargo/bump_test.go | 2 +- pkg/notes/internal/fakes/issue_getter.go | 2 +- pkg/notes/internal/fakes/issues_by_repo_lister.go | 2 +- pkg/notes/internal/fakes/issues_service.go | 2 +- pkg/notes/internal/fakes/milestone_lister.go | 2 +- pkg/notes/internal/fakes/releases_service.go | 2 +- pkg/notes/notes_data.go | 2 +- pkg/notes/notes_data_test.go | 2 +- pkg/notes/notes_page_test.go | 2 +- pkg/notes/notes_template_test.go | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/internal/commands/release_notes.go b/internal/commands/release_notes.go index 8a1d703e9..a94342a80 100644 --- a/internal/commands/release_notes.go +++ b/internal/commands/release_notes.go @@ -16,7 +16,7 @@ import ( "time" "github.com/go-git/go-git/v5" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/jhanda" "github.com/pivotal-cf/kiln/internal/gh" diff --git a/internal/commands/release_notes_test.go b/internal/commands/release_notes_test.go index c431ac38e..04059357b 100644 --- a/internal/commands/release_notes_test.go +++ b/internal/commands/release_notes_test.go @@ -14,7 +14,7 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/storage/memory" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/jhanda" "github.com/pivotal-cf/kiln/pkg/cargo" diff --git a/internal/component/fakes/release_by_tag_getter.go b/internal/component/fakes/release_by_tag_getter.go index 742dea393..8a0073791 100644 --- a/internal/component/fakes/release_by_tag_getter.go +++ b/internal/component/fakes/release_by_tag_getter.go @@ -5,7 +5,7 @@ import ( "context" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/kiln/internal/component" ) diff --git a/internal/component/fakes/release_by_tag_getter_asset_downloader.go b/internal/component/fakes/release_by_tag_getter_asset_downloader.go index 30fca6a80..38534107f 100644 --- a/internal/component/fakes/release_by_tag_getter_asset_downloader.go +++ b/internal/component/fakes/release_by_tag_getter_asset_downloader.go @@ -7,7 +7,7 @@ import ( "net/http" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/kiln/internal/component" ) diff --git a/internal/component/fakes/releases_lister.go b/internal/component/fakes/releases_lister.go index f9f40aa6c..7ca2df186 100644 --- a/internal/component/fakes/releases_lister.go +++ b/internal/component/fakes/releases_lister.go @@ -5,7 +5,7 @@ import ( "context" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/kiln/internal/component" ) diff --git a/internal/component/fakes_internal/release_by_tag_getter_asset_downloader.go b/internal/component/fakes_internal/release_by_tag_getter_asset_downloader.go index b23c72c42..28ed19f62 100644 --- a/internal/component/fakes_internal/release_by_tag_getter_asset_downloader.go +++ b/internal/component/fakes_internal/release_by_tag_getter_asset_downloader.go @@ -7,7 +7,7 @@ import ( "net/http" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" ) type ReleaseByTagGetterAssetDownloader struct { diff --git a/internal/component/fakes_internal/repository_release_lister.go b/internal/component/fakes_internal/repository_release_lister.go index 042e3b89c..d712a4e90 100644 --- a/internal/component/fakes_internal/repository_release_lister.go +++ b/internal/component/fakes_internal/repository_release_lister.go @@ -5,7 +5,7 @@ import ( "context" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" ) type RepositoryReleaseLister struct { diff --git a/internal/component/github_release_source.go b/internal/component/github_release_source.go index 999d5a20c..204d701a3 100644 --- a/internal/component/github_release_source.go +++ b/internal/component/github_release_source.go @@ -15,7 +15,7 @@ import ( "strings" "github.com/Masterminds/semver/v3" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "golang.org/x/oauth2" "github.com/pivotal-cf/kiln/internal/gh" diff --git a/internal/component/github_release_source_internal_test.go b/internal/component/github_release_source_internal_test.go index b96a5e985..b0cc374c8 100644 --- a/internal/component/github_release_source_internal_test.go +++ b/internal/component/github_release_source_internal_test.go @@ -9,7 +9,7 @@ import ( "os" "testing" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" . "github.com/onsi/gomega" diff --git a/internal/component/github_release_source_test.go b/internal/component/github_release_source_test.go index 87b28d980..d121429cb 100644 --- a/internal/component/github_release_source_test.go +++ b/internal/component/github_release_source_test.go @@ -11,7 +11,7 @@ import ( "os" "testing" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" . "github.com/onsi/gomega" "github.com/pivotal-cf/kiln/internal/component" diff --git a/internal/gh/client.go b/internal/gh/client.go index 5263c525b..e4db8aef6 100644 --- a/internal/gh/client.go +++ b/internal/gh/client.go @@ -3,7 +3,7 @@ package gh import ( "context" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "golang.org/x/oauth2" ) diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index ff0c5f57b..0daf74558 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -8,7 +8,7 @@ import ( "sync" "github.com/Masterminds/semver/v3" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/kiln/internal/gh" ) diff --git a/pkg/cargo/bump_internal_test.go b/pkg/cargo/bump_internal_test.go index dd4986311..991569f85 100644 --- a/pkg/cargo/bump_internal_test.go +++ b/pkg/cargo/bump_internal_test.go @@ -5,7 +5,7 @@ import ( . "github.com/onsi/gomega" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" ) func TestInternal_deduplicateReleasesWithTheSameTagName(t *testing.T) { diff --git a/pkg/cargo/bump_test.go b/pkg/cargo/bump_test.go index 826c754f4..6b24d627f 100644 --- a/pkg/cargo/bump_test.go +++ b/pkg/cargo/bump_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" . "github.com/onsi/gomega" diff --git a/pkg/notes/internal/fakes/issue_getter.go b/pkg/notes/internal/fakes/issue_getter.go index 3dbaa90cc..ea84d5afe 100644 --- a/pkg/notes/internal/fakes/issue_getter.go +++ b/pkg/notes/internal/fakes/issue_getter.go @@ -5,7 +5,7 @@ import ( "context" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" ) type IssueGetter struct { diff --git a/pkg/notes/internal/fakes/issues_by_repo_lister.go b/pkg/notes/internal/fakes/issues_by_repo_lister.go index f63c2368d..b05a0543c 100644 --- a/pkg/notes/internal/fakes/issues_by_repo_lister.go +++ b/pkg/notes/internal/fakes/issues_by_repo_lister.go @@ -5,7 +5,7 @@ import ( "context" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" ) type IssuesByRepoLister struct { diff --git a/pkg/notes/internal/fakes/issues_service.go b/pkg/notes/internal/fakes/issues_service.go index fb4af88f0..d0dfb05c7 100644 --- a/pkg/notes/internal/fakes/issues_service.go +++ b/pkg/notes/internal/fakes/issues_service.go @@ -5,7 +5,7 @@ import ( "context" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" ) type IssuesService struct { diff --git a/pkg/notes/internal/fakes/milestone_lister.go b/pkg/notes/internal/fakes/milestone_lister.go index 02d2c029d..c2e007fc1 100644 --- a/pkg/notes/internal/fakes/milestone_lister.go +++ b/pkg/notes/internal/fakes/milestone_lister.go @@ -5,7 +5,7 @@ import ( "context" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" ) type MilestoneLister struct { diff --git a/pkg/notes/internal/fakes/releases_service.go b/pkg/notes/internal/fakes/releases_service.go index 0d89fd752..895e31ac5 100644 --- a/pkg/notes/internal/fakes/releases_service.go +++ b/pkg/notes/internal/fakes/releases_service.go @@ -5,7 +5,7 @@ import ( "context" "sync" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/kiln/pkg/cargo" ) diff --git a/pkg/notes/notes_data.go b/pkg/notes/notes_data.go index e06175f00..23830ed07 100644 --- a/pkg/notes/notes_data.go +++ b/pkg/notes/notes_data.go @@ -21,7 +21,7 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "gopkg.in/yaml.v2" "github.com/pivotal-cf/kiln/pkg/cargo" diff --git a/pkg/notes/notes_data_test.go b/pkg/notes/notes_data_test.go index 93ec5bcb0..a5372bfa1 100644 --- a/pkg/notes/notes_data_test.go +++ b/pkg/notes/notes_data_test.go @@ -16,7 +16,7 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/storage/memory" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/kiln/pkg/cargo" "github.com/pivotal-cf/kiln/pkg/notes/internal/fakes" diff --git a/pkg/notes/notes_page_test.go b/pkg/notes/notes_page_test.go index 5ff4d80a6..5488881d7 100644 --- a/pkg/notes/notes_page_test.go +++ b/pkg/notes/notes_page_test.go @@ -17,7 +17,7 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/storage/memory" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" "github.com/pivotal-cf/kiln/pkg/cargo" ) diff --git a/pkg/notes/notes_template_test.go b/pkg/notes/notes_template_test.go index 78bdb3c3b..9fedfa015 100644 --- a/pkg/notes/notes_template_test.go +++ b/pkg/notes/notes_template_test.go @@ -6,7 +6,7 @@ import ( "text/template" "github.com/Masterminds/semver/v3" - "github.com/google/go-github/v40/github" + "github.com/google/go-github/v50/github" . "github.com/onsi/gomega" "github.com/pivotal-cf/kiln/pkg/cargo" From b2ce0ba37a846a97de902e66017a50fbb9b2d93d Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Fri, 16 Aug 2024 14:28:06 -0700 Subject: [PATCH 03/16] feat: use new Kilnfile to construct GitHub client Co-authored-by: Joe Eltgroth story: TPCF-26493 this is required for generating tile release notes --- internal/commands/release_notes.go | 43 ++++++++++---- internal/commands/release_notes_test.go | 4 +- internal/component/github_release_source.go | 19 ++---- pkg/cargo/bump.go | 61 ++++++++++++++----- pkg/cargo/bump_test.go | 66 +++++++++++++++------ pkg/cargo/files.go | 4 +- pkg/cargo/kilnfile.go | 17 ++++++ pkg/notes/notes_data.go | 35 +++++++---- pkg/notes/notes_data_test.go | 4 -- pkg/notes/notes_page_test.go | 44 +++++++------- 10 files changed, 194 insertions(+), 103 deletions(-) diff --git a/internal/commands/release_notes.go b/internal/commands/release_notes.go index a94342a80..90bf39dd1 100644 --- a/internal/commands/release_notes.go +++ b/internal/commands/release_notes.go @@ -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" ) @@ -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 } @@ -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 } @@ -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 { @@ -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 diff --git a/internal/commands/release_notes_test.go b/internal/commands/release_notes_test.go index 04059357b..8af9f6bbf 100644 --- a/internal/commands/release_notes_test.go +++ b/internal/commands/release_notes_test.go @@ -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 @@ -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.", diff --git a/internal/component/github_release_source.go b/internal/component/github_release_source.go index 204d701a3..0c7ab317f 100644 --- a/internal/component/github_release_source.go +++ b/internal/component/github_release_source.go @@ -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" @@ -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, diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index 0daf74558..16af59e33 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -2,6 +2,7 @@ package cargo import ( "context" + "fmt" "slices" "sort" "strings" @@ -14,7 +15,8 @@ import ( ) type Bump struct { - Name, FromVersion, ToVersion string + Name string + From, To BOSHReleaseTarballLock Releases []*github.RepositoryRelease } @@ -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) @@ -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 @@ -78,8 +83,8 @@ 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 @@ -87,11 +92,11 @@ func WinfsVersionBump(bumped bool, version string, bumps []Bump) []Bump { 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 } @@ -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, } } @@ -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 { @@ -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 } }() @@ -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 { @@ -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 @@ -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...) } diff --git a/pkg/cargo/bump_test.go b/pkg/cargo/bump_test.go index 6b24d627f..edafaba80 100644 --- a/pkg/cargo/bump_test.go +++ b/pkg/cargo/bump_test.go @@ -33,7 +33,7 @@ func TestCalculateBumps(t *testing.T) { {Name: "a", Version: "1"}, {Name: "b", Version: "1"}, })).To(Equal([]Bump{ - {Name: "b", FromVersion: "1", ToVersion: "2"}, + {Name: "b", From: BOSHReleaseTarballLock{Name: "b", Version: "1"}, To: BOSHReleaseTarballLock{Name: "b", Version: "2"}}, }), "it returns the changed lock", ) @@ -49,8 +49,8 @@ func TestCalculateBumps(t *testing.T) { {Name: "b", Version: "1"}, {Name: "c", Version: "1"}, })).To(Equal([]Bump{ - {Name: "a", FromVersion: "1", ToVersion: "2"}, - {Name: "c", FromVersion: "1", ToVersion: "2"}, + {Name: "a", From: BOSHReleaseTarballLock{Name: "a", Version: "1"}, To: BOSHReleaseTarballLock{Name: "a", Version: "2"}}, + {Name: "c", From: BOSHReleaseTarballLock{Name: "c", Version: "1"}, To: BOSHReleaseTarballLock{Name: "c", Version: "2"}}, }), "it returns all the bumps", ) @@ -77,7 +77,7 @@ func TestCalculateBumps(t *testing.T) { }, []BOSHReleaseTarballLock{ {Name: "a", Version: "1"}, })).To(Equal([]Bump{ - {Name: "b", FromVersion: "", ToVersion: "1"}, + {Name: "b", From: BOSHReleaseTarballLock{}, To: BOSHReleaseTarballLock{Name: "b", Version: "1"}}, }), "it returns the component as a bump", ) @@ -90,18 +90,18 @@ func TestWinfsVersionBump(t *testing.T) { t.Run("when the winfs version is not bumped", func(t *testing.T) { please.Expect(WinfsVersionBump(false, "2.61.0", []Bump{ - {Name: "b", FromVersion: "1", ToVersion: "2"}, + {Name: "b", From: BOSHReleaseTarballLock{Version: "1"}, To: BOSHReleaseTarballLock{Version: "2"}}, })).To(Equal([]Bump{ - {Name: "b", FromVersion: "1", ToVersion: "2"}, + {Name: "b", From: BOSHReleaseTarballLock{Version: "1"}, To: BOSHReleaseTarballLock{Version: "2"}}, })) }) t.Run("when the winfs version is bumped", func(t *testing.T) { please.Expect(WinfsVersionBump(true, "2.61.0", []Bump{ - {Name: "b", FromVersion: "1", ToVersion: "2"}, + {Name: "b", From: BOSHReleaseTarballLock{Version: "1"}, To: BOSHReleaseTarballLock{Version: "2"}}, })).To(Equal([]Bump{ - {Name: "b", FromVersion: "1", ToVersion: "2"}, - {Name: "windowsfs-release", FromVersion: "", ToVersion: "2.61.0"}, + {Name: "b", From: BOSHReleaseTarballLock{Version: "1"}, To: BOSHReleaseTarballLock{Version: "2"}}, + {Name: "windowsfs-release", From: BOSHReleaseTarballLock{Version: ""}, To: BOSHReleaseTarballLock{Version: "2.61.0"}}, })) }) } @@ -140,9 +140,8 @@ func TestInternal_addReleaseNotes(t *testing.T) { return nil, nil, nil } - result, err := ReleaseNotes( + result, err := releaseNotes( context.Background(), - releaseLister, Kilnfile{ Releases: []BOSHReleaseTarballSpecification{ { @@ -156,15 +155,17 @@ func TestInternal_addReleaseNotes(t *testing.T) { }, BumpList{ { - Name: "peach", - ToVersion: "2.0.1", // served - FromVersion: "0.1.3", // ripe + Name: "peach", + To: BOSHReleaseTarballLock{Version: "2.0.1"}, // served + From: BOSHReleaseTarballLock{Version: "0.1.3"}, // ripe }, { - Name: "mango", - ToVersion: "10", - FromVersion: "9", + Name: "mango", + To: BOSHReleaseTarballLock{Version: "10"}, + From: BOSHReleaseTarballLock{Version: "9"}, }, + }, func(kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { + return releaseLister, nil }) please.Expect(err).NotTo(HaveOccurred()) please.Expect(result).To(HaveLen(2)) @@ -174,6 +175,37 @@ func TestInternal_addReleaseNotes(t *testing.T) { please.Expect(result[0].ReleaseNotes()).To(Equal("served\nplated\nstored\nlabeled\npreserved\nchopped\ncleaned")) } +func Test_deduplicateReleasesWithTheSameTagName(t *testing.T) { + please := NewWithT(t) + b := Bump{ + Releases: []*github.RepositoryRelease{ + {TagName: ptr("Y")}, + {TagName: ptr("1")}, + {TagName: ptr("2")}, + {TagName: ptr("3")}, + {TagName: ptr("3")}, + {TagName: ptr("3")}, + {TagName: ptr("X")}, + {TagName: ptr("2")}, + {TagName: ptr("4")}, + {TagName: ptr("4")}, + }, + } + b = deduplicateReleasesWithTheSameTagName(b) + tags := make([]string, 0, len(b.Releases)) + for _, r := range b.Releases { + tags = append(tags, r.GetTagName()) + } + please.Expect(tags).To(Equal([]string{ + "Y", + "1", + "2", + "3", + "X", + "4", + })) +} + func githubResponse(t *testing.T, status int) *github.Response { t.Helper() diff --git a/pkg/cargo/files.go b/pkg/cargo/files.go index 80f753930..7deecc01f 100644 --- a/pkg/cargo/files.go +++ b/pkg/cargo/files.go @@ -20,6 +20,8 @@ func InterpolateAndParseKilnfile(in io.Reader, templateVariables map[string]any) return Kilnfile{}, fmt.Errorf("unable to read Kilnfile: %w", err) } + fmt.Println(string(kilnfileYAML)) + kilnfileTemplate, err := template.New("Kilnfile"). Funcs(template.FuncMap{ "variable": variableTemplateFunction(templateVariables), @@ -28,7 +30,7 @@ func InterpolateAndParseKilnfile(in io.Reader, templateVariables map[string]any) Option("missingkey=error"). Parse(string(kilnfileYAML)) if err != nil { - return Kilnfile{}, err + return Kilnfile{}, fmt.Errorf("failed to interpolate kilnfile using text/template: %w", err) } var buf bytes.Buffer diff --git a/pkg/cargo/kilnfile.go b/pkg/cargo/kilnfile.go index 4622543e2..dc9212a72 100644 --- a/pkg/cargo/kilnfile.go +++ b/pkg/cargo/kilnfile.go @@ -1,8 +1,11 @@ package cargo import ( + "context" "errors" "fmt" + "github.com/google/go-github/v50/github" + "golang.org/x/oauth2" "strings" "gopkg.in/yaml.v3" @@ -169,6 +172,20 @@ type ReleaseSourceConfig struct { Password string `yaml:"password,omitempty"` } +func (c ReleaseSourceConfig) GitHubClient(ctx context.Context) (*github.Client, error) { + if c.GithubToken == "" { + return nil, errors.New("no token passed for github release source") + } + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: c.GithubToken}) + tokenClient := oauth2.NewClient(ctx, tokenSource) + var githubClient *github.Client + if c.Endpoint != "" { + return github.NewEnterpriseClient(c.Endpoint, c.Endpoint, tokenClient) + } + githubClient = github.NewClient(tokenClient) + return githubClient, nil +} + // BOSHReleaseTarballLock represents an exact build of a bosh release // It may identify the where the release is cached; // it may identify the stemcell used to compile the release. diff --git a/pkg/notes/notes_data.go b/pkg/notes/notes_data.go index 23830ed07..b44b5b868 100644 --- a/pkg/notes/notes_data.go +++ b/pkg/notes/notes_data.go @@ -127,8 +127,8 @@ func (q IssuesQuery) Exp() (*regexp.Regexp, error) { return regexp.Compile(str) } -func FetchData(ctx context.Context, repo *git.Repository, client *github.Client, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision string, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher) (Data, error) { - f, err := newFetchNotesData(repo, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision, client, issuesQuery, trainstatClient) +func FetchData(ctx context.Context, repo *git.Repository, client *github.Client, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision string, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher, variables map[string]any) (Data, error) { + f, err := newFetchNotesData(repo, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision, client, issuesQuery, trainstatClient, variables) if err != nil { return Data{}, err } @@ -138,11 +138,10 @@ func FetchData(ctx context.Context, repo *git.Repository, client *github.Client, // FetchDataWithoutRepo can be used to generate release notes from tile metadata func FetchDataWithoutRepo(ctx context.Context, client *github.Client, tileRepoOwner, tileRepoName string, kilnfile cargo.Kilnfile, kilnfileLockInitial, kilnfileLockFinal cargo.KilnfileLock, issuesQuery IssuesQuery) (Data, error) { r := fetchNotesData{ - repoOwner: tileRepoOwner, - repoName: tileRepoName, - issuesQuery: issuesQuery, - issuesService: client.Issues, - releasesService: client.Repositories, + repoOwner: tileRepoOwner, + repoName: tileRepoName, + issuesQuery: issuesQuery, + issuesService: client.Issues, } data := Data{ Bumps: cargo.CalculateBumps(kilnfileLockFinal.Releases, kilnfileLockInitial.Releases), @@ -164,7 +163,7 @@ func FetchDataWithoutRepo(ctx context.Context, client *github.Client, tileRepoOw return data, nil } -func newFetchNotesData(repo *git.Repository, tileRepoOwner string, tileRepoName string, kilnfilePath string, initialRevision string, finalRevision string, client *github.Client, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher) (fetchNotesData, error) { +func newFetchNotesData(repo *git.Repository, tileRepoOwner string, tileRepoName string, kilnfilePath string, initialRevision string, finalRevision string, client *github.Client, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher, variables map[string]any) (fetchNotesData, error) { if repo == nil { return fetchNotesData{}, errors.New("git repository required to generate release notes") } @@ -184,11 +183,12 @@ func newFetchNotesData(repo *git.Repository, tileRepoOwner string, tileRepoName issuesQuery: issuesQuery, trainstatClient: trainstatClient, + + variables: variables, } if client != nil { f.issuesService = client.Issues - f.releasesService = client.Repositories } return f, nil } @@ -201,7 +201,6 @@ type fetchNotesData struct { repository *git.Repository issuesService - releasesService cargo.RepositoryReleaseLister repoOwner, repoName, kilnfilePath, @@ -209,6 +208,8 @@ type fetchNotesData struct { issuesQuery IssuesQuery trainstatClient TrainstatNotesFetcher + + variables map[string]any } func (r fetchNotesData) fetch(ctx context.Context) (Data, error) { @@ -359,10 +360,20 @@ type issuesService interface { // test for Execute does not set GithubToken intentionally so this code is not triggered and Execute does not actually // reach out to GitHub. func (r fetchNotesData) fetchIssuesAndReleaseNotes(ctx context.Context, finalKF, wtKF cargo.Kilnfile, bumpList cargo.BumpList, issuesQuery IssuesQuery) ([]*github.Issue, cargo.BumpList, error) { - if r.releasesService == nil || r.issuesService == nil { + if r.issuesService == nil { return nil, bumpList, nil } - bumpList, err := cargo.ReleaseNotes(ctx, r.releasesService, setEmptyComponentGitHubRepositoryFromOtherKilnfile(finalKF, wtKF), bumpList) + + buf, err := yaml.Marshal(finalKF) + if err != nil { + return nil, nil, err + } + finalKF, err = cargo.InterpolateAndParseKilnfile(bytes.NewReader(buf), r.variables) + if err != nil { + return nil, nil, err + } + + bumpList, err = cargo.ReleaseNotes(ctx, setEmptyComponentGitHubRepositoryFromOtherKilnfile(finalKF, wtKF), bumpList) if err != nil { return nil, nil, err } diff --git a/pkg/notes/notes_data_test.go b/pkg/notes/notes_data_test.go index a5372bfa1..6a2c51416 100644 --- a/pkg/notes/notes_data_test.go +++ b/pkg/notes/notes_data_test.go @@ -115,7 +115,6 @@ func Test_fetch_for_ist_tas(t *testing.T) { historicVersion: historicVersion.Spy, issuesService: fakeIssuesService, - releasesService: fakeReleaseService, trainstatClient: fakeTrainstatClient, } @@ -129,7 +128,6 @@ func Test_fetch_for_ist_tas(t *testing.T) { please.Expect(historicVersion.CallCount()).To(Equal(1)) _, historicVersionHashArg, _ := historicVersion.ArgsForCall(0) please.Expect(historicVersionHashArg).To(Equal(finalHash)) - please.Expect(fakeReleaseService.ListReleasesCallCount()).To(Equal(1)) please.Expect(fakeIssuesService.GetCallCount()).To(Equal(2)) _, orgName, repoName, n := fakeIssuesService.GetArgsForCall(0) @@ -245,7 +243,6 @@ func Test_fetch_for_tasw(t *testing.T) { historicVersion: historicVersion.Spy, issuesService: fakeIssuesService, - releasesService: fakeReleaseService, trainstatClient: fakeTrainstatClient, } @@ -259,7 +256,6 @@ func Test_fetch_for_tasw(t *testing.T) { please.Expect(historicVersion.CallCount()).To(Equal(1)) _, historicVersionHashArg, _ := historicVersion.ArgsForCall(0) please.Expect(historicVersionHashArg).To(Equal(finalHash)) - please.Expect(fakeReleaseService.ListReleasesCallCount()).To(Equal(1)) please.Expect(fakeIssuesService.GetCallCount()).To(Equal(2)) _, orgName, repoName, n := fakeIssuesService.GetArgsForCall(0) diff --git a/pkg/notes/notes_page_test.go b/pkg/notes/notes_page_test.go index 5488881d7..c0ebad3f4 100644 --- a/pkg/notes/notes_page_test.go +++ b/pkg/notes/notes_page_test.go @@ -121,22 +121,22 @@ func TestParseNotesPage(t *testing.T) { {BOSHReleaseTarballLock: cargo.BOSHReleaseTarballLock{Name: "uaa", Version: "73.4.32"}}, }, Bumps: cargo.BumpList{ - {Name: "backup-and-restore-sdk", ToVersion: "1.18.26"}, - {Name: "bpm", ToVersion: "1.1.15"}, - {Name: "capi", ToVersion: "1.84.20"}, - {Name: "cf-autoscaling", ToVersion: "241"}, - {Name: "cf-networking", ToVersion: "2.40.0"}, - {Name: "cflinuxfs3", ToVersion: "0.264.0"}, - {Name: "dotnet-core-offline-buildpack", ToVersion: "2.3.36"}, - {Name: "go-offline-buildpack", ToVersion: "1.9.37"}, - {Name: "nodejs-offline-buildpack", ToVersion: "1.7.63"}, - {Name: "php-offline-buildpack", ToVersion: "4.4.48"}, - {Name: "python-offline-buildpack", ToVersion: "1.7.47"}, - {Name: "r-offline-buildpack", ToVersion: "1.1.23"}, - {Name: "routing", ToVersion: "0.226.0"}, - {Name: "ruby-offline-buildpack", ToVersion: "1.8.48"}, - {Name: "silk", ToVersion: "2.40.0"}, - {Name: "staticfile-offline-buildpack", ToVersion: "1.5.26"}, + {Name: "backup-and-restore-sdk", To: cargo.BOSHReleaseTarballLock{Name: "backup-and-restore-sdk", Version: "1.18.26"}}, + {Name: "bpm", To: cargo.BOSHReleaseTarballLock{Name: "bpm", Version: "1.1.15"}}, + {Name: "capi", To: cargo.BOSHReleaseTarballLock{Name: "capi", Version: "1.84.20"}}, + {Name: "cf-autoscaling", To: cargo.BOSHReleaseTarballLock{Name: "cf-autoscaling", Version: "241"}}, + {Name: "cf-networking", To: cargo.BOSHReleaseTarballLock{Name: "cf-networking", Version: "2.40.0"}}, + {Name: "cflinuxfs3", To: cargo.BOSHReleaseTarballLock{Name: "cflinuxfs3", Version: "0.264.0"}}, + {Name: "dotnet-core-offline-buildpack", To: cargo.BOSHReleaseTarballLock{Name: "dotnet-core-offline-buildpack", Version: "2.3.36"}}, + {Name: "go-offline-buildpack", To: cargo.BOSHReleaseTarballLock{Name: "go-offline-buildpack", Version: "1.9.37"}}, + {Name: "nodejs-offline-buildpack", To: cargo.BOSHReleaseTarballLock{Name: "nodejs-offline-buildpack", Version: "1.7.63"}}, + {Name: "php-offline-buildpack", To: cargo.BOSHReleaseTarballLock{Name: "php-offline-buildpack", Version: "4.4.48"}}, + {Name: "python-offline-buildpack", To: cargo.BOSHReleaseTarballLock{Name: "python-offline-buildpack", Version: "1.7.47"}}, + {Name: "r-offline-buildpack", To: cargo.BOSHReleaseTarballLock{Name: "r-offline-buildpack", Version: "1.1.23"}}, + {Name: "routing", To: cargo.BOSHReleaseTarballLock{Name: "routing", Version: "0.226.0"}}, + {Name: "ruby-offline-buildpack", To: cargo.BOSHReleaseTarballLock{Name: "ruby-offline-buildpack", Version: "1.8.48"}}, + {Name: "silk", To: cargo.BOSHReleaseTarballLock{Name: "silk", Version: "2.40.0"}}, + {Name: "staticfile-offline-buildpack", To: cargo.BOSHReleaseTarballLock{Name: "staticfile-offline-buildpack", Version: "1.5.26"}}, }, } @@ -208,7 +208,7 @@ func Test_newFetchNotesData(t *testing.T) { IssueMilestone: "BLA", }, &TrainstatClient{ host: "test", - }) + }, make(map[string]any)) please.Expect(err).NotTo(HaveOccurred()) please.Expect(f.repoOwner).To(Equal("o")) please.Expect(f.repoName).To(Equal("r")) @@ -226,14 +226,14 @@ func Test_newFetchNotesData(t *testing.T) { }) t.Run("when repo is nil", func(t *testing.T) { please := NewWithT(t) - _, err := newFetchNotesData(nil, "o", "r", "k", "ri", "rf", &github.Client{}, IssuesQuery{}, &TrainstatClient{}) + _, err := newFetchNotesData(nil, "o", "r", "k", "ri", "rf", &github.Client{}, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) please.Expect(err).To(HaveOccurred()) }) t.Run("when repo is not nil", func(t *testing.T) { please := NewWithT(t) f, err := newFetchNotesData(&git.Repository{ Storer: &memory.Storage{}, - }, "o", "r", "k", "ri", "rf", &github.Client{}, IssuesQuery{}, &TrainstatClient{}) + }, "o", "r", "k", "ri", "rf", &github.Client{}, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) please.Expect(err).NotTo(HaveOccurred()) please.Expect(f.repository).NotTo(BeNil()) please.Expect(f.revisionResolver).NotTo(BeNil()) @@ -244,17 +244,15 @@ func Test_newFetchNotesData(t *testing.T) { f, err := newFetchNotesData(&git.Repository{}, "o", "r", "k", "ri", "rf", &github.Client{ Issues: &github.IssuesService{}, Repositories: &github.RepositoriesService{}, - }, IssuesQuery{}, &TrainstatClient{}) + }, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) please.Expect(err).NotTo(HaveOccurred()) please.Expect(f.issuesService).NotTo(BeNil()) - please.Expect(f.releasesService).NotTo(BeNil()) }) t.Run("when github client is nil", func(t *testing.T) { please := NewWithT(t) - f, err := newFetchNotesData(&git.Repository{}, "o", "r", "k", "ri", "rf", nil, IssuesQuery{}, &TrainstatClient{}) + f, err := newFetchNotesData(&git.Repository{}, "o", "r", "k", "ri", "rf", nil, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) please.Expect(err).NotTo(HaveOccurred()) please.Expect(f.issuesService).To(BeNil()) - please.Expect(f.releasesService).To(BeNil()) }) } From dfdd1637880a2ec3475c8c7959ffe1df5d0e86b7 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Thu, 19 Sep 2024 13:27:00 -0700 Subject: [PATCH 04/16] remove debug line --- pkg/cargo/files.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/cargo/files.go b/pkg/cargo/files.go index 7deecc01f..4d781779a 100644 --- a/pkg/cargo/files.go +++ b/pkg/cargo/files.go @@ -20,8 +20,6 @@ func InterpolateAndParseKilnfile(in io.Reader, templateVariables map[string]any) return Kilnfile{}, fmt.Errorf("unable to read Kilnfile: %w", err) } - fmt.Println(string(kilnfileYAML)) - kilnfileTemplate, err := template.New("Kilnfile"). Funcs(template.FuncMap{ "variable": variableTemplateFunction(templateVariables), From 5597bf847abb3dd0442857f78ac27d07d06f43db Mon Sep 17 00:00:00 2001 From: Ajita Jain Date: Thu, 3 Oct 2024 16:31:46 -0700 Subject: [PATCH 05/16] fix github url issue --- internal/commands/release_notes.go | 4 ---- internal/gh/uri.go | 9 ++++++++- pkg/cargo/bump.go | 6 +++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/internal/commands/release_notes.go b/internal/commands/release_notes.go index 90bf39dd1..fc81013fb 100644 --- a/internal/commands/release_notes.go +++ b/internal/commands/release_notes.go @@ -11,7 +11,6 @@ import ( "os" "path/filepath" "regexp" - "strings" "text/template" "time" @@ -282,9 +281,6 @@ func getGithubRemoteRepoOwnerAndName(repo *git.Repository) (string, string, erro } config := remote.Config() for _, u := range config.URLs { - if !strings.Contains(u, "github.com") { - continue - } remoteURL = u break } diff --git a/internal/gh/uri.go b/internal/gh/uri.go index 5c52d6b82..e2d2e570e 100644 --- a/internal/gh/uri.go +++ b/internal/gh/uri.go @@ -4,6 +4,7 @@ import ( "fmt" "net/url" "path/filepath" + "regexp" "strings" ) @@ -13,7 +14,13 @@ func RepositoryOwnerAndNameFromPath(urlStr string) (owner, repo string, err erro wrapError := func(urlStr string, err error) error { return fmt.Errorf("failed to parse owner and repo name from URI %q: %w", urlStr, err) } - urlStr = strings.TrimPrefix(urlStr, "git@github.com:") + + sshReg := regexp.MustCompile(`(?m)git@(?P.*):(?P[^/]+)/(?P.*)\.git`) + if m := sshReg.FindStringSubmatch(urlStr); m != nil { + owner = m[sshReg.SubexpIndex("owner")] + repo = m[sshReg.SubexpIndex("name")] + return owner, repo, nil + } u, err := url.Parse(urlStr) if err != nil { return "", "", wrapError(urlStr, err) diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index 16af59e33..c50e659ba 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -3,6 +3,7 @@ package cargo import ( "context" "fmt" + "log" "slices" "sort" "strings" @@ -208,7 +209,10 @@ func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLis var result []*github.RepositoryRelease ops := github.ListOptions{} - releases, _, _ := repoService.ListReleases(ctx, owner, repo, &ops) + releases, _, err := repoService.ListReleases(ctx, owner, repo, &ops) + if err != nil { + log.Println(err) + } for _, rel := range releases { rv, err := semver.NewVersion(strings.TrimPrefix(rel.GetTagName(), "v")) From 835c7e39266cb7d4a10c3776c685f259bf05d348 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Thu, 3 Oct 2024 17:46:55 -0700 Subject: [PATCH 06/16] fix: get the right credentials for bosh release repo release listing Co-Authored-By: Ajita Jain --- internal/gh/uri.go | 29 +++++++++++++++++++---------- internal/gh/uri_test.go | 23 ++++++++++++++++++++--- pkg/cargo/bump.go | 25 ++++++++++++++++++++----- pkg/cargo/bump_test.go | 2 +- 4 files changed, 60 insertions(+), 19 deletions(-) diff --git a/internal/gh/uri.go b/internal/gh/uri.go index e2d2e570e..5d558501b 100644 --- a/internal/gh/uri.go +++ b/internal/gh/uri.go @@ -10,27 +10,36 @@ import ( // RepositoryOwnerAndNameFromPath is from the github-release-source branch // once that one is merged we should that one instead of this one -func RepositoryOwnerAndNameFromPath(urlStr string) (owner, repo string, err error) { +func RepositoryOwnerAndNameFromPath(urlStr string) (string, string, error) { + _, owner, repo, err := RepositoryHostOwnerAndNameFromPath(urlStr) + return owner, repo, err +} + +func RepositoryHostOwnerAndNameFromPath(urlStr string) (string, string, string, error) { wrapError := func(urlStr string, err error) error { return fmt.Errorf("failed to parse owner and repo name from URI %q: %w", urlStr, err) } - - sshReg := regexp.MustCompile(`(?m)git@(?P.*):(?P[^/]+)/(?P.*)\.git`) - if m := sshReg.FindStringSubmatch(urlStr); m != nil { - owner = m[sshReg.SubexpIndex("owner")] - repo = m[sshReg.SubexpIndex("name")] - return owner, repo, nil + if strings.HasPrefix(urlStr, "git@") { + exp := regexp.MustCompile(`git@(?P.*):(?P[^/]+)/(?P.+)\.git`) + m := exp.FindStringSubmatch(urlStr) + if m == nil { + return "", "", "", fmt.Errorf("path missing expected parts") + } + host := m[exp.SubexpIndex("host")] + owner := m[exp.SubexpIndex("owner")] + repo := m[exp.SubexpIndex("name")] + return host, owner, repo, nil } u, err := url.Parse(urlStr) if err != nil { - return "", "", wrapError(urlStr, err) + return "", "", "", wrapError(urlStr, err) } if filepath.Ext(u.Path) == ".git" { u.Path = strings.TrimSuffix(u.Path, ".git") } owner, repo, found := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/") if !found || owner == "" || repo == "" { - return owner, repo, wrapError(urlStr, fmt.Errorf("path missing expected parts")) + return "", owner, repo, wrapError(urlStr, fmt.Errorf("path missing expected parts")) } - return owner, repo, nil + return u.Host, owner, repo, nil } diff --git a/internal/gh/uri_test.go b/internal/gh/uri_test.go index 1ee5be28e..5e42642d0 100644 --- a/internal/gh/uri_test.go +++ b/internal/gh/uri_test.go @@ -13,23 +13,29 @@ func Test_RepositoryOwnerAndNameFromPath(t *testing.T) { Name, URI, RepositoryOwner, RepositoryName, + RepositoryHost, ErrorSubstring string }{ { Name: "valid url", URI: "https://github.com/crhntr/hello-release", - RepositoryOwner: "crhntr", RepositoryName: "hello-release", + RepositoryOwner: "crhntr", RepositoryName: "hello-release", RepositoryHost: "github.com", }, { Name: "ssh url", URI: "git@github.com:crhntr/hello-release.git", - RepositoryOwner: "crhntr", RepositoryName: "hello-release", + RepositoryOwner: "crhntr", RepositoryName: "hello-release", RepositoryHost: "github.com", }, { Name: "empty ssh path", URI: "git@github.com:", ErrorSubstring: "path missing expected parts", }, + { + Name: "github enterprise", + URI: "git@example.com:x/y.git", + RepositoryOwner: "x", RepositoryName: "y", RepositoryHost: "example.com", + }, { Name: "not a valid ssh path", URI: "git@github.com:?invalid_url?", @@ -52,13 +58,24 @@ func Test_RepositoryOwnerAndNameFromPath(t *testing.T) { }, } { t.Run(tt.Name, func(t *testing.T) { - repoOwner, repoName, err := gh.RepositoryOwnerAndNameFromPath(tt.URI) + repoHost, repoOwner, repoName, err := gh.RepositoryHostOwnerAndNameFromPath(tt.URI) + if tt.ErrorSubstring != "" { + require.ErrorContains(t, err, tt.ErrorSubstring) + } else { + require.NoError(t, err) + assert.Equal(t, tt.RepositoryOwner, repoOwner) + assert.Equal(t, tt.RepositoryName, repoName) + assert.Equal(t, tt.RepositoryHost, repoHost) + } + + repoOwner, repoName, err = gh.RepositoryOwnerAndNameFromPath(tt.URI) if tt.ErrorSubstring != "" { require.ErrorContains(t, err, tt.ErrorSubstring) } else { require.NoError(t, err) assert.Equal(t, tt.RepositoryOwner, repoOwner) assert.Equal(t, tt.RepositoryName, repoName) + assert.Equal(t, tt.RepositoryHost, repoHost) } }) } diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index c50e659ba..6b6c8e84a 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -129,7 +129,7 @@ type repositoryReleaseLister interface { type ( RepositoryReleaseLister = repositoryReleaseLister - githubClientFunc func(Kilnfile, BOSHReleaseTarballLock) (repositoryReleaseLister, error) + githubClientFunc func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) ) func releaseNotes(ctx context.Context, kf Kilnfile, list BumpList, client githubClientFunc) (BumpList, error) { @@ -184,9 +184,23 @@ func releaseNotes(ctx context.Context, kf Kilnfile, list BumpList, client github } func ReleaseNotes(ctx context.Context, kf Kilnfile, list BumpList) (BumpList, error) { - return releaseNotes(ctx, kf, list, func(kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { + return releaseNotes(ctx, kf, list, listerForRelease(kf)) +} + +func listerForRelease(kf Kilnfile) func(ctx context.Context, _ Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { + return func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { + spec, err := kf.BOSHReleaseTarballSpecification(lock.Name) + if err != nil { + return nil, err + } + + _, owner, _, err := gh.RepositoryHostOwnerAndNameFromPath(spec.GitHubRepository) + if err != nil { + return nil, err + } + i := slices.IndexFunc(kf.ReleaseSources, func(config ReleaseSourceConfig) bool { - return BOSHReleaseTarballSourceID(config) == lock.RemoteSource + return config.Type == BOSHReleaseTarballSourceTypeGithub && config.Org == owner }) if i < 0 { return nil, fmt.Errorf("release source with id %s not found", lock.RemoteSource) @@ -197,7 +211,7 @@ func ReleaseNotes(ctx context.Context, kf Kilnfile, list BumpList) (BumpList, er return nil, err } return client.Repositories, err - }) + } } func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLister, repository string, from, to *semver.Version) []*github.RepositoryRelease { @@ -226,8 +240,9 @@ func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLis } func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, client githubClientFunc) Bump { - lister, err := client(kf, bump.To) + lister, err := client(ctx, kf, bump.To) if err != nil { + log.Println(err) return bump } spec, err := kf.BOSHReleaseTarballSpecification(bump.Name) diff --git a/pkg/cargo/bump_test.go b/pkg/cargo/bump_test.go index edafaba80..e1ea2d555 100644 --- a/pkg/cargo/bump_test.go +++ b/pkg/cargo/bump_test.go @@ -164,7 +164,7 @@ func TestInternal_addReleaseNotes(t *testing.T) { To: BOSHReleaseTarballLock{Version: "10"}, From: BOSHReleaseTarballLock{Version: "9"}, }, - }, func(kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { + }, func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { return releaseLister, nil }) please.Expect(err).NotTo(HaveOccurred()) From 852058ec689af81fc424a52515a681d77b42a042 Mon Sep 17 00:00:00 2001 From: Ajita Jain Date: Fri, 4 Oct 2024 15:31:39 -0700 Subject: [PATCH 07/16] code refactor + change regex for github url validation Co-Authored-By: Joe Eltgroth Co-Authored-By: Christopher Hunter --- internal/acceptance/README.md | 3 +++ internal/commands/update_release.go | 2 -- internal/commands/update_stemcell.go | 1 - internal/gh/uri.go | 4 ++-- pkg/cargo/kilnfile.go | 3 ++- pkg/planitest/internal/config.go | 1 - pkg/planitest/internal/om_runner.go | 2 -- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/internal/acceptance/README.md b/internal/acceptance/README.md index 7317db9f0..243de7716 100644 --- a/internal/acceptance/README.md +++ b/internal/acceptance/README.md @@ -25,8 +25,11 @@ go run github.com/onsi/ginkgo/ginkgo ### Workflows These are written in Go and use [godog](https://github.com/cucumber/godog) (a Cucumber test framework). +> PS: Export GITHUB_TOKEN as an env var before running the acceptance tests + ```bash # from anywhere in the repo you can run: +export GITHUB_TOKEN="$(gh auth token)" go test -v --tags acceptance --timeout=1h github.com/pivotal-cf/kiln/internal/acceptance/workflows ``` diff --git a/internal/commands/update_release.go b/internal/commands/update_release.go index 003890f1a..d17a8445e 100644 --- a/internal/commands/update_release.go +++ b/internal/commands/update_release.go @@ -78,7 +78,6 @@ func (u UpdateRelease) Execute(args []string) error { StemcellOS: kilnfileLock.Stemcell.OS, GitHubRepository: releaseSpec.GitHubRepository, }, false) - if err != nil { if component.IsErrNotFound(err) { return fmt.Errorf("error finding the release: %w", err) @@ -99,7 +98,6 @@ func (u UpdateRelease) Execute(args []string) error { StemcellVersion: kilnfileLock.Stemcell.Version, GitHubRepository: releaseSpec.GitHubRepository, }) - if err != nil { if component.IsErrNotFound(err) { return fmt.Errorf("error finding the release: %w", err) diff --git a/internal/commands/update_stemcell.go b/internal/commands/update_stemcell.go index 128ec23f1..36992c79f 100644 --- a/internal/commands/update_stemcell.go +++ b/internal/commands/update_stemcell.go @@ -48,7 +48,6 @@ func (update UpdateStemcell) Execute(args []string) error { kilnStemcellVersion := kilnfile.Stemcell.Version releaseVersionConstraint, err = semver.NewConstraint(kilnStemcellVersion) - if err != nil { return fmt.Errorf("invalid stemcell constraint in kilnfile: %w", err) } diff --git a/internal/gh/uri.go b/internal/gh/uri.go index 5d558501b..c0a86b97c 100644 --- a/internal/gh/uri.go +++ b/internal/gh/uri.go @@ -20,14 +20,14 @@ func RepositoryHostOwnerAndNameFromPath(urlStr string) (string, string, string, return fmt.Errorf("failed to parse owner and repo name from URI %q: %w", urlStr, err) } if strings.HasPrefix(urlStr, "git@") { - exp := regexp.MustCompile(`git@(?P.*):(?P[^/]+)/(?P.+)\.git`) + exp := regexp.MustCompile(`git@(?P.+):(?P[^/]+)/(?P.+)(\.git)?`) m := exp.FindStringSubmatch(urlStr) if m == nil { return "", "", "", fmt.Errorf("path missing expected parts") } host := m[exp.SubexpIndex("host")] owner := m[exp.SubexpIndex("owner")] - repo := m[exp.SubexpIndex("name")] + repo := strings.TrimSuffix(m[exp.SubexpIndex("name")], ".git") return host, owner, repo, nil } u, err := url.Parse(urlStr) diff --git a/pkg/cargo/kilnfile.go b/pkg/cargo/kilnfile.go index dc9212a72..c3d6ad3b6 100644 --- a/pkg/cargo/kilnfile.go +++ b/pkg/cargo/kilnfile.go @@ -4,9 +4,10 @@ import ( "context" "errors" "fmt" + "strings" + "github.com/google/go-github/v50/github" "golang.org/x/oauth2" - "strings" "gopkg.in/yaml.v3" diff --git a/pkg/planitest/internal/config.go b/pkg/planitest/internal/config.go index 7e5b40463..4c3bb5cd6 100644 --- a/pkg/planitest/internal/config.go +++ b/pkg/planitest/internal/config.go @@ -43,7 +43,6 @@ func MergeAdditionalProductProperties(configFile io.Reader, additionalProperties var inputConfig ProductConfiguration err = yaml.Unmarshal(yamlInput, &inputConfig) - if err != nil { return nil, fmt.Errorf("could not parse config file: %s", err) } diff --git a/pkg/planitest/internal/om_runner.go b/pkg/planitest/internal/om_runner.go index 40fc80249..906bcb8be 100644 --- a/pkg/planitest/internal/om_runner.go +++ b/pkg/planitest/internal/om_runner.go @@ -89,7 +89,6 @@ func (o OMRunner) ResetAndConfigure(productName string, productVersion string, c "--product-name", productName, "--product-version", productVersion, ) - if err != nil { return fmt.Errorf("Unable to stage product %q, version %q: %s: %s", productName, productVersion, err, errOutput) @@ -114,7 +113,6 @@ func (o OMRunner) ResetAndConfigure(productName string, productVersion string, c "configure-product", "--config", configFile.Name(), ) - if err != nil { return fmt.Errorf("Unable to configure product %q: %s: %s", productName, err, errOutput) } From af77e11d9114632dd32b31687a7768a13693b3ab Mon Sep 17 00:00:00 2001 From: Ajita Jain Date: Mon, 7 Oct 2024 21:03:30 -0700 Subject: [PATCH 08/16] Ignore bosh release with no Github repo for release-notes cmd & update trainstat url --- pkg/cargo/bump.go | 12 +++++++++--- pkg/notes/notes_data.go | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index 6b6c8e84a..b2056257e 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -240,13 +240,19 @@ func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLis } func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, client githubClientFunc) Bump { - lister, err := client(ctx, kf, bump.To) + spec, err := kf.BOSHReleaseTarballSpecification(bump.Name) if err != nil { - log.Println(err) return bump } - spec, err := kf.BOSHReleaseTarballSpecification(bump.Name) + + // Ignores release notes for Bosh releases with empty Github repository + if spec.GitHubRepository == "" { + return bump + } + + lister, err := client(ctx, kf, bump.To) if err != nil { + log.Println(err) return bump } diff --git a/pkg/notes/notes_data.go b/pkg/notes/notes_data.go index b44b5b868..277188558 100644 --- a/pkg/notes/notes_data.go +++ b/pkg/notes/notes_data.go @@ -102,7 +102,7 @@ type IssuesQuery struct { } type TrainstatQuery struct { - TrainstatURL string `long:"trainstat-url" short:"tu" description:"trainstat url to fetch the release notes for component bumps" default:"https://trainstat.sc2-04-pcf1-apps.oc.vmware.com"` + TrainstatURL string `long:"trainstat-url" short:"tu" description:"trainstat url to fetch the release notes for component bumps" default:"https://tas-trainstat.eng.tanzu.broadcom.com"` } func TrainstatURL() string { From 5830ed32494a8c44229231d84a40d5cae8adfd12 Mon Sep 17 00:00:00 2001 From: Ajita Jain Date: Mon, 14 Oct 2024 11:12:47 -0700 Subject: [PATCH 09/16] fix: cannot read variable file Co-authored-by: Nick Rohn --- internal/baking/template_variables_service.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/baking/template_variables_service.go b/internal/baking/template_variables_service.go index 34023480e..491ccba5d 100644 --- a/internal/baking/template_variables_service.go +++ b/internal/baking/template_variables_service.go @@ -2,6 +2,7 @@ package baking import ( "fmt" + "os" "strings" "github.com/go-git/go-billy/v5" @@ -21,7 +22,7 @@ func (s TemplateVariablesService) FromPathsAndPairs(paths []string, pairs []stri variables := map[string]any{} for _, path := range paths { - err := parseVariablesFromFile(s.filesystem, path, variables) + err := parseVariablesFromFile(path, variables) if err != nil { return nil, err } @@ -40,8 +41,8 @@ func (s TemplateVariablesService) FromPathsAndPairs(paths []string, pairs []stri return variables, nil } -func parseVariablesFromFile(fs billy.Basic, path string, variables map[string]any) error { - file, err := fs.Open(path) +func parseVariablesFromFile(path string, variables map[string]any) error { + file, err := os.Open(path) if err != nil { return fmt.Errorf("unable to open file %q: %w", path, err) } From 406c7e9a26e1a779dd987a5ea4c0881ad45366d6 Mon Sep 17 00:00:00 2001 From: Ajita Jain Date: Mon, 14 Oct 2024 13:21:19 -0700 Subject: [PATCH 10/16] rename variables for code readability use "github_host" env var to fetch release notes for bosh releases bump Co-authored-by: Nick Rohn --- README.md | 1 + internal/commands/release_notes.go | 38 ++++++++++++++----------- internal/commands/release_notes_test.go | 2 +- pkg/cargo/bump.go | 23 ++++++++------- pkg/notes/notes_data.go | 2 +- 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index f21e6d22e..443083cd1 100644 --- a/README.md +++ b/README.md @@ -658,6 +658,7 @@ stemcell_criteria: - type: github id: optional-unique-name-defaults-to-github-org-name org: the-github-org + endpoint: $(variable "github_host") github_token: $(variable "github_token") ``` diff --git a/internal/commands/release_notes.go b/internal/commands/release_notes.go index fc81013fb..679abeece 100644 --- a/internal/commands/release_notes.go +++ b/internal/commands/release_notes.go @@ -28,15 +28,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"` - 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"` + ReleaseDate string `long:"release-date" short:"d" description:"release date of the tile"` + TemplateName string `long:"template" short:"t" description:"path to template"` + GithubIssuesServiceToken string `long:"github-token" short:"g" description:"auth token for fetching issues and milestones with labels" env:"GITHUB_TOKEN"` + GithubHost string `long:"github-host" description:"set this when you are using GitHub enterprise to fetch issues, milestones or notes for bosh releases" 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 } @@ -82,10 +82,16 @@ func (r ReleaseNotes) Execute(args []string) error { 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) + if varValue, ok := templateVariables["github_token"]; !ok && r.Options.GithubIssuesServiceToken != "" { + templateVariables["github_token"] = r.Options.GithubIssuesServiceToken + } else if ok && r.Options.GithubIssuesServiceToken == "" { + r.Options.GithubIssuesServiceToken = varValue.(string) + } + + if varValue, ok := templateVariables["github_host"]; !ok && r.Options.GithubHost != "" { + templateVariables["github_host"] = r.Options.GithubHost + } else if ok && r.Options.GithubHost == "" { + r.Options.GithubHost = varValue.(string) } ctx := context.Background() @@ -100,8 +106,8 @@ func (r ReleaseNotes) Execute(args []string) error { } var client *github.Client - if r.Options.GithubToken != "" { - client, err = gh.Client(ctx, r.Options.GithubHost, r.Options.GithubToken) + if r.Options.GithubIssuesServiceToken != "" { + client, err = gh.Client(ctx, r.Options.GithubHost, r.Options.GithubIssuesServiceToken) if err != nil { return fmt.Errorf("failed to setup github client: %w", err) } @@ -237,7 +243,7 @@ func (r ReleaseNotes) checkInputs(nonFlagArgs []string) error { } } - if r.Options.GithubToken == "" && + if r.Options.GithubIssuesServiceToken == "" && (r.Options.IssueMilestone != "" || len(r.Options.IssueIDs) > 0 || len(r.Options.IssueLabels) > 0) { diff --git a/internal/commands/release_notes_test.go b/internal/commands/release_notes_test.go index 8af9f6bbf..948f898c3 100644 --- a/internal/commands/release_notes_test.go +++ b/internal/commands/release_notes_test.go @@ -104,7 +104,7 @@ func TestReleaseNotes_Execute(t *testing.T) { }, } - rn.Options.GithubToken = "secret" + rn.Options.GithubIssuesServiceToken = "secret" err := rn.Execute([]string{ "--kilnfile=tile/Kilnfile", diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index b2056257e..e76c6977f 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -129,10 +129,11 @@ type repositoryReleaseLister interface { type ( RepositoryReleaseLister = repositoryReleaseLister - githubClientFunc func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) + githubReleasesClient func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) ) -func releaseNotes(ctx context.Context, kf Kilnfile, list BumpList, client githubClientFunc) (BumpList, error) { +// Fetch release notes for each of the release bumps in the Kilnfile +func releaseNotes(ctx context.Context, kf Kilnfile, list BumpList, getGithubRepositoryClientForRelease githubReleasesClient) (BumpList, error) { const workerCount = 10 type fetchReleaseNotesForBump struct { @@ -152,7 +153,7 @@ func releaseNotes(ctx context.Context, kf Kilnfile, list BumpList, client github go func() { defer wg.Done() for j := range in { - j.bump = fetchReleasesForBump(ctx, kf, j.bump, client) + j.bump = fetchReleasesForBump(ctx, kf, j.bump, getGithubRepositoryClientForRelease) results <- j } }() @@ -184,10 +185,10 @@ func releaseNotes(ctx context.Context, kf Kilnfile, list BumpList, client github } func ReleaseNotes(ctx context.Context, kf Kilnfile, list BumpList) (BumpList, error) { - return releaseNotes(ctx, kf, list, listerForRelease(kf)) + return releaseNotes(ctx, kf, list, getGithubRepositoryClientForRelease(kf)) } -func listerForRelease(kf Kilnfile) func(ctx context.Context, _ Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { +func getGithubRepositoryClientForRelease(kf Kilnfile) func(ctx context.Context, _ Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { return func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { spec, err := kf.BOSHReleaseTarballSpecification(lock.Name) if err != nil { @@ -214,7 +215,8 @@ func listerForRelease(kf Kilnfile) func(ctx context.Context, _ Kilnfile, lock BO } } -func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLister, repository string, from, to *semver.Version) []*github.RepositoryRelease { +// Fetch all the releases from GitHub repository between from and to versions +func fetchReleasesFromRepo(ctx context.Context, releaseLister RepositoryReleaseLister, repository string, from, to *semver.Version) []*github.RepositoryRelease { owner, repo, err := gh.RepositoryOwnerAndNameFromPath(repository) if err != nil { return nil @@ -223,7 +225,7 @@ func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLis var result []*github.RepositoryRelease ops := github.ListOptions{} - releases, _, err := repoService.ListReleases(ctx, owner, repo, &ops) + releases, _, err := releaseLister.ListReleases(ctx, owner, repo, &ops) if err != nil { log.Println(err) } @@ -239,7 +241,7 @@ func fetchReleasesFromRepo(ctx context.Context, repoService RepositoryReleaseLis return result } -func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, client githubClientFunc) Bump { +func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, getGithubRepositoryClientForRelease githubReleasesClient) Bump { spec, err := kf.BOSHReleaseTarballSpecification(bump.Name) if err != nil { return bump @@ -250,7 +252,8 @@ func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, client gi return bump } - lister, err := client(ctx, kf, bump.To) + // Fetch the GitHub releases client for a single release (bump) in the Kilnfile + releaseLister, err := getGithubRepositoryClientForRelease(ctx, kf, bump.To) if err != nil { log.Println(err) return bump @@ -262,7 +265,7 @@ func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, client gi } if spec.GitHubRepository != "" { - releases := fetchReleasesFromRepo(ctx, lister, spec.GitHubRepository, from, to) + releases := fetchReleasesFromRepo(ctx, releaseLister, spec.GitHubRepository, from, to) bump.Releases = append(bump.Releases, releases...) } diff --git a/pkg/notes/notes_data.go b/pkg/notes/notes_data.go index 277188558..906d091d7 100644 --- a/pkg/notes/notes_data.go +++ b/pkg/notes/notes_data.go @@ -357,7 +357,7 @@ type issuesService interface { // manual test to ensure it continues to behave as expected during refactors. // // The function can be tested by generating release notes for a tile with issue ids and a milestone set. The happy path -// test for Execute does not set GithubToken intentionally so this code is not triggered and Execute does not actually +// test for Execute does not set GithubIssuesServiceToken intentionally so this code is not triggered and Execute does not actually // reach out to GitHub. func (r fetchNotesData) fetchIssuesAndReleaseNotes(ctx context.Context, finalKF, wtKF cargo.Kilnfile, bumpList cargo.BumpList, issuesQuery IssuesQuery) ([]*github.Issue, cargo.BumpList, error) { if r.issuesService == nil { From 6f3b66ecc58ea36a7de1a6dea4d259fe1da5c601 Mon Sep 17 00:00:00 2001 From: Nick Rohn Date: Wed, 16 Oct 2024 14:14:40 -0700 Subject: [PATCH 11/16] wip: ideas for refactoring to create github client per release --- pkg/cargo/bump.go | 6 ++++-- pkg/cargo/kilnfile.go | 23 ++++++++++++----------- pkg/notes/notes_data.go | 28 ---------------------------- 3 files changed, 16 insertions(+), 41 deletions(-) diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index e76c6977f..aff362091 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -189,13 +189,14 @@ func ReleaseNotes(ctx context.Context, kf Kilnfile, list BumpList) (BumpList, er } func getGithubRepositoryClientForRelease(kf Kilnfile) func(ctx context.Context, _ Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { + // todo: []repositoryReleaseLister return func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { spec, err := kf.BOSHReleaseTarballSpecification(lock.Name) if err != nil { return nil, err } - _, owner, _, err := gh.RepositoryHostOwnerAndNameFromPath(spec.GitHubRepository) + host, owner, _, err := gh.RepositoryHostOwnerAndNameFromPath(spec.GitHubRepository) if err != nil { return nil, err } @@ -207,7 +208,8 @@ func getGithubRepositoryClientForRelease(kf Kilnfile) func(ctx context.Context, return nil, fmt.Errorf("release source with id %s not found", lock.RemoteSource) } source := kf.ReleaseSources[i] - client, err := source.GitHubClient(ctx) + + client, err := source.GitHubClient(ctx, host) if err != nil { return nil, err } diff --git a/pkg/cargo/kilnfile.go b/pkg/cargo/kilnfile.go index c3d6ad3b6..fea2d37fd 100644 --- a/pkg/cargo/kilnfile.go +++ b/pkg/cargo/kilnfile.go @@ -4,11 +4,10 @@ import ( "context" "errors" "fmt" + "github.com/pivotal-cf/kiln/internal/gh" "strings" "github.com/google/go-github/v50/github" - "golang.org/x/oauth2" - "gopkg.in/yaml.v3" "github.com/Masterminds/semver/v3" @@ -173,18 +172,20 @@ type ReleaseSourceConfig struct { Password string `yaml:"password,omitempty"` } -func (c ReleaseSourceConfig) GitHubClient(ctx context.Context) (*github.Client, error) { +func (c ReleaseSourceConfig) GitHubClient(ctx context.Context, githubHost string) (*github.Client, error) { if c.GithubToken == "" { return nil, errors.New("no token passed for github release source") } - tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: c.GithubToken}) - tokenClient := oauth2.NewClient(ctx, tokenSource) - var githubClient *github.Client - if c.Endpoint != "" { - return github.NewEnterpriseClient(c.Endpoint, c.Endpoint, tokenClient) - } - githubClient = github.NewClient(tokenClient) - return githubClient, nil + //tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: c.GithubToken}) + //tokenClient := oauth2.NewClient(ctx, tokenSource) + //var githubClient *github.Client + //gh.Client(ctx) todo use gh.Client not github.NewClient or github.NewEnterpriseClient + return gh.Client(ctx, host, c.GithubToken, c.GithubEnterpriseToken) + //if strings.HasSuffix(githubHost, "broadcom.net") { + // return github.NewEnterpriseClient(c.Endpoint, c.Endpoint, tokenClient) + //} + //githubClient = github.NewClient(tokenClient) + //return githubClient, nil } // BOSHReleaseTarballLock represents an exact build of a bosh release diff --git a/pkg/notes/notes_data.go b/pkg/notes/notes_data.go index 906d091d7..f5fa8f05c 100644 --- a/pkg/notes/notes_data.go +++ b/pkg/notes/notes_data.go @@ -135,34 +135,6 @@ func FetchData(ctx context.Context, repo *git.Repository, client *github.Client, return f.fetch(ctx) } -// FetchDataWithoutRepo can be used to generate release notes from tile metadata -func FetchDataWithoutRepo(ctx context.Context, client *github.Client, tileRepoOwner, tileRepoName string, kilnfile cargo.Kilnfile, kilnfileLockInitial, kilnfileLockFinal cargo.KilnfileLock, issuesQuery IssuesQuery) (Data, error) { - r := fetchNotesData{ - repoOwner: tileRepoOwner, - repoName: tileRepoName, - issuesQuery: issuesQuery, - issuesService: client.Issues, - } - data := Data{ - Bumps: cargo.CalculateBumps(kilnfileLockFinal.Releases, kilnfileLockInitial.Releases), - Stemcell: kilnfileLockFinal.Stemcell, - } - var err error - data.Issues, data.Bumps, err = r.fetchIssuesAndReleaseNotes(ctx, kilnfile, kilnfile, data.Bumps, issuesQuery) - if err != nil { - return Data{}, err - } - - for _, c := range kilnfileLockFinal.Releases { - data.Components = append(data.Components, BOSHReleaseData{ - BOSHReleaseTarballLock: c, - Releases: data.Bumps.ForLock(c).Releases, - }) - } - - return data, nil -} - func newFetchNotesData(repo *git.Repository, tileRepoOwner string, tileRepoName string, kilnfilePath string, initialRevision string, finalRevision string, client *github.Client, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher, variables map[string]any) (fetchNotesData, error) { if repo == nil { return fetchNotesData{}, errors.New("git repository required to generate release notes") From 5688b1e8b75572da701664049db1491640029250 Mon Sep 17 00:00:00 2001 From: Ajita Jain Date: Wed, 16 Oct 2024 16:14:38 -0700 Subject: [PATCH 12/16] Remove github_host var, rename github_token to github_access_token, match the release sources to the release by org --- .../workflows/create-debugging-artifact.yml | 1 + .github/workflows/release.yml | 4 ++ .github/workflows/test.yml | 1 + .../generating_release_notes.feature | 2 +- .../workflows/scenario/step_funcs_github.go | 2 +- .../workflows/testdata/tiles/v1/Kilnfile | 2 +- .../workflows/testdata/tiles/v2/Kilnfile | 2 +- internal/commands/release_notes.go | 71 +++++++++---------- internal/commands/release_notes_test.go | 47 +++++------- internal/component/github_release_source.go | 2 +- internal/gh/client.go | 26 +++++-- internal/gh/client_test.go | 16 +++-- pkg/cargo/bump.go | 57 +++++++++------ pkg/cargo/bump_test.go | 6 +- pkg/cargo/kilnfile.go | 19 ----- pkg/notes/notes_data.go | 11 +-- pkg/notes/notes_page_test.go | 10 +-- 17 files changed, 146 insertions(+), 133 deletions(-) diff --git a/.github/workflows/create-debugging-artifact.yml b/.github/workflows/create-debugging-artifact.yml index ca3c0c47d..f95e553d6 100644 --- a/.github/workflows/create-debugging-artifact.yml +++ b/.github/workflows/create-debugging-artifact.yml @@ -41,6 +41,7 @@ jobs: RELEEN_GITHUB_TOKEN: ${{ secrets.RELEEN_GITHUB_TOKEN }} run: | export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" + export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" go test ./... - name: Acceptance Tests diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 434a55b54..e084ff404 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,6 +38,7 @@ jobs: RELEEN_GITHUB_TOKEN: ${{ secrets.RELEEN_GITHUB_TOKEN }} run: | export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" + export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" go test --covermode=atomic --coverprofile=kiln-${{github.sha}}-unit-test-code-coverage.out ./... - name: Archive Unit Test Code Coverage Output @@ -53,6 +54,7 @@ jobs: run: | set -euo pipefail export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" + export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" set -x go test -v --timeout 24h --tags acceptance github.com/pivotal-cf/kiln/internal/acceptance/workflows @@ -80,3 +82,5 @@ jobs: args: release --rm-dist env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fe685da5a..3fde51512 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,6 +51,7 @@ jobs: run: | set -euo pipefail export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" + export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" set -x go test -v --timeout 15m --tags acceptance github.com/pivotal-cf/kiln/internal/acceptance/workflows diff --git a/internal/acceptance/workflows/generating_release_notes.feature b/internal/acceptance/workflows/generating_release_notes.feature index 52f265881..798b3e436 100644 --- a/internal/acceptance/workflows/generating_release_notes.feature +++ b/internal/acceptance/workflows/generating_release_notes.feature @@ -10,7 +10,7 @@ Feature: As a robot, I want to generate release notes | --name=hello-release | | --version=v0.1.5 | | --without-download | - | --variable=github_token="${GITHUB_TOKEN}" | + | --variable=github_access_token="${GITHUB_TOKEN}" | And I write file "version" | 0.1.4 | And I execute git add Kilnfile.lock version diff --git a/internal/acceptance/workflows/scenario/step_funcs_github.go b/internal/acceptance/workflows/scenario/step_funcs_github.go index e68dae33a..6d2b9cdcf 100644 --- a/internal/acceptance/workflows/scenario/step_funcs_github.go +++ b/internal/acceptance/workflows/scenario/step_funcs_github.go @@ -13,7 +13,7 @@ func githubRepoHasReleaseWithTag(ctx context.Context, repoOrg, repoName, tag str if err != nil { return err } - ghAPI, err := gh.Client(ctx, "", accessToken) + ghAPI, err := gh.Client(ctx, "", accessToken, accessToken) if err != nil { return fmt.Errorf("failed to setup github client: %w", err) } diff --git a/internal/acceptance/workflows/testdata/tiles/v1/Kilnfile b/internal/acceptance/workflows/testdata/tiles/v1/Kilnfile index f606a5408..701818e74 100644 --- a/internal/acceptance/workflows/testdata/tiles/v1/Kilnfile +++ b/internal/acceptance/workflows/testdata/tiles/v1/Kilnfile @@ -3,7 +3,7 @@ slug: crhntr-hello release_sources: - type: github org: crhntr - github_token: $(variable "github_token") + github_token: $(variable "github_access_token") - type: bosh.io releases: - name: bpm diff --git a/internal/acceptance/workflows/testdata/tiles/v2/Kilnfile b/internal/acceptance/workflows/testdata/tiles/v2/Kilnfile index bfe462310..381087e38 100644 --- a/internal/acceptance/workflows/testdata/tiles/v2/Kilnfile +++ b/internal/acceptance/workflows/testdata/tiles/v2/Kilnfile @@ -3,7 +3,7 @@ slug: crhntr-hello release_sources: - type: github org: crhntr - github_token: $(variable "github_token") + github_token: $(variable "github_access_token") - type: bosh.io releases: - name: bpm diff --git a/internal/commands/release_notes.go b/internal/commands/release_notes.go index 679abeece..3e13a8eeb 100644 --- a/internal/commands/release_notes.go +++ b/internal/commands/release_notes.go @@ -28,15 +28,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"` - GithubIssuesServiceToken string `long:"github-token" short:"g" description:"auth token for fetching issues and milestones with labels" env:"GITHUB_TOKEN"` - GithubHost string `long:"github-host" description:"set this when you are using GitHub enterprise to fetch issues, milestones or notes for bosh releases" 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"` + ReleaseDate string `long:"release-date" short:"d" description:"release date of the tile"` + TemplateName string `long:"template" short:"t" description:"path to template"` + GithubAccessToken string `long:"github_access_token" short:"g" description:"auth token for github.com" env:"GITHUB_ACCESS_TOKEN"` + GithubEnterpriseAccessToken string `long:"github_enterprise_access_token" short:"ge" description:"auth token for github enterprise" env:"GITHUB_ENTERPRISE_ACCESS_TOKEN"` + 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 } @@ -49,10 +49,10 @@ type ReleaseNotes struct { fetchNotesData FetchNotesData variablesService baking.TemplateVariablesService - repoOwner, repoName string + repoHost, 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, variables map[string]any) (notes.Data, error) +type FetchNotesData func(ctx context.Context, repo *git.Repository, client *github.Client, tileRepoHost, 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{ @@ -82,16 +82,16 @@ func (r ReleaseNotes) Execute(args []string) error { if err != nil { return fmt.Errorf("failed to parse template variables: %s", err) } - if varValue, ok := templateVariables["github_token"]; !ok && r.Options.GithubIssuesServiceToken != "" { - templateVariables["github_token"] = r.Options.GithubIssuesServiceToken - } else if ok && r.Options.GithubIssuesServiceToken == "" { - r.Options.GithubIssuesServiceToken = varValue.(string) + if varValue, ok := templateVariables["github_access_token"]; !ok && r.Options.GithubAccessToken != "" { + templateVariables["github_access_token"] = r.Options.GithubAccessToken + } else if ok && r.Options.GithubAccessToken == "" { + r.Options.GithubAccessToken = varValue.(string) } - if varValue, ok := templateVariables["github_host"]; !ok && r.Options.GithubHost != "" { - templateVariables["github_host"] = r.Options.GithubHost - } else if ok && r.Options.GithubHost == "" { - r.Options.GithubHost = varValue.(string) + if varValue, ok := templateVariables["github_enterprise_access_token"]; !ok && r.Options.GithubAccessToken != "" { + templateVariables["github_enterprise_access_token"] = r.Options.GithubEnterpriseAccessToken + } else if ok && r.Options.GithubEnterpriseAccessToken == "" { + r.Options.GithubEnterpriseAccessToken = varValue.(string) } ctx := context.Background() @@ -106,18 +106,17 @@ func (r ReleaseNotes) Execute(args []string) error { } var client *github.Client - if r.Options.GithubIssuesServiceToken != "" { - client, err = gh.Client(ctx, r.Options.GithubHost, r.Options.GithubIssuesServiceToken) - if err != nil { - return fmt.Errorf("failed to setup github client: %w", err) - } + + client, err = gh.Client(ctx, r.repoHost, r.Options.GithubAccessToken, r.Options.GithubEnterpriseAccessToken) + if err != nil { + return fmt.Errorf("failed to setup github client: %w", err) } trainstatClient := notes.NewTrainstatClient(r.Options.TrainstatQuery.TrainstatURL) _ = notes.FetchData // fetchNotesData is github.com/pivotal/kiln/internal/notes.FetchData data, err := r.fetchNotesData(ctx, - r.repository, client, r.repoOwner, r.repoName, + r.repository, client, r.repoHost, r.repoOwner, r.repoName, r.Options.Kilnfile, nonFlagArgs[0], nonFlagArgs[1], r.Options.IssuesQuery, @@ -196,12 +195,13 @@ func (r *ReleaseNotes) initRepo() error { return fmt.Errorf("release-notes must be run from the root of the repository (use --kilnfile flag to specify which tile to build)") } - repoOwner, repoName, err := getGithubRemoteRepoOwnerAndName(repo) + repoHost, repoOwner, repoName, err := getGithubRemoteHostRepoOwnerAndName(repo) if err != nil { return err } r.repository = repo + r.repoHost = repoHost r.repoName = repoName r.repoOwner = repoOwner @@ -243,11 +243,8 @@ func (r ReleaseNotes) checkInputs(nonFlagArgs []string) error { } } - if r.Options.GithubIssuesServiceToken == "" && - (r.Options.IssueMilestone != "" || - len(r.Options.IssueIDs) > 0 || - len(r.Options.IssueLabels) > 0) { - return errors.New("github-token (env: GITHUB_TOKEN) must be set to interact with the github api") + if r.Options.GithubEnterpriseAccessToken == "" && r.Options.GithubAccessToken == "" { + return errors.New("github_access_token(env: GITHUB_ACCESS_TOKEN) and/or github_enterprise_access_token(env: GITHUB_ENTERPRISE_ACCESS_TOKEN) must be set to interact with the github api") } if r.Options.DocsFile != "" { @@ -279,11 +276,11 @@ func (r ReleaseNotes) parseReleaseDate() (time.Time, error) { return releaseDate, nil } -func getGithubRemoteRepoOwnerAndName(repo *git.Repository) (string, string, error) { +func getGithubRemoteHostRepoOwnerAndName(repo *git.Repository) (string, string, string, error) { var remoteURL string remote, err := repo.Remote("origin") if err != nil { - return "", "", err + return "", "", "", err } config := remote.Config() for _, u := range config.URLs { @@ -291,13 +288,13 @@ func getGithubRemoteRepoOwnerAndName(repo *git.Repository) (string, string, erro break } if remoteURL == "" { - return "", "", fmt.Errorf("remote github URL not found for repo") + return "", "", "", fmt.Errorf("remote github URL not found for repo") } - repoOwner, repoName, err := gh.RepositoryOwnerAndNameFromPath(remoteURL) + repoHost, repoOwner, repoName, err := gh.RepositoryHostOwnerAndNameFromPath(remoteURL) if err != nil { - return "", "", err + return "", "", "", err } - return repoOwner, repoName, nil + return repoHost, repoOwner, repoName, nil } diff --git a/internal/commands/release_notes_test.go b/internal/commands/release_notes_test.go index 948f898c3..91bfbfe75 100644 --- a/internal/commands/release_notes_test.go +++ b/internal/commands/release_notes_test.go @@ -57,7 +57,7 @@ func TestReleaseNotes_Execute(t *testing.T) { } var ( - tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision string + tileRepoHost, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision string issuesQuery notes.IssuesQuery repository *git.Repository @@ -69,12 +69,13 @@ func TestReleaseNotes_Execute(t *testing.T) { rn := ReleaseNotes{ Writer: &out, repository: nonNilRepo, + repoHost: "github.com", 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, __ map[string]any) (notes.Data, error) { + fetchNotesData: func(c context.Context, repo *git.Repository, ghc *github.Client, trh, 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 + tileRepoHost, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision = trh, tro, trn, kfp, ir, fr issuesQuery = iq return notes.Data{ ReleaseDate: mustParseTime(time.Parse(releaseDateFormat, "2021-11-04")), @@ -104,12 +105,12 @@ func TestReleaseNotes_Execute(t *testing.T) { }, } - rn.Options.GithubIssuesServiceToken = "secret" + rn.Options.GithubAccessToken = "secret" err := rn.Execute([]string{ "--kilnfile=tile/Kilnfile", "--release-date=2021-11-04", - "--github-token=lemon", + "--github_access_token=lemon", "--github-issue-milestone=smoothie", "--github-issue-label=tropical", "--github-issue=54000", @@ -124,6 +125,7 @@ func TestReleaseNotes_Execute(t *testing.T) { please.Expect(repository).NotTo(BeNil()) please.Expect(client).NotTo(BeNil()) + please.Expect(tileRepoHost).To(Equal("github.com")) please.Expect(tileRepoOwner).To(Equal("bunch")) please.Expect(tileRepoName).To(Equal("banana")) please.Expect(kilnfilePath).To(Equal("tile/Kilnfile")) @@ -188,6 +190,7 @@ func TestReleaseNotes_checkInputs(t *testing.T) { rn := ReleaseNotes{} rn.Options.ReleaseDate = `some-date` + rn.Options.GithubAccessToken = "test-token" err := rn.checkInputs([]string{"a", "b"}) please.Expect(err).To(MatchError(ContainSubstring("cannot parse"))) }) @@ -197,27 +200,9 @@ func TestReleaseNotes_checkInputs(t *testing.T) { please := NewWithT(t) rn := ReleaseNotes{} - rn.Options.IssueMilestone = "s" err := rn.checkInputs([]string{"a", "b"}) - please.Expect(err).To(MatchError(ContainSubstring("github-token"))) - }) - - t.Run("ids", func(t *testing.T) { - please := NewWithT(t) - - rn := ReleaseNotes{} - rn.Options.IssueIDs = []string{"s"} - err := rn.checkInputs([]string{"a", "b"}) - please.Expect(err).To(MatchError(ContainSubstring("github-token"))) - }) - - t.Run("labels", func(t *testing.T) { - please := NewWithT(t) - - rn := ReleaseNotes{} - rn.Options.IssueLabels = []string{"s"} - err := rn.checkInputs([]string{"a", "b"}) - please.Expect(err).To(MatchError(ContainSubstring("github-token"))) + please.Expect(err).To(MatchError(ContainSubstring("github_access_token"))) + please.Expect(err).To(MatchError(ContainSubstring("github_enterprise_access_token"))) }) t.Run("exp", func(t *testing.T) { @@ -225,6 +210,7 @@ func TestReleaseNotes_checkInputs(t *testing.T) { rn := ReleaseNotes{} rn.Options.IssueTitleExp = "s" + rn.Options.GithubEnterpriseAccessToken = "test-token" err := rn.checkInputs([]string{"a", "b"}) please.Expect(err).NotTo(HaveOccurred()) }) @@ -243,8 +229,9 @@ func Test_getGithubRemoteRepoOwnerAndName(t *testing.T) { "https://github.com/pivotal-cf/kiln", }, }) - o, r, err := getGithubRemoteRepoOwnerAndName(repo) + h, o, r, err := getGithubRemoteHostRepoOwnerAndName(repo) please.Expect(err).NotTo(HaveOccurred()) + please.Expect(h).To(Equal("github.com")) please.Expect(o).To(Equal("pivotal-cf")) please.Expect(r).To(Equal("kiln")) }) @@ -259,8 +246,9 @@ func Test_getGithubRemoteRepoOwnerAndName(t *testing.T) { "git@github.com:pivotal-cf/kiln.git", }, }) - o, r, err := getGithubRemoteRepoOwnerAndName(repo) + h, o, r, err := getGithubRemoteHostRepoOwnerAndName(repo) please.Expect(err).NotTo(HaveOccurred()) + please.Expect(h).To(Equal("github.com")) please.Expect(o).To(Equal("pivotal-cf")) please.Expect(r).To(Equal("kiln")) }) @@ -269,7 +257,7 @@ func Test_getGithubRemoteRepoOwnerAndName(t *testing.T) { please := NewWithT(t) repo, _ := git.Init(memory.NewStorage(), memfs.New()) - _, _, err := getGithubRemoteRepoOwnerAndName(repo) + _, _, _, err := getGithubRemoteHostRepoOwnerAndName(repo) please.Expect(err).To(MatchError(ContainSubstring("not found"))) }) @@ -289,8 +277,9 @@ func Test_getGithubRemoteRepoOwnerAndName(t *testing.T) { "git@github.com:pivotal-cf/kiln.git", }, }) - o, _, err := getGithubRemoteRepoOwnerAndName(repo) + h, o, _, err := getGithubRemoteHostRepoOwnerAndName(repo) please.Expect(err).NotTo(HaveOccurred()) + please.Expect(h).To(Equal("github.com")) please.Expect(o).To(Equal("pivotal-cf"), "it uses the remote with name 'origin'") }) } diff --git a/internal/component/github_release_source.go b/internal/component/github_release_source.go index 0c7ab317f..759d42a81 100644 --- a/internal/component/github_release_source.go +++ b/internal/component/github_release_source.go @@ -43,7 +43,7 @@ func NewGithubReleaseSource(c cargo.ReleaseSourceConfig) *GithubReleaseSource { if c.Org == "" { panic("no github org passed for github release source") } - githubClient, err := c.GitHubClient(context.TODO()) + githubClient, err := gh.Client(context.TODO(), "", c.GithubToken, c.GithubToken) // host is github.com by default if err != nil { panic(err) } diff --git a/internal/gh/client.go b/internal/gh/client.go index e4db8aef6..cea9962ae 100644 --- a/internal/gh/client.go +++ b/internal/gh/client.go @@ -2,15 +2,33 @@ package gh import ( "context" + "errors" + "fmt" + "strings" "github.com/google/go-github/v50/github" "golang.org/x/oauth2" ) -func Client(ctx context.Context, host, accessToken string) (*github.Client, error) { - client := oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: accessToken})) - if host == "" { +/* Client +Creates a GitHub client based on the host. +If host = GitHub Enterprise Host, uses githubEnterpriseAccessToken +Else it assumes host as GitHub.com and uses githubAccessToken +*/ + +func Client(ctx context.Context, host, githubAccessToken string, githubEnterpriseAccessToken string) (*github.Client, error) { + if host != "" && strings.HasSuffix(host, "broadcom.net") { + if githubEnterpriseAccessToken == "" { + return nil, errors.New("github enterprise access token is absent") + } + client := oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubEnterpriseAccessToken})) + return github.NewEnterpriseClient(host, host, client) + } else if host == "" || host == "github.com" { + if githubAccessToken == "" { + return nil, fmt.Errorf("github access token (github.com) is absent") + } + client := oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubAccessToken})) return github.NewClient(client), nil } - return github.NewEnterpriseClient(host, host, client) + return nil, errors.New("github host not recognized") } diff --git a/internal/gh/client_test.go b/internal/gh/client_test.go index bcb97fab3..fe7b996a3 100644 --- a/internal/gh/client_test.go +++ b/internal/gh/client_test.go @@ -13,18 +13,26 @@ func TestClient(t *testing.T) { t.Run("when the host is empty", func(t *testing.T) { ctx := context.Background() token := "xxx" - ghClient, err := gh.Client(ctx, "", token) + ghClient, err := gh.Client(ctx, "", token, token) require.NoError(t, err) require.NotNil(t, ghClient.Client()) assert.Contains(t, ghClient.BaseURL.String(), "https://api.github.com") }) - t.Run("when the host is not empty", func(t *testing.T) { + t.Run("when the host point to enterprise github", func(t *testing.T) { ctx := context.Background() token := "xxx" - ghClient, err := gh.Client(ctx, "https://example.com", token) + ghClient, err := gh.Client(ctx, "https://broadcom.net", token, token) require.NoError(t, err) require.NotNil(t, ghClient.Client()) - assert.Contains(t, ghClient.BaseURL.String(), "https://example.com") + assert.Contains(t, ghClient.BaseURL.String(), "https://broadcom.net") + }) + + t.Run("when the host point to non-enterprise random github", func(t *testing.T) { + ctx := context.Background() + token := "xxx" + ghClient, err := gh.Client(ctx, "https://example.com", token, token) + require.Error(t, err, "github host not recognized") + require.Nil(t, ghClient) }) } diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index aff362091..0f80bc681 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -2,7 +2,6 @@ package cargo import ( "context" - "fmt" "log" "slices" "sort" @@ -129,7 +128,7 @@ type repositoryReleaseLister interface { type ( RepositoryReleaseLister = repositoryReleaseLister - githubReleasesClient func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) + githubReleasesClient func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) ([]repositoryReleaseLister, error) ) // Fetch release notes for each of the release bumps in the Kilnfile @@ -188,9 +187,8 @@ func ReleaseNotes(ctx context.Context, kf Kilnfile, list BumpList) (BumpList, er return releaseNotes(ctx, kf, list, getGithubRepositoryClientForRelease(kf)) } -func getGithubRepositoryClientForRelease(kf Kilnfile) func(ctx context.Context, _ Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { - // todo: []repositoryReleaseLister - return func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { +func getGithubRepositoryClientForRelease(kf Kilnfile) func(ctx context.Context, _ Kilnfile, lock BOSHReleaseTarballLock) ([]repositoryReleaseLister, error) { + return func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) ([]repositoryReleaseLister, error) { spec, err := kf.BOSHReleaseTarballSpecification(lock.Name) if err != nil { return nil, err @@ -201,24 +199,26 @@ func getGithubRepositoryClientForRelease(kf Kilnfile) func(ctx context.Context, return nil, err } - i := slices.IndexFunc(kf.ReleaseSources, func(config ReleaseSourceConfig) bool { - return config.Type == BOSHReleaseTarballSourceTypeGithub && config.Org == owner - }) - if i < 0 { - return nil, fmt.Errorf("release source with id %s not found", lock.RemoteSource) - } - source := kf.ReleaseSources[i] + var repoReleaseLister []repositoryReleaseLister + // Create GitHub clients for all the release sources that have same org as the bosh release. Map the client to + // client.Repositories + for _, releaseSourceConfig := range kf.ReleaseSources { + if releaseSourceConfig.Type == BOSHReleaseTarballSourceTypeGithub && releaseSourceConfig.Org == owner { + client, err := gh.Client(ctx, host, releaseSourceConfig.GithubToken, releaseSourceConfig.GithubToken) + if err != nil { + return nil, err + } + repoReleaseLister = append(repoReleaseLister, client.Repositories) - client, err := source.GitHubClient(ctx, host) - if err != nil { - return nil, err + } } - return client.Repositories, err + + return repoReleaseLister, err } } // Fetch all the releases from GitHub repository between from and to versions -func fetchReleasesFromRepo(ctx context.Context, releaseLister RepositoryReleaseLister, repository string, from, to *semver.Version) []*github.RepositoryRelease { +func fetchReleasesFromRepo(ctx context.Context, releaseListers []RepositoryReleaseLister, repository string, from, to *semver.Version) []*github.RepositoryRelease { owner, repo, err := gh.RepositoryOwnerAndNameFromPath(repository) if err != nil { return nil @@ -227,9 +227,18 @@ func fetchReleasesFromRepo(ctx context.Context, releaseLister RepositoryReleaseL var result []*github.RepositoryRelease ops := github.ListOptions{} - releases, _, err := releaseLister.ListReleases(ctx, owner, repo, &ops) - if err != nil { - log.Println(err) + var releases []*github.RepositoryRelease + for _, releaseLister := range releaseListers { + releases, _, err = releaseLister.ListReleases(ctx, owner, repo, &ops) + if err != nil { + log.Println(err) + // We have multiple releaseListers because there can be different release sources in Kilnfile with the same org but diff access token. + // If we are unable to fetch the releases due to Bad Credentials using one lister, we can try another with different access token. + if releases != nil { + break + } + } + } for _, rel := range releases { @@ -254,8 +263,10 @@ func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, getGithub return bump } - // Fetch the GitHub releases client for a single release (bump) in the Kilnfile - releaseLister, err := getGithubRepositoryClientForRelease(ctx, kf, bump.To) + // Fetch the GitHub releases clients for a single release (bump) in the Kilnfile. + // There can be multiple clients present for a release because Kilnfile can have different release sources matching the release's org + // Need to try out different clients to figure out the right one based on the access token + releaseListers, err := getGithubRepositoryClientForRelease(ctx, kf, bump.To) if err != nil { log.Println(err) return bump @@ -267,7 +278,7 @@ func fetchReleasesForBump(ctx context.Context, kf Kilnfile, bump Bump, getGithub } if spec.GitHubRepository != "" { - releases := fetchReleasesFromRepo(ctx, releaseLister, spec.GitHubRepository, from, to) + releases := fetchReleasesFromRepo(ctx, releaseListers, spec.GitHubRepository, from, to) bump.Releases = append(bump.Releases, releases...) } diff --git a/pkg/cargo/bump_test.go b/pkg/cargo/bump_test.go index e1ea2d555..4b7d9688b 100644 --- a/pkg/cargo/bump_test.go +++ b/pkg/cargo/bump_test.go @@ -164,8 +164,10 @@ func TestInternal_addReleaseNotes(t *testing.T) { To: BOSHReleaseTarballLock{Version: "10"}, From: BOSHReleaseTarballLock{Version: "9"}, }, - }, func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) (repositoryReleaseLister, error) { - return releaseLister, nil + }, func(ctx context.Context, kilnfile Kilnfile, lock BOSHReleaseTarballLock) ([]repositoryReleaseLister, error) { + var r []repositoryReleaseLister + r = append(r, releaseLister) + return r, nil }) please.Expect(err).NotTo(HaveOccurred()) please.Expect(result).To(HaveLen(2)) diff --git a/pkg/cargo/kilnfile.go b/pkg/cargo/kilnfile.go index fea2d37fd..4622543e2 100644 --- a/pkg/cargo/kilnfile.go +++ b/pkg/cargo/kilnfile.go @@ -1,13 +1,10 @@ package cargo import ( - "context" "errors" "fmt" - "github.com/pivotal-cf/kiln/internal/gh" "strings" - "github.com/google/go-github/v50/github" "gopkg.in/yaml.v3" "github.com/Masterminds/semver/v3" @@ -172,22 +169,6 @@ type ReleaseSourceConfig struct { Password string `yaml:"password,omitempty"` } -func (c ReleaseSourceConfig) GitHubClient(ctx context.Context, githubHost string) (*github.Client, error) { - if c.GithubToken == "" { - return nil, errors.New("no token passed for github release source") - } - //tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: c.GithubToken}) - //tokenClient := oauth2.NewClient(ctx, tokenSource) - //var githubClient *github.Client - //gh.Client(ctx) todo use gh.Client not github.NewClient or github.NewEnterpriseClient - return gh.Client(ctx, host, c.GithubToken, c.GithubEnterpriseToken) - //if strings.HasSuffix(githubHost, "broadcom.net") { - // return github.NewEnterpriseClient(c.Endpoint, c.Endpoint, tokenClient) - //} - //githubClient = github.NewClient(tokenClient) - //return githubClient, nil -} - // BOSHReleaseTarballLock represents an exact build of a bosh release // It may identify the where the release is cached; // it may identify the stemcell used to compile the release. diff --git a/pkg/notes/notes_data.go b/pkg/notes/notes_data.go index f5fa8f05c..de8ee221f 100644 --- a/pkg/notes/notes_data.go +++ b/pkg/notes/notes_data.go @@ -127,20 +127,21 @@ func (q IssuesQuery) Exp() (*regexp.Regexp, error) { return regexp.Compile(str) } -func FetchData(ctx context.Context, repo *git.Repository, client *github.Client, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision string, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher, variables map[string]any) (Data, error) { - f, err := newFetchNotesData(repo, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision, client, issuesQuery, trainstatClient, variables) +func FetchData(ctx context.Context, repo *git.Repository, client *github.Client, tileRepoHost, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision string, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher, variables map[string]any) (Data, error) { + f, err := newFetchNotesData(repo, tileRepoHost, tileRepoOwner, tileRepoName, kilnfilePath, initialRevision, finalRevision, client, issuesQuery, trainstatClient, variables) if err != nil { return Data{}, err } return f.fetch(ctx) } -func newFetchNotesData(repo *git.Repository, tileRepoOwner string, tileRepoName string, kilnfilePath string, initialRevision string, finalRevision string, client *github.Client, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher, variables map[string]any) (fetchNotesData, error) { +func newFetchNotesData(repo *git.Repository, tileRepoHost string, tileRepoOwner string, tileRepoName string, kilnfilePath string, initialRevision string, finalRevision string, client *github.Client, issuesQuery IssuesQuery, trainstatClient TrainstatNotesFetcher, variables map[string]any) (fetchNotesData, error) { if repo == nil { return fetchNotesData{}, errors.New("git repository required to generate release notes") } f := fetchNotesData{ + repoHost: tileRepoHost, repoOwner: tileRepoOwner, repoName: tileRepoName, kilnfilePath: kilnfilePath, @@ -174,7 +175,7 @@ type fetchNotesData struct { issuesService - repoOwner, repoName, + repoHost, repoOwner, repoName, kilnfilePath, initialRevision, finalRevision string @@ -329,7 +330,7 @@ type issuesService interface { // manual test to ensure it continues to behave as expected during refactors. // // The function can be tested by generating release notes for a tile with issue ids and a milestone set. The happy path -// test for Execute does not set GithubIssuesServiceToken intentionally so this code is not triggered and Execute does not actually +// test for Execute does not set GithubToken intentionally so this code is not triggered and Execute does not actually // reach out to GitHub. func (r fetchNotesData) fetchIssuesAndReleaseNotes(ctx context.Context, finalKF, wtKF cargo.Kilnfile, bumpList cargo.BumpList, issuesQuery IssuesQuery) ([]*github.Issue, cargo.BumpList, error) { if r.issuesService == nil { diff --git a/pkg/notes/notes_page_test.go b/pkg/notes/notes_page_test.go index c0ebad3f4..fb38f5086 100644 --- a/pkg/notes/notes_page_test.go +++ b/pkg/notes/notes_page_test.go @@ -204,7 +204,7 @@ func TestParseNotesPageWithExpressionAndReleasesSentinel(t *testing.T) { func Test_newFetchNotesData(t *testing.T) { t.Run("when called", func(t *testing.T) { please := NewWithT(t) - f, err := newFetchNotesData(&git.Repository{}, "o", "r", "k", "ri", "rf", nil, IssuesQuery{ + f, err := newFetchNotesData(&git.Repository{}, "h", "o", "r", "k", "ri", "rf", nil, IssuesQuery{ IssueMilestone: "BLA", }, &TrainstatClient{ host: "test", @@ -226,14 +226,14 @@ func Test_newFetchNotesData(t *testing.T) { }) t.Run("when repo is nil", func(t *testing.T) { please := NewWithT(t) - _, err := newFetchNotesData(nil, "o", "r", "k", "ri", "rf", &github.Client{}, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) + _, err := newFetchNotesData(nil, "h", "o", "r", "k", "ri", "rf", &github.Client{}, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) please.Expect(err).To(HaveOccurred()) }) t.Run("when repo is not nil", func(t *testing.T) { please := NewWithT(t) f, err := newFetchNotesData(&git.Repository{ Storer: &memory.Storage{}, - }, "o", "r", "k", "ri", "rf", &github.Client{}, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) + }, "h", "o", "r", "k", "ri", "rf", &github.Client{}, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) please.Expect(err).NotTo(HaveOccurred()) please.Expect(f.repository).NotTo(BeNil()) please.Expect(f.revisionResolver).NotTo(BeNil()) @@ -241,7 +241,7 @@ func Test_newFetchNotesData(t *testing.T) { }) t.Run("when github client is not nil", func(t *testing.T) { please := NewWithT(t) - f, err := newFetchNotesData(&git.Repository{}, "o", "r", "k", "ri", "rf", &github.Client{ + f, err := newFetchNotesData(&git.Repository{}, "h", "o", "r", "k", "ri", "rf", &github.Client{ Issues: &github.IssuesService{}, Repositories: &github.RepositoriesService{}, }, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) @@ -250,7 +250,7 @@ func Test_newFetchNotesData(t *testing.T) { }) t.Run("when github client is nil", func(t *testing.T) { please := NewWithT(t) - f, err := newFetchNotesData(&git.Repository{}, "o", "r", "k", "ri", "rf", nil, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) + f, err := newFetchNotesData(&git.Repository{}, "h", "o", "r", "k", "ri", "rf", nil, IssuesQuery{}, &TrainstatClient{}, make(map[string]any)) please.Expect(err).NotTo(HaveOccurred()) please.Expect(f.issuesService).To(BeNil()) }) From 430694de279628445c19cfc553a9aed6c1a41a3f Mon Sep 17 00:00:00 2001 From: Ajita Jain Date: Fri, 18 Oct 2024 15:42:00 -0700 Subject: [PATCH 13/16] update references to env var GITHUB_TOKEN to GITHUB_ACCESS_TOKEN --- .../workflows/create-debugging-artifact.yml | 3 +-- .github/workflows/release.yml | 5 +---- .github/workflows/test.yml | 1 - .goreleaser.yml | 2 +- TILE_AUTHOR_GUIDE.md | 6 +++--- internal/acceptance/README.md | 4 ++-- .../workflows/baking_a_tile.feature | 8 ++++---- .../generating_release_notes.feature | 4 ++-- .../workflows/scenario/shared_state.go | 2 +- .../workflows/scenario/step_funcs_github.go | 2 +- .../workflows/scenario/step_funcs_kiln.go | 2 +- .../workflows/scenario/utilities.go | 4 ++-- .../tiles/v1/.github/workflows/release.yml | 6 +++--- .../workflows/updating_releases.feature | 6 +++--- .../workflows/updating_stemcell.feature | 4 ++-- internal/commands/generate_osm_manifest.go | 2 +- internal/commands/release_notes.go | 2 +- internal/component/github_release_source.go | 2 +- .../component/github_release_source_test.go | 4 ++-- internal/gh/client.go | 20 ++++++++++++++++++- internal/gh/client_test.go | 8 ++++---- pkg/cargo/bump.go | 2 +- pkg/notes/notes_data.go | 2 +- pkg/notes/notes_data_test.go | 4 ++-- scripts/test.sh | 6 +++--- 25 files changed, 62 insertions(+), 49 deletions(-) diff --git a/.github/workflows/create-debugging-artifact.yml b/.github/workflows/create-debugging-artifact.yml index f95e553d6..3a1bde759 100644 --- a/.github/workflows/create-debugging-artifact.yml +++ b/.github/workflows/create-debugging-artifact.yml @@ -40,7 +40,6 @@ jobs: env: RELEEN_GITHUB_TOKEN: ${{ secrets.RELEEN_GITHUB_TOKEN }} run: | - export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" go test ./... @@ -50,7 +49,7 @@ jobs: RELEEN_GITHUB_TOKEN: ${{ secrets.RELEEN_GITHUB_TOKEN }} run: | set -euo pipefail - export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" + export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" set -x go test --run '(using_kiln|baking_a_tile|generating_release_notes|updating_)' \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e084ff404..2497785b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,6 @@ jobs: env: RELEEN_GITHUB_TOKEN: ${{ secrets.RELEEN_GITHUB_TOKEN }} run: | - export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" go test --covermode=atomic --coverprofile=kiln-${{github.sha}}-unit-test-code-coverage.out ./... @@ -53,7 +52,6 @@ jobs: RELEEN_GITHUB_TOKEN: ${{ secrets.RELEEN_GITHUB_TOKEN }} run: | set -euo pipefail - export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" set -x @@ -81,6 +79,5 @@ jobs: version: latest args: release --rm-dist env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_ACCESS_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3fde51512..fe11e43d2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,7 +50,6 @@ jobs: RELEEN_GITHUB_TOKEN: ${{ secrets.RELEEN_GITHUB_TOKEN }} run: | set -euo pipefail - export GITHUB_TOKEN="${RELEEN_GITHUB_TOKEN}" export GITHUB_ACCESS_TOKEN="${RELEEN_GITHUB_TOKEN}" set -x diff --git a/.goreleaser.yml b/.goreleaser.yml index 837baf7cf..f99fe4584 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -33,7 +33,7 @@ brews: tap: owner: pivotal-cf name: kiln - token: "{{ .Env.GITHUB_TOKEN }}" + token: "{{ .Env.GITHUB_ACCESS_TOKEN }}" folder: HomebrewFormula ids: - homebrew diff --git a/TILE_AUTHOR_GUIDE.md b/TILE_AUTHOR_GUIDE.md index 1893bc011..0a2ce3daa 100644 --- a/TILE_AUTHOR_GUIDE.md +++ b/TILE_AUTHOR_GUIDE.md @@ -358,7 +358,7 @@ release_sources: - type: "github" id: crhntr # (optional) the default ID in this case is the value of org org: "crhntr" - github_token: $(variable "github_token") + github_token: $(variable "github_access_token") ``` **`github_token` is always required even for public repositories because we make API requests** @@ -371,10 +371,10 @@ You will need to add the following flag to most commands: ``` # Optional helper -export GITHUB_TOKEN="$(gh auth status --show-token 2>&1 | grep 'Token:' | awk '{print $NF}')" +export GITHUB_ACCESS_TOKEN="$(gh auth status --show-token 2>&1 | grep 'Token:' | awk '{print $NF}')" # Example Kiln variable flag -kiln fetch --variable="github_token=${GITHUB_TOKEN}" +kiln fetch --variable="github_access_token=${GITHUB_ACCESS_TOKEN}" ``` The value of `remote_path` in the BOSH release tarball lock is a URL. diff --git a/internal/acceptance/README.md b/internal/acceptance/README.md index 243de7716..d830cc4a0 100644 --- a/internal/acceptance/README.md +++ b/internal/acceptance/README.md @@ -25,11 +25,11 @@ go run github.com/onsi/ginkgo/ginkgo ### Workflows These are written in Go and use [godog](https://github.com/cucumber/godog) (a Cucumber test framework). -> PS: Export GITHUB_TOKEN as an env var before running the acceptance tests +> PS: Export GITHUB_ACCESS_TOKEN as an env var before running the acceptance tests ```bash # from anywhere in the repo you can run: -export GITHUB_TOKEN="$(gh auth token)" +export GITHUB_ACCESS_TOKEN="$(gh auth token)" go test -v --tags acceptance --timeout=1h github.com/pivotal-cf/kiln/internal/acceptance/workflows ``` diff --git a/internal/acceptance/workflows/baking_a_tile.feature b/internal/acceptance/workflows/baking_a_tile.feature index 77cd16587..1dc2c6371 100644 --- a/internal/acceptance/workflows/baking_a_tile.feature +++ b/internal/acceptance/workflows/baking_a_tile.feature @@ -5,7 +5,7 @@ Feature: As a developer, I want to bake a tile When I invoke kiln | bake | | --final | - | --variable=github_token="${GITHUB_TOKEN}" | + | --variable=github_access_token="${GITHUB_ACCESS_TOKEN}" | Then a Tile is created And the Tile contains | metadata/metadata.yml | @@ -13,11 +13,11 @@ Feature: As a developer, I want to bake a tile | releases/bpm-1.2.12.tgz | | releases/hello-release-0.2.3.tgz | And "bake_records/0.2.0-dev.json" contains substring: "version": "0.2.0-dev" - And "bake_records/0.2.0-dev.json" contains substring: "source_revision": "6d5069f9dfb954ff77bb16c5aee670b9909f154a" + And "bake_records/0.2.0-dev.json" contains substring: "source_revision": "896c44a006a24d8601ed09fd871b1a4423636d77" And "bake_records/0.2.0-dev.json" contains substring: "tile_directory": "." And "bake_records/0.2.0-dev.json" contains substring: "kiln_version": "0.0.0+acceptance-tests" - And "bake_records/0.2.0-dev.json" contains substring: "file_checksum": "c94e5749bf676f03ff10539956e9445d309647c5299b16dfe71cb522e9258f0d" - And "tile-0.2.0-dev.pivotal" has sha256 sum "c94e5749bf676f03ff10539956e9445d309647c5299b16dfe71cb522e9258f0d" + And "bake_records/0.2.0-dev.json" contains substring: "file_checksum": "6754bb95193e42cd5706f810c3fdb1beead88e2a01601bb222e3e98818f90e8a" + And "tile-0.2.0-dev.pivotal" has sha256 sum "6754bb95193e42cd5706f810c3fdb1beead88e2a01601bb222e3e98818f90e8a" Scenario: it reads directory configuration from Kilnfile Given I have a tile source directory "testdata/tiles/non-standard-paths" diff --git a/internal/acceptance/workflows/generating_release_notes.feature b/internal/acceptance/workflows/generating_release_notes.feature index 798b3e436..d257d859c 100644 --- a/internal/acceptance/workflows/generating_release_notes.feature +++ b/internal/acceptance/workflows/generating_release_notes.feature @@ -10,7 +10,7 @@ Feature: As a robot, I want to generate release notes | --name=hello-release | | --version=v0.1.5 | | --without-download | - | --variable=github_access_token="${GITHUB_TOKEN}" | + | --variable=github_access_token="${GITHUB_ACCESS_TOKEN}" | And I write file "version" | 0.1.4 | And I execute git add Kilnfile.lock version @@ -25,7 +25,7 @@ Feature: As a robot, I want to generate release notes | version | | 0.1.3 | - And the environment variable "GITHUB_TOKEN" is set + And the environment variable "GITHUB_ACCESS_TOKEN" is set When I invoke kiln | release-notes | diff --git a/internal/acceptance/workflows/scenario/shared_state.go b/internal/acceptance/workflows/scenario/shared_state.go index f79444f21..4784ba0c6 100644 --- a/internal/acceptance/workflows/scenario/shared_state.go +++ b/internal/acceptance/workflows/scenario/shared_state.go @@ -107,7 +107,7 @@ func loadGithubToken(ctx context.Context) (context.Context, error) { return ctx, nil } - token := os.Getenv("GITHUB_TOKEN") + token := os.Getenv("GITHUB_ACCESS_TOKEN") if token == "" { token, err = getGithubTokenFromCLI() if err != nil { diff --git a/internal/acceptance/workflows/scenario/step_funcs_github.go b/internal/acceptance/workflows/scenario/step_funcs_github.go index 6d2b9cdcf..2589102e9 100644 --- a/internal/acceptance/workflows/scenario/step_funcs_github.go +++ b/internal/acceptance/workflows/scenario/step_funcs_github.go @@ -13,7 +13,7 @@ func githubRepoHasReleaseWithTag(ctx context.Context, repoOrg, repoName, tag str if err != nil { return err } - ghAPI, err := gh.Client(ctx, "", accessToken, accessToken) + ghAPI, err := gh.Client(ctx, accessToken) if err != nil { return fmt.Errorf("failed to setup github client: %w", err) } diff --git a/internal/acceptance/workflows/scenario/step_funcs_kiln.go b/internal/acceptance/workflows/scenario/step_funcs_kiln.go index bf457fdc5..5e9cad2b3 100644 --- a/internal/acceptance/workflows/scenario/step_funcs_kiln.go +++ b/internal/acceptance/workflows/scenario/step_funcs_kiln.go @@ -19,7 +19,7 @@ func iTryToInvokeKiln(ctx context.Context, table *godog.Table) (context.Context, } func kilnValidateSucceeds(ctx context.Context) (context.Context, error) { - return invokeKiln(ctx, true, "validate", "--variable=github_token=banana") + return invokeKiln(ctx, true, "validate", "--variable=github_access_token=banana") } func invokeKiln(ctx context.Context, requireSuccess bool, args ...string) (context.Context, error) { diff --git a/internal/acceptance/workflows/scenario/utilities.go b/internal/acceptance/workflows/scenario/utilities.go index 905c03c2f..568768ae8 100644 --- a/internal/acceptance/workflows/scenario/utilities.go +++ b/internal/acceptance/workflows/scenario/utilities.go @@ -81,11 +81,11 @@ func getGithubTokenFromCLI() (string, error) { cmd.Stderr = &out err := cmd.Run() if err != nil { - return "", fmt.Errorf("login to github using the CLI or set GITHUB_TOKEN") + return "", fmt.Errorf("login to github using the CLI or set GITHUB_ACCESS_TOKEN") } matches := regexp.MustCompile("(?m)^.*Token: (gho_.*)$").FindStringSubmatch(out.String()) if len(matches) == 0 { - return "", fmt.Errorf("login to github using the CLI or set GITHUB_TOKEN") + return "", fmt.Errorf("login to github using the CLI or set GITHUB_ACCESS_TOKEN") } return matches[1], nil } diff --git a/internal/acceptance/workflows/testdata/tiles/v1/.github/workflows/release.yml b/internal/acceptance/workflows/testdata/tiles/v1/.github/workflows/release.yml index f8678197d..2fa68e877 100644 --- a/internal/acceptance/workflows/testdata/tiles/v1/.github/workflows/release.yml +++ b/internal/acceptance/workflows/testdata/tiles/v1/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: - name: Bake Tile env: KILN_VERSION: 0.68.3 - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} TILE_VERSION: ${{ steps.vars.outputs.tag_name }} run: | cd "${GITHUB_WORKSPACE}" || exit 1 @@ -36,8 +36,8 @@ jobs: echo "${TILE_VERSION}" > version - kiln fetch --variable github_token="${GITHUB_TOKEN}" - kiln validate --variable github_token="${GITHUB_TOKEN}" + kiln fetch --variable github_access_token="${GITHUB_ACCESS_TOKEN}" + kiln validate --variable github_access_token="${GITHUB_ACCESS_TOKEN}" kiln bake - name: Create GitHub Release diff --git a/internal/acceptance/workflows/updating_releases.feature b/internal/acceptance/workflows/updating_releases.feature index 7f60254bf..ac2bef48d 100644 --- a/internal/acceptance/workflows/updating_releases.feature +++ b/internal/acceptance/workflows/updating_releases.feature @@ -6,7 +6,7 @@ Feature: As a dependabot, I want to update a BOSH Release When I invoke kiln | find-release-version | | --release=hello-release | - | --variable=github_token="${GITHUB_TOKEN}" | + | --variable=github_access_token="${GITHUB_ACCESS_TOKEN}" | Then stdout contains substring: "0.2.3" Scenario: Find a version on bosh.io @@ -15,7 +15,7 @@ Feature: As a dependabot, I want to update a BOSH Release When I invoke kiln | find-release-version | | --release=bpm | - | --variable=github_token="${GITHUB_TOKEN}" | + | --variable=github_access_token="${GITHUB_ACCESS_TOKEN}" | Then stdout contains substring: "1.1.18" Scenario: Update a component to a new release @@ -27,6 +27,6 @@ Feature: As a dependabot, I want to update a BOSH Release | --name=hello-release | | --version=v0.2.3 | | --without-download | - | --variable=github_token="${GITHUB_TOKEN}" | + | --variable=github_access_token="${GITHUB_ACCESS_TOKEN}" | Then the Kilnfile.lock specifies version "0.2.3" for release "hello-release" And kiln validate succeeds diff --git a/internal/acceptance/workflows/updating_stemcell.feature b/internal/acceptance/workflows/updating_stemcell.feature index 6f9365a9e..c206e2087 100644 --- a/internal/acceptance/workflows/updating_stemcell.feature +++ b/internal/acceptance/workflows/updating_stemcell.feature @@ -10,7 +10,7 @@ Feature: As a dependabot, I want to update a stemcell And I set the Kilnfile stemcell version constraint to "=< 1.341" When I invoke kiln | find-stemcell-version | - | --variable=github_token="${GITHUB_TOKEN}" | + | --variable=github_access_token="${GITHUB_ACCESS_TOKEN}" | Then stdout contains substring: "1.340" Scenario: Update the stemcell @@ -20,5 +20,5 @@ Feature: As a dependabot, I want to update a stemcell When I invoke kiln | update-stemcell | | --version=1.340 | - | --variable=github_token="${GITHUB_TOKEN}" | + | --variable=github_access_token="${GITHUB_ACCESS_TOKEN}" | Then "Kilnfile.lock" contains substring: version: "1.340" diff --git a/internal/commands/generate_osm_manifest.go b/internal/commands/generate_osm_manifest.go index e7bdb141e..064daf6a3 100644 --- a/internal/commands/generate_osm_manifest.go +++ b/internal/commands/generate_osm_manifest.go @@ -29,7 +29,7 @@ type OSM struct { Options struct { flags.Standard NoDownload bool `short:"nd" long:"no-download" default:"false" description:"Do not download & zip the packages"` - GithubToken string `short:"g" long:"github-token" description:"Auth token for fetching specified Github packages" env:"GITHUB_TOKEN"` + GithubToken string `short:"g" long:"github_access_token" description:"Auth token for fetching specified Github packages" env:"GITHUB_ACCESS_TOKEN"` Only string `short:"o" long:"only" default:"" description:"Only download the specified package name, must be used with --url to specify package Github URL"` Url string `short:"u" long:"url" default:"" description:"Github URL for package specified by --only"` } diff --git a/internal/commands/release_notes.go b/internal/commands/release_notes.go index 3e13a8eeb..7cb1f3b41 100644 --- a/internal/commands/release_notes.go +++ b/internal/commands/release_notes.go @@ -107,7 +107,7 @@ func (r ReleaseNotes) Execute(args []string) error { var client *github.Client - client, err = gh.Client(ctx, r.repoHost, r.Options.GithubAccessToken, r.Options.GithubEnterpriseAccessToken) + client, err = gh.GitClient(ctx, r.repoHost, r.Options.GithubAccessToken, r.Options.GithubEnterpriseAccessToken) if err != nil { return fmt.Errorf("failed to setup github client: %w", err) } diff --git a/internal/component/github_release_source.go b/internal/component/github_release_source.go index 759d42a81..793d38d81 100644 --- a/internal/component/github_release_source.go +++ b/internal/component/github_release_source.go @@ -43,7 +43,7 @@ func NewGithubReleaseSource(c cargo.ReleaseSourceConfig) *GithubReleaseSource { if c.Org == "" { panic("no github org passed for github release source") } - githubClient, err := gh.Client(context.TODO(), "", c.GithubToken, c.GithubToken) // host is github.com by default + githubClient, err := gh.Client(context.TODO(), c.GithubToken) if err != nil { panic(err) } diff --git a/internal/component/github_release_source_test.go b/internal/component/github_release_source_test.go index d121429cb..a94180b06 100644 --- a/internal/component/github_release_source_test.go +++ b/internal/component/github_release_source_test.go @@ -24,7 +24,7 @@ func TestListAllOfTheCrap(t *testing.T) { grs := component.NewGithubReleaseSource(cargo.ReleaseSourceConfig{ Type: component.ReleaseSourceTypeGithub, - GithubToken: os.Getenv("GITHUB_TOKEN"), + GithubToken: os.Getenv("GITHUB_ACCESS_TOKEN"), Org: "cloudfoundry", }) // grs.ListAllOfTheCrap(context.TODO(), "cloudfoundry") @@ -535,7 +535,7 @@ func TestDownloadReleaseAsset(t *testing.T) { grs := component.NewGithubReleaseSource(cargo.ReleaseSourceConfig{ Type: component.ReleaseSourceTypeGithub, - GithubToken: os.Getenv("GITHUB_TOKEN"), + GithubToken: os.Getenv("GITHUB_ACCESS_TOKEN"), Org: "cloudfoundry", }) testLock, err := grs.GetMatchedRelease(cargo.BOSHReleaseTarballSpecification{Name: "routing", Version: "0.226.0", GitHubRepository: "https://github.com/cloudfoundry/routing-release"}) diff --git a/internal/gh/client.go b/internal/gh/client.go index cea9962ae..e9fbe4517 100644 --- a/internal/gh/client.go +++ b/internal/gh/client.go @@ -11,17 +11,35 @@ import ( ) /* Client + +This method doesn't support creating a GitHub Client based on the host and is soon to be deprecated. Kindly use the GitClient +method below +*/ + +func Client(ctx context.Context, githubAccessToken string) (*github.Client, error) { + client, err := GitClient(ctx, "", githubAccessToken, githubAccessToken) + if err != nil { + return nil, err + } + return client, nil +} + +/* GitClient + Creates a GitHub client based on the host. If host = GitHub Enterprise Host, uses githubEnterpriseAccessToken Else it assumes host as GitHub.com and uses githubAccessToken */ -func Client(ctx context.Context, host, githubAccessToken string, githubEnterpriseAccessToken string) (*github.Client, error) { +func GitClient(ctx context.Context, host, githubAccessToken string, githubEnterpriseAccessToken string) (*github.Client, error) { if host != "" && strings.HasSuffix(host, "broadcom.net") { if githubEnterpriseAccessToken == "" { return nil, errors.New("github enterprise access token is absent") } client := oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubEnterpriseAccessToken})) + if !strings.HasPrefix(host, "http") { + host = "https://" + host + } return github.NewEnterpriseClient(host, host, client) } else if host == "" || host == "github.com" { if githubAccessToken == "" { diff --git a/internal/gh/client_test.go b/internal/gh/client_test.go index fe7b996a3..5b4495955 100644 --- a/internal/gh/client_test.go +++ b/internal/gh/client_test.go @@ -10,10 +10,10 @@ import ( ) func TestClient(t *testing.T) { - t.Run("when the host is empty", func(t *testing.T) { + t.Run("when the host is empty - backward compatibility", func(t *testing.T) { ctx := context.Background() token := "xxx" - ghClient, err := gh.Client(ctx, "", token, token) + ghClient, err := gh.Client(ctx, token) require.NoError(t, err) require.NotNil(t, ghClient.Client()) assert.Contains(t, ghClient.BaseURL.String(), "https://api.github.com") @@ -22,7 +22,7 @@ func TestClient(t *testing.T) { t.Run("when the host point to enterprise github", func(t *testing.T) { ctx := context.Background() token := "xxx" - ghClient, err := gh.Client(ctx, "https://broadcom.net", token, token) + ghClient, err := gh.GitClient(ctx, "https://broadcom.net", token, token) require.NoError(t, err) require.NotNil(t, ghClient.Client()) assert.Contains(t, ghClient.BaseURL.String(), "https://broadcom.net") @@ -31,7 +31,7 @@ func TestClient(t *testing.T) { t.Run("when the host point to non-enterprise random github", func(t *testing.T) { ctx := context.Background() token := "xxx" - ghClient, err := gh.Client(ctx, "https://example.com", token, token) + ghClient, err := gh.GitClient(ctx, "https://example.com", token, token) require.Error(t, err, "github host not recognized") require.Nil(t, ghClient) }) diff --git a/pkg/cargo/bump.go b/pkg/cargo/bump.go index 0f80bc681..1f5ce26ab 100644 --- a/pkg/cargo/bump.go +++ b/pkg/cargo/bump.go @@ -204,7 +204,7 @@ func getGithubRepositoryClientForRelease(kf Kilnfile) func(ctx context.Context, // client.Repositories for _, releaseSourceConfig := range kf.ReleaseSources { if releaseSourceConfig.Type == BOSHReleaseTarballSourceTypeGithub && releaseSourceConfig.Org == owner { - client, err := gh.Client(ctx, host, releaseSourceConfig.GithubToken, releaseSourceConfig.GithubToken) + client, err := gh.GitClient(ctx, host, releaseSourceConfig.GithubToken, releaseSourceConfig.GithubToken) if err != nil { return nil, err } diff --git a/pkg/notes/notes_data.go b/pkg/notes/notes_data.go index de8ee221f..3be42c20d 100644 --- a/pkg/notes/notes_data.go +++ b/pkg/notes/notes_data.go @@ -330,7 +330,7 @@ type issuesService interface { // manual test to ensure it continues to behave as expected during refactors. // // The function can be tested by generating release notes for a tile with issue ids and a milestone set. The happy path -// test for Execute does not set GithubToken intentionally so this code is not triggered and Execute does not actually +// test for Execute does not set GithubAccessToken/GithubEnterprisesAccessToken intentionally so this code is not triggered and Execute does not actually // reach out to GitHub. func (r fetchNotesData) fetchIssuesAndReleaseNotes(ctx context.Context, finalKF, wtKF cargo.Kilnfile, bumpList cargo.BumpList, issuesQuery IssuesQuery) ([]*github.Issue, cargo.BumpList, error) { if r.issuesService == nil { diff --git a/pkg/notes/notes_data_test.go b/pkg/notes/notes_data_test.go index 6a2c51416..ed397b8a5 100644 --- a/pkg/notes/notes_data_test.go +++ b/pkg/notes/notes_data_test.go @@ -25,7 +25,7 @@ import ( func Test_fetch_for_ist_tas(t *testing.T) { please := NewWithT(t) - t.Setenv("GITHUB_TOKEN", "") + t.Setenv("GITHUB_ACCESS_TOKEN", "") repo, _ := git.Init(memory.NewStorage(), memfs.New()) @@ -152,7 +152,7 @@ func Test_fetch_for_ist_tas(t *testing.T) { func Test_fetch_for_tasw(t *testing.T) { please := NewWithT(t) - t.Setenv("GITHUB_TOKEN", "") + t.Setenv("GITHUB_ACCESS_TOKEN", "") repo, _ := git.Init(memory.NewStorage(), memfs.New()) diff --git a/scripts/test.sh b/scripts/test.sh index d75addda7..81cc83d9e 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -19,9 +19,9 @@ function main() { golangci-lint run ./... set +x - echo "Setting GITHUB_TOKEN with 'gh auth token'" - export GITHUB_TOKEN - GITHUB_TOKEN="$(gh auth token)" + echo "Setting GITHUB_ACCESS_TOKEN with 'gh auth token'" + export GITHUB_ACCESS_TOKEN + GITHUB_ACCESS_TOKEN="$(gh auth token)" set -x go test -v -count=1 -tags acceptance --timeout=25m ./internal/acceptance/workflows From 47b5d34e012fd8db9e3b6765e140966877b11518 Mon Sep 17 00:00:00 2001 From: Rizwan Reza Date: Tue, 29 Oct 2024 09:11:23 -0500 Subject: [PATCH 14/16] Use GitClient in the GitHub Release Source to support GitHub enterprise --- internal/component/github_release_source.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/internal/component/github_release_source.go b/internal/component/github_release_source.go index 793d38d81..70f5e0034 100644 --- a/internal/component/github_release_source.go +++ b/internal/component/github_release_source.go @@ -43,7 +43,17 @@ func NewGithubReleaseSource(c cargo.ReleaseSourceConfig) *GithubReleaseSource { if c.Org == "" { panic("no github org passed for github release source") } - githubClient, err := gh.Client(context.TODO(), c.GithubToken) + + // The GitClient should be initialized with the proper host according to + // the release repository URL instead. This function doesn't have access + // to each release, so this will do for now. + // + host := "" + if c.Org == "TNZ" { + host = "https://github.gwd.broadcom.net" + } + + githubClient, err := gh.GitClient(context.TODO(), host, c.GithubToken, c.GithubToken) if err != nil { panic(err) } From 549e78d9233bea1592b8ab6b6233a6b9d5a0984a Mon Sep 17 00:00:00 2001 From: Rizwan Reza Date: Tue, 29 Oct 2024 13:38:44 -0500 Subject: [PATCH 15/16] Update go and remove unused libraries [Co-authored by: Dave Walter ] --- go.mod | 3 +-- go.sum | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 8b3a2155b..0245810fd 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/pivotal-cf/kiln -go 1.22.6 +go 1.23 require ( github.com/Masterminds/semver/v3 v3.2.1 @@ -17,7 +17,6 @@ require ( github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.11.0 - github.com/google/go-github/v40 v40.0.0 github.com/google/go-github/v50 v50.2.0 github.com/julienschmidt/httprouter v1.3.0 github.com/masterminds/sprig v2.22.0+incompatible diff --git a/go.sum b/go.sum index 9063f3b1a..12c618f8a 100644 --- a/go.sum +++ b/go.sum @@ -301,12 +301,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v40 v40.0.0 h1:oBPVDaIhdUmwDWRRH8XJ/dZG+Rn755i08+Hp1uJHlR0= -github.com/google/go-github/v40 v40.0.0/go.mod h1:G8wWKTEjUCL0zdbaQvpwDk0hqf6KZgPQH+ssJa+/NVc= github.com/google/go-github/v50 v50.0.0/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA= github.com/google/go-github/v50 v50.2.0 h1:j2FyongEHlO9nxXLc+LP3wuBSVU9mVxfpdYUexMpIfk= github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q= From 5ef85e611ef17805faefda0dac8c5365dbe84acd Mon Sep 17 00:00:00 2001 From: Rizwan Reza Date: Tue, 29 Oct 2024 14:15:32 -0500 Subject: [PATCH 16/16] Update counterfeiter and regenerate all fakes Co-authored by: --- go.mod | 26 ++++---- go.sum | 59 +++++++++-------- internal/builder/fakes/zipper.go | 14 ++-- internal/commands/fakes/filesystem.go | 66 +++++++++---------- internal/commands/fakes/test_tile_function.go | 5 +- internal/commands/release_notes.go | 1 - internal/commands/test_tile.go | 1 + internal/commands/test_tile_test.go | 3 +- 8 files changed, 90 insertions(+), 85 deletions(-) diff --git a/go.mod b/go.mod index 0245810fd..0f1567c74 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/pivotal-cf/kiln go 1.23 +toolchain go1.23.2 + require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/avvmoto/buf-readerat v0.0.0-20171115124131-a17c8cb89270 @@ -20,11 +22,11 @@ require ( github.com/google/go-github/v50 v50.2.0 github.com/julienschmidt/httprouter v1.3.0 github.com/masterminds/sprig v2.22.0+incompatible - github.com/maxbrunsfeld/counterfeiter/v6 v6.5.0 + github.com/maxbrunsfeld/counterfeiter/v6 v6.10.0 github.com/migueleliasweb/go-github-mock v0.0.16 github.com/moby/buildkit v0.12.5 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.27.10 + github.com/onsi/gomega v1.34.2 github.com/opencontainers/image-spec v1.1.0 github.com/pivotal-cf-experimental/gomegamatchers v0.0.0-20180326192815-e36bfcc98c3a github.com/pivotal-cf/go-pivnet/v7 v7.0.2 @@ -32,10 +34,10 @@ require ( github.com/pivotal-cf/om v0.0.0-20230707145702-e2ef8fd451b1 github.com/snabb/httpreaderat v1.0.1 github.com/stretchr/testify v1.8.4 - golang.org/x/crypto v0.21.0 + golang.org/x/crypto v0.28.0 golang.org/x/oauth2 v0.16.0 - golang.org/x/sync v0.6.0 - golang.org/x/term v0.18.0 + golang.org/x/sync v0.8.0 + golang.org/x/term v0.25.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -68,7 +70,7 @@ require ( github.com/fatih/color v1.15.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect @@ -118,17 +120,17 @@ require ( go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/sdk v1.21.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.18.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.26.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect google.golang.org/grpc v1.62.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index 12c618f8a..754515bc8 100644 --- a/go.sum +++ b/go.sum @@ -232,8 +232,8 @@ github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v0.0.0-20180625085808-7a0fa49edf48/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= @@ -246,7 +246,8 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -321,8 +322,8 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230811205829-9131a7e9cc17 h1:0h35ESZ02+hN/MFZb7XZOXg+Rl9+Rk8fBIf5YLws9gA= -github.com/google/pprof v0.0.0-20230811205829-9131a7e9cc17/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/readahead v0.0.0-20161222183148-eaceba169032/go.mod h1:qYysrqQXuV4tzsizt4oOQ6mrBZQ0xnQXP3ylXX8Jk5Y= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= @@ -431,8 +432,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= -github.com/maxbrunsfeld/counterfeiter/v6 v6.5.0 h1:rBhB9Rls+yb8kA4x5a/cWxOufWfXt24E+kq4YlbGj3g= -github.com/maxbrunsfeld/counterfeiter/v6 v6.5.0/go.mod h1:fJ0UAZc1fx3xZhU4eSHQDJ1ApFmTVhp5VTpV9tm2ogg= +github.com/maxbrunsfeld/counterfeiter/v6 v6.10.0 h1:9WsegDYiSKtZXru+NcOB4z7iqb00n4atjmQlyy5TRXI= +github.com/maxbrunsfeld/counterfeiter/v6 v6.10.0/go.mod h1:TeVdzh+5QB5IpWDJAU/uviXA6kOg9yXzLrrjeLKJXqY= github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= github.com/migueleliasweb/go-github-mock v0.0.16 h1:iEx6iqYASRJVoEO5eMOYpQZFTc00cZ6ysynOArUKM3A= github.com/migueleliasweb/go-github-mock v0.0.16/go.mod h1:CjrgPd8s5sf5g3XSESAQqxufae+PZbgM/F317C3uD7g= @@ -468,8 +469,8 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo= +github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.4.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -479,8 +480,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= @@ -626,8 +627,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -662,8 +663,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180712202826-d0887baf81f4/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -710,8 +711,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -734,8 +735,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180709060233-1b2967e3c290/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -797,8 +798,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -806,8 +807,8 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -820,8 +821,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -880,8 +881,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -984,8 +985,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/builder/fakes/zipper.go b/internal/builder/fakes/zipper.go index 49e02b439..45245e71d 100644 --- a/internal/builder/fakes/zipper.go +++ b/internal/builder/fakes/zipper.go @@ -3,7 +3,7 @@ package fakes import ( "io" - "io/fs" + "os" "sync" "time" ) @@ -21,12 +21,12 @@ type Zipper struct { addReturnsOnCall map[int]struct { result1 error } - AddWithModeStub func(string, io.Reader, fs.FileMode) error + AddWithModeStub func(string, io.Reader, os.FileMode) error addWithModeMutex sync.RWMutex addWithModeArgsForCall []struct { arg1 string arg2 io.Reader - arg3 fs.FileMode + arg3 os.FileMode } addWithModeReturns struct { result1 error @@ -131,13 +131,13 @@ func (fake *Zipper) AddReturnsOnCall(i int, result1 error) { }{result1} } -func (fake *Zipper) AddWithMode(arg1 string, arg2 io.Reader, arg3 fs.FileMode) error { +func (fake *Zipper) AddWithMode(arg1 string, arg2 io.Reader, arg3 os.FileMode) error { fake.addWithModeMutex.Lock() ret, specificReturn := fake.addWithModeReturnsOnCall[len(fake.addWithModeArgsForCall)] fake.addWithModeArgsForCall = append(fake.addWithModeArgsForCall, struct { arg1 string arg2 io.Reader - arg3 fs.FileMode + arg3 os.FileMode }{arg1, arg2, arg3}) stub := fake.AddWithModeStub fakeReturns := fake.addWithModeReturns @@ -158,13 +158,13 @@ func (fake *Zipper) AddWithModeCallCount() int { return len(fake.addWithModeArgsForCall) } -func (fake *Zipper) AddWithModeCalls(stub func(string, io.Reader, fs.FileMode) error) { +func (fake *Zipper) AddWithModeCalls(stub func(string, io.Reader, os.FileMode) error) { fake.addWithModeMutex.Lock() defer fake.addWithModeMutex.Unlock() fake.AddWithModeStub = stub } -func (fake *Zipper) AddWithModeArgsForCall(i int) (string, io.Reader, fs.FileMode) { +func (fake *Zipper) AddWithModeArgsForCall(i int) (string, io.Reader, os.FileMode) { fake.addWithModeMutex.RLock() defer fake.addWithModeMutex.RUnlock() argsForCall := fake.addWithModeArgsForCall[i] diff --git a/internal/commands/fakes/filesystem.go b/internal/commands/fakes/filesystem.go index 8064ef3af..6ef3d3b71 100644 --- a/internal/commands/fakes/filesystem.go +++ b/internal/commands/fakes/filesystem.go @@ -2,7 +2,7 @@ package fakes import ( - "io/fs" + "os" "sync" billy "github.com/go-git/go-billy/v5" @@ -34,11 +34,11 @@ type FileSystem struct { joinReturnsOnCall map[int]struct { result1 string } - MkdirAllStub func(string, fs.FileMode) error + MkdirAllStub func(string, os.FileMode) error mkdirAllMutex sync.RWMutex mkdirAllArgsForCall []struct { arg1 string - arg2 fs.FileMode + arg2 os.FileMode } mkdirAllReturns struct { result1 error @@ -59,12 +59,12 @@ type FileSystem struct { result1 billy.File result2 error } - OpenFileStub func(string, int, fs.FileMode) (billy.File, error) + OpenFileStub func(string, int, os.FileMode) (billy.File, error) openFileMutex sync.RWMutex openFileArgsForCall []struct { arg1 string arg2 int - arg3 fs.FileMode + arg3 os.FileMode } openFileReturns struct { result1 billy.File @@ -74,17 +74,17 @@ type FileSystem struct { result1 billy.File result2 error } - ReadDirStub func(string) ([]fs.FileInfo, error) + ReadDirStub func(string) ([]os.FileInfo, error) readDirMutex sync.RWMutex readDirArgsForCall []struct { arg1 string } readDirReturns struct { - result1 []fs.FileInfo + result1 []os.FileInfo result2 error } readDirReturnsOnCall map[int]struct { - result1 []fs.FileInfo + result1 []os.FileInfo result2 error } RemoveStub func(string) error @@ -110,17 +110,17 @@ type FileSystem struct { renameReturnsOnCall map[int]struct { result1 error } - StatStub func(string) (fs.FileInfo, error) + StatStub func(string) (os.FileInfo, error) statMutex sync.RWMutex statArgsForCall []struct { arg1 string } statReturns struct { - result1 fs.FileInfo + result1 os.FileInfo result2 error } statReturnsOnCall map[int]struct { - result1 fs.FileInfo + result1 os.FileInfo result2 error } invocations map[string][][]interface{} @@ -252,12 +252,12 @@ func (fake *FileSystem) JoinReturnsOnCall(i int, result1 string) { }{result1} } -func (fake *FileSystem) MkdirAll(arg1 string, arg2 fs.FileMode) error { +func (fake *FileSystem) MkdirAll(arg1 string, arg2 os.FileMode) error { fake.mkdirAllMutex.Lock() ret, specificReturn := fake.mkdirAllReturnsOnCall[len(fake.mkdirAllArgsForCall)] fake.mkdirAllArgsForCall = append(fake.mkdirAllArgsForCall, struct { arg1 string - arg2 fs.FileMode + arg2 os.FileMode }{arg1, arg2}) stub := fake.MkdirAllStub fakeReturns := fake.mkdirAllReturns @@ -278,13 +278,13 @@ func (fake *FileSystem) MkdirAllCallCount() int { return len(fake.mkdirAllArgsForCall) } -func (fake *FileSystem) MkdirAllCalls(stub func(string, fs.FileMode) error) { +func (fake *FileSystem) MkdirAllCalls(stub func(string, os.FileMode) error) { fake.mkdirAllMutex.Lock() defer fake.mkdirAllMutex.Unlock() fake.MkdirAllStub = stub } -func (fake *FileSystem) MkdirAllArgsForCall(i int) (string, fs.FileMode) { +func (fake *FileSystem) MkdirAllArgsForCall(i int) (string, os.FileMode) { fake.mkdirAllMutex.RLock() defer fake.mkdirAllMutex.RUnlock() argsForCall := fake.mkdirAllArgsForCall[i] @@ -378,13 +378,13 @@ func (fake *FileSystem) OpenReturnsOnCall(i int, result1 billy.File, result2 err }{result1, result2} } -func (fake *FileSystem) OpenFile(arg1 string, arg2 int, arg3 fs.FileMode) (billy.File, error) { +func (fake *FileSystem) OpenFile(arg1 string, arg2 int, arg3 os.FileMode) (billy.File, error) { fake.openFileMutex.Lock() ret, specificReturn := fake.openFileReturnsOnCall[len(fake.openFileArgsForCall)] fake.openFileArgsForCall = append(fake.openFileArgsForCall, struct { arg1 string arg2 int - arg3 fs.FileMode + arg3 os.FileMode }{arg1, arg2, arg3}) stub := fake.OpenFileStub fakeReturns := fake.openFileReturns @@ -405,13 +405,13 @@ func (fake *FileSystem) OpenFileCallCount() int { return len(fake.openFileArgsForCall) } -func (fake *FileSystem) OpenFileCalls(stub func(string, int, fs.FileMode) (billy.File, error)) { +func (fake *FileSystem) OpenFileCalls(stub func(string, int, os.FileMode) (billy.File, error)) { fake.openFileMutex.Lock() defer fake.openFileMutex.Unlock() fake.OpenFileStub = stub } -func (fake *FileSystem) OpenFileArgsForCall(i int) (string, int, fs.FileMode) { +func (fake *FileSystem) OpenFileArgsForCall(i int) (string, int, os.FileMode) { fake.openFileMutex.RLock() defer fake.openFileMutex.RUnlock() argsForCall := fake.openFileArgsForCall[i] @@ -444,7 +444,7 @@ func (fake *FileSystem) OpenFileReturnsOnCall(i int, result1 billy.File, result2 }{result1, result2} } -func (fake *FileSystem) ReadDir(arg1 string) ([]fs.FileInfo, error) { +func (fake *FileSystem) ReadDir(arg1 string) ([]os.FileInfo, error) { fake.readDirMutex.Lock() ret, specificReturn := fake.readDirReturnsOnCall[len(fake.readDirArgsForCall)] fake.readDirArgsForCall = append(fake.readDirArgsForCall, struct { @@ -469,7 +469,7 @@ func (fake *FileSystem) ReadDirCallCount() int { return len(fake.readDirArgsForCall) } -func (fake *FileSystem) ReadDirCalls(stub func(string) ([]fs.FileInfo, error)) { +func (fake *FileSystem) ReadDirCalls(stub func(string) ([]os.FileInfo, error)) { fake.readDirMutex.Lock() defer fake.readDirMutex.Unlock() fake.ReadDirStub = stub @@ -482,28 +482,28 @@ func (fake *FileSystem) ReadDirArgsForCall(i int) string { return argsForCall.arg1 } -func (fake *FileSystem) ReadDirReturns(result1 []fs.FileInfo, result2 error) { +func (fake *FileSystem) ReadDirReturns(result1 []os.FileInfo, result2 error) { fake.readDirMutex.Lock() defer fake.readDirMutex.Unlock() fake.ReadDirStub = nil fake.readDirReturns = struct { - result1 []fs.FileInfo + result1 []os.FileInfo result2 error }{result1, result2} } -func (fake *FileSystem) ReadDirReturnsOnCall(i int, result1 []fs.FileInfo, result2 error) { +func (fake *FileSystem) ReadDirReturnsOnCall(i int, result1 []os.FileInfo, result2 error) { fake.readDirMutex.Lock() defer fake.readDirMutex.Unlock() fake.ReadDirStub = nil if fake.readDirReturnsOnCall == nil { fake.readDirReturnsOnCall = make(map[int]struct { - result1 []fs.FileInfo + result1 []os.FileInfo result2 error }) } fake.readDirReturnsOnCall[i] = struct { - result1 []fs.FileInfo + result1 []os.FileInfo result2 error }{result1, result2} } @@ -631,7 +631,7 @@ func (fake *FileSystem) RenameReturnsOnCall(i int, result1 error) { }{result1} } -func (fake *FileSystem) Stat(arg1 string) (fs.FileInfo, error) { +func (fake *FileSystem) Stat(arg1 string) (os.FileInfo, error) { fake.statMutex.Lock() ret, specificReturn := fake.statReturnsOnCall[len(fake.statArgsForCall)] fake.statArgsForCall = append(fake.statArgsForCall, struct { @@ -656,7 +656,7 @@ func (fake *FileSystem) StatCallCount() int { return len(fake.statArgsForCall) } -func (fake *FileSystem) StatCalls(stub func(string) (fs.FileInfo, error)) { +func (fake *FileSystem) StatCalls(stub func(string) (os.FileInfo, error)) { fake.statMutex.Lock() defer fake.statMutex.Unlock() fake.StatStub = stub @@ -669,28 +669,28 @@ func (fake *FileSystem) StatArgsForCall(i int) string { return argsForCall.arg1 } -func (fake *FileSystem) StatReturns(result1 fs.FileInfo, result2 error) { +func (fake *FileSystem) StatReturns(result1 os.FileInfo, result2 error) { fake.statMutex.Lock() defer fake.statMutex.Unlock() fake.StatStub = nil fake.statReturns = struct { - result1 fs.FileInfo + result1 os.FileInfo result2 error }{result1, result2} } -func (fake *FileSystem) StatReturnsOnCall(i int, result1 fs.FileInfo, result2 error) { +func (fake *FileSystem) StatReturnsOnCall(i int, result1 os.FileInfo, result2 error) { fake.statMutex.Lock() defer fake.statMutex.Unlock() fake.StatStub = nil if fake.statReturnsOnCall == nil { fake.statReturnsOnCall = make(map[int]struct { - result1 fs.FileInfo + result1 os.FileInfo result2 error }) } fake.statReturnsOnCall[i] = struct { - result1 fs.FileInfo + result1 os.FileInfo result2 error }{result1, result2} } diff --git a/internal/commands/fakes/test_tile_function.go b/internal/commands/fakes/test_tile_function.go index 2fe5e67fc..99351a0e9 100644 --- a/internal/commands/fakes/test_tile_function.go +++ b/internal/commands/fakes/test_tile_function.go @@ -6,6 +6,7 @@ import ( "io" "sync" + "github.com/pivotal-cf/kiln/internal/commands" "github.com/pivotal-cf/kiln/internal/test" ) @@ -37,7 +38,7 @@ func (fake *TestTileFunction) Spy(arg1 context.Context, arg2 io.Writer, arg3 tes }{arg1, arg2, arg3}) stub := fake.Stub returns := fake.returns - fake.recordInvocation("tileTestFunction", []interface{}{arg1, arg2, arg3}) + fake.recordInvocation("TileTestFunction", []interface{}{arg1, arg2, arg3}) fake.mutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3) @@ -112,3 +113,5 @@ func (fake *TestTileFunction) recordInvocation(key string, args []interface{}) { } fake.invocations[key] = append(fake.invocations[key], args) } + +var _ commands.TileTestFunction = new(TestTileFunction).Spy diff --git a/internal/commands/release_notes.go b/internal/commands/release_notes.go index 7cb1f3b41..e73028f1b 100644 --- a/internal/commands/release_notes.go +++ b/internal/commands/release_notes.go @@ -114,7 +114,6 @@ func (r ReleaseNotes) Execute(args []string) error { trainstatClient := notes.NewTrainstatClient(r.Options.TrainstatQuery.TrainstatURL) - _ = notes.FetchData // fetchNotesData is github.com/pivotal/kiln/internal/notes.FetchData data, err := r.fetchNotesData(ctx, r.repository, client, r.repoHost, r.repoOwner, r.repoName, r.Options.Kilnfile, diff --git a/internal/commands/test_tile.go b/internal/commands/test_tile.go index 996e13216..74361f31c 100644 --- a/internal/commands/test_tile.go +++ b/internal/commands/test_tile.go @@ -12,6 +12,7 @@ import ( "github.com/pivotal-cf/kiln/internal/test" ) +//counterfeiter:generate -o ./fakes/test_tile_function.go --fake-name TestTileFunction . TileTestFunction type TileTestFunction func(ctx context.Context, w io.Writer, configuration test.Configuration) error type TileTest struct { diff --git a/internal/commands/test_tile_test.go b/internal/commands/test_tile_test.go index 69aceab29..871ad6c01 100644 --- a/internal/commands/test_tile_test.go +++ b/internal/commands/test_tile_test.go @@ -26,12 +26,11 @@ func init() { // counterfeiter does not handle publicly exported type function spy generation super well. // So I am telling it to generate the spy off of a private type alias. This works but is a bit confusing. // -//counterfeiter:generate -o ./fakes/test_tile_function.go --fake-name TestTileFunction . tileTestFunction // nolint:unused // //goland:noinspection GoUnusedType -type tileTestFunction = commands.TileTestFunction +// type tileTestFunction = commands.TileTestFunction var _ = Describe("kiln test", func() { var output bytes.Buffer