From 47b407daf6b59f89c706a190e437ce55cdfdf2a2 Mon Sep 17 00:00:00 2001 From: Thomas Vilte Date: Fri, 31 Jul 2026 16:51:07 -0300 Subject: [PATCH 1/2] chore(go): update Go versions and linting configuration --- .github/workflows/ci.yml | 7 +-- .github/workflows/golangci-lint.yml | 8 ++- internal/ai/gemini/issue_content_generator.go | 6 +-- internal/ai/gemini/release_generator.go | 50 +++++++++---------- internal/ai/prompts.go | 22 ++++---- internal/commands/release/formatter.go | 20 ++++---- internal/services/issue_generator_service.go | 14 +++--- internal/services/pull_request_service.go | 4 +- internal/services/release_changelog.go | 20 ++++---- internal/vcs/github/client_pr.go | 6 +-- 10 files changed, 78 insertions(+), 79 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c576a41..9714efb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: [ '1.21', '1.22', '1.23'] + go-version: [ '1.25', '1.26'] steps: - name: Checkout code @@ -33,11 +33,6 @@ jobs: go mod tidy git diff --exit-code go.mod go.sum || (echo "go.mod or go.sum changed unexpectedly" && exit 1) - - name: Run golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - version: latest - - name: Run tests env: JIRA_API_KEY: ${{ secrets.JIRA_API_KEY }} diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 48606d2..24c357e 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -14,9 +14,13 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: '1.24' + go-version: '1.25' cache: false - name: golangci-lint uses: golangci/golangci-lint-action@v6 with: - version: latest + # golangci-lint stopped cutting v1.x releases; "latest" here still + # resolves to the last v1.x tag (v1.64.8, built with go1.24), which + # can't lint a module whose go.mod requires go1.25+. Pin an actual + # v2 release explicitly instead of trusting "latest". + version: v2.12.2 diff --git a/internal/ai/gemini/issue_content_generator.go b/internal/ai/gemini/issue_content_generator.go index b6e1efb..80774a3 100644 --- a/internal/ai/gemini/issue_content_generator.go +++ b/internal/ai/gemini/issue_content_generator.go @@ -230,7 +230,7 @@ func (s *GeminiIssueContentGenerator) buildIssuePrompt(request models.IssueGener var sb strings.Builder if request.Description != "" { - sb.WriteString(fmt.Sprintf("Global Description: %s\n\n", request.Description)) + fmt.Fprintf(&sb, "Global Description: %s\n\n", request.Description) } if request.Diff != "" { @@ -243,14 +243,14 @@ func (s *GeminiIssueContentGenerator) buildIssuePrompt(request models.IssueGener if len(request.ChangedFiles) > 0 { sb.WriteString("Changed files:\n") for _, file := range request.ChangedFiles { - sb.WriteString(fmt.Sprintf("- %s\n", file)) + fmt.Fprintf(&sb, "- %s\n", file) } sb.WriteString("\n") } } if request.Hint != "" { - sb.WriteString(fmt.Sprintf("User Hint: %s\n\n", request.Hint)) + fmt.Fprintf(&sb, "User Hint: %s\n\n", request.Hint) } if request.Template != nil { diff --git a/internal/ai/gemini/release_generator.go b/internal/ai/gemini/release_generator.go index 03c875a..f1c898f 100644 --- a/internal/ai/gemini/release_generator.go +++ b/internal/ai/gemini/release_generator.go @@ -283,53 +283,53 @@ func (g *ReleaseNotesGenerator) formatChangesForPrompt(release *models.Release) headers := ai.GetReleaseNotesSectionHeaders(g.lang) if len(release.Breaking) > 0 { - sb.WriteString(fmt.Sprintf("%s\n", headers["breaking"])) + fmt.Fprintf(&sb, "%s\n", headers["breaking"]) for _, item := range release.Breaking { - sb.WriteString(fmt.Sprintf("- %s: %s\n", item.Type, item.Description)) + fmt.Fprintf(&sb, "- %s: %s\n", item.Type, item.Description) } sb.WriteString("\n") } if len(release.Features) > 0 { - sb.WriteString(fmt.Sprintf("%s\n", headers["features"])) + fmt.Fprintf(&sb, "%s\n", headers["features"]) for _, item := range release.Features { - sb.WriteString(fmt.Sprintf("- %s: %s\n", item.Type, item.Description)) + fmt.Fprintf(&sb, "- %s: %s\n", item.Type, item.Description) } sb.WriteString("\n") } if len(release.BugFixes) > 0 { - sb.WriteString(fmt.Sprintf("%s\n", headers["fixes"])) + fmt.Fprintf(&sb, "%s\n", headers["fixes"]) for _, item := range release.BugFixes { - sb.WriteString(fmt.Sprintf("- %s: %s\n", item.Type, item.Description)) + fmt.Fprintf(&sb, "- %s: %s\n", item.Type, item.Description) } sb.WriteString("\n") } if len(release.Improvements) > 0 { - sb.WriteString(fmt.Sprintf("%s\n", headers["improvements"])) + fmt.Fprintf(&sb, "%s\n", headers["improvements"]) for _, item := range release.Improvements { - sb.WriteString(fmt.Sprintf("- %s: %s\n", item.Type, item.Description)) + fmt.Fprintf(&sb, "- %s: %s\n", item.Type, item.Description) } sb.WriteString("\n") } if len(release.ClosedIssues) > 0 { - sb.WriteString(fmt.Sprintf("%s\n", headers["closed_issues"])) + fmt.Fprintf(&sb, "%s\n", headers["closed_issues"]) for _, issue := range release.ClosedIssues { - sb.WriteString(fmt.Sprintf("- #%d: %s (by @%s)\n", issue.Number, issue.Title, issue.Author)) + fmt.Fprintf(&sb, "- #%d: %s (by @%s)\n", issue.Number, issue.Title, issue.Author) } sb.WriteString("\n") } if len(release.MergedPRs) > 0 { - sb.WriteString(fmt.Sprintf("%s\n", headers["merged_prs"])) + fmt.Fprintf(&sb, "%s\n", headers["merged_prs"]) for _, pr := range release.MergedPRs { - sb.WriteString(fmt.Sprintf("- #%d: %s (by @%s)\n", pr.Number, pr.Title, pr.Author)) + fmt.Fprintf(&sb, "- #%d: %s (by @%s)\n", pr.Number, pr.Title, pr.Author) if pr.Description != "" { lines := strings.Split(pr.Description, "\n") if len(lines) > 0 && lines[0] != "" { - sb.WriteString(fmt.Sprintf(" Description: %s\n", lines[0])) + fmt.Fprintf(&sb, " Description: %s\n", lines[0]) } } } @@ -337,40 +337,40 @@ func (g *ReleaseNotesGenerator) formatChangesForPrompt(release *models.Release) } if len(release.Contributors) > 0 { - sb.WriteString(fmt.Sprintf("%s (%d total):\n", headers["contributors"], len(release.Contributors))) + fmt.Fprintf(&sb, "%s (%d total):\n", headers["contributors"], len(release.Contributors)) for _, contributor := range release.Contributors { - sb.WriteString(fmt.Sprintf("- @%s\n", contributor)) + fmt.Fprintf(&sb, "- @%s\n", contributor) } if len(release.NewContributors) > 0 { - sb.WriteString(fmt.Sprintf("New contributors: %s\n", strings.Join(release.NewContributors, ", "))) + fmt.Fprintf(&sb, "New contributors: %s\n", strings.Join(release.NewContributors, ", ")) } sb.WriteString("\n") } if release.FileStats.FilesChanged > 0 { - sb.WriteString(fmt.Sprintf("%s\n", headers["file_stats"])) - sb.WriteString(fmt.Sprintf("- Files changed: %d\n", release.FileStats.FilesChanged)) - sb.WriteString(fmt.Sprintf("- Insertions: +%d\n", release.FileStats.Insertions)) - sb.WriteString(fmt.Sprintf("- Deletions: -%d\n", release.FileStats.Deletions)) + fmt.Fprintf(&sb, "%s\n", headers["file_stats"]) + fmt.Fprintf(&sb, "- Files changed: %d\n", release.FileStats.FilesChanged) + fmt.Fprintf(&sb, "- Insertions: +%d\n", release.FileStats.Insertions) + fmt.Fprintf(&sb, "- Deletions: -%d\n", release.FileStats.Deletions) if len(release.FileStats.TopFiles) > 0 { sb.WriteString("Top modified files:\n") for _, file := range release.FileStats.TopFiles { - sb.WriteString(fmt.Sprintf(" - %s (+%d/-%d)\n", file.Path, file.Additions, file.Deletions)) + fmt.Fprintf(&sb, " - %s (+%d/-%d)\n", file.Path, file.Additions, file.Deletions) } } sb.WriteString("\n") } if len(release.Dependencies) > 0 { - sb.WriteString(fmt.Sprintf("%s\n", headers["deps"])) + fmt.Fprintf(&sb, "%s\n", headers["deps"]) for _, dep := range release.Dependencies { switch dep.Type { case "updated": - sb.WriteString(fmt.Sprintf("- %s: %s → %s\n", dep.Name, dep.OldVersion, dep.NewVersion)) + fmt.Fprintf(&sb, "- %s: %s → %s\n", dep.Name, dep.OldVersion, dep.NewVersion) case "added": - sb.WriteString(fmt.Sprintf("- Added: %s %s\n", dep.Name, dep.NewVersion)) + fmt.Fprintf(&sb, "- Added: %s %s\n", dep.Name, dep.NewVersion) case "removed": - sb.WriteString(fmt.Sprintf("- Removed: %s %s\n", dep.Name, dep.OldVersion)) + fmt.Fprintf(&sb, "- Removed: %s %s\n", dep.Name, dep.OldVersion) } } sb.WriteString("\n") diff --git a/internal/ai/prompts.go b/internal/ai/prompts.go index 7b07244..4adae71 100644 --- a/internal/ai/prompts.go +++ b/internal/ai/prompts.go @@ -446,17 +446,17 @@ func FormatTemplateForPrompt(template *models.IssueTemplate, lang string, templa if template.Name != "" { if lang == "es" { - sb.WriteString(fmt.Sprintf("Nombre del Template: %s\n", template.Name)) + fmt.Fprintf(&sb, "Nombre del Template: %s\n", template.Name) } else { - sb.WriteString(fmt.Sprintf("Template Name: %s\n", template.Name)) + fmt.Fprintf(&sb, "Template Name: %s\n", template.Name) } } if template.GetAbout() != "" { if lang == "es" { - sb.WriteString(fmt.Sprintf("Descripción del Template: %s\n", template.GetAbout())) + fmt.Fprintf(&sb, "Descripción del Template: %s\n", template.GetAbout()) } else { - sb.WriteString(fmt.Sprintf("Template Description: %s\n", template.GetAbout())) + fmt.Fprintf(&sb, "Template Description: %s\n", template.GetAbout()) } } @@ -497,12 +497,12 @@ func FormatTemplateForPrompt(template *models.IssueTemplate, lang string, templa } if item.Attributes.Label != "" { - sb.WriteString(fmt.Sprintf("### %s\n", item.Attributes.Label)) + fmt.Fprintf(&sb, "### %s\n", item.Attributes.Label) if item.Attributes.Description != "" { - sb.WriteString(fmt.Sprintf("Context: %s\n", item.Attributes.Description)) + fmt.Fprintf(&sb, "Context: %s\n", item.Attributes.Description) } if item.Attributes.Placeholder != "" { - sb.WriteString(fmt.Sprintf("Example: %s\n", item.Attributes.Placeholder)) + fmt.Fprintf(&sb, "Example: %s\n", item.Attributes.Placeholder) } sb.WriteString("\n") } @@ -581,22 +581,22 @@ func FormatIssuesForPrompt(issues []models.Issue, locale string) string { var result strings.Builder for _, issue := range issues { if locale == "es" { - result.WriteString(fmt.Sprintf("- Issue #%d: %s\n", issue.Number, issue.Title)) + fmt.Fprintf(&result, "- Issue #%d: %s\n", issue.Number, issue.Title) if issue.Description != "" { desc := issue.Description if len(desc) > 200 { desc = desc[:200] + "..." } - result.WriteString(fmt.Sprintf(" Descripción: %s\n", desc)) + fmt.Fprintf(&result, " Descripción: %s\n", desc) } } else { - result.WriteString(fmt.Sprintf("- Issue #%d: %s\n", issue.Number, issue.Title)) + fmt.Fprintf(&result, "- Issue #%d: %s\n", issue.Number, issue.Title) if issue.Description != "" { desc := issue.Description if len(desc) > 200 { desc = desc[:200] + "..." } - result.WriteString(fmt.Sprintf(" Description: %s\n", desc)) + fmt.Fprintf(&result, " Description: %s\n", desc) } } } diff --git a/internal/commands/release/formatter.go b/internal/commands/release/formatter.go index 5912597..a35b78a 100644 --- a/internal/commands/release/formatter.go +++ b/internal/commands/release/formatter.go @@ -80,9 +80,9 @@ func FormatReleaseMarkdown(release *models.Release, notes *models.ReleaseNotes, md.WriteString("\n\n") for _, pr := range release.MergedPRs { if pr.URL != "" { - md.WriteString(fmt.Sprintf("- [#%d](%s) %s (by @%s)\n", pr.Number, pr.URL, pr.Title, pr.Author)) + fmt.Fprintf(&md, "- [#%d](%s) %s (by @%s)\n", pr.Number, pr.URL, pr.Title, pr.Author) } else { - md.WriteString(fmt.Sprintf("- #%d %s (by @%s)\n", pr.Number, pr.Title, pr.Author)) + fmt.Fprintf(&md, "- #%d %s (by @%s)\n", pr.Number, pr.Title, pr.Author) } } md.WriteString("\n") @@ -97,7 +97,7 @@ func FormatReleaseMarkdown(release *models.Release, notes *models.ReleaseNotes, md.WriteString(trans.GetMessage("release.new_contributors", 0, struct{ Count int }{len(release.NewContributors)})) md.WriteString(" ") for i, contributor := range release.NewContributors { - md.WriteString(fmt.Sprintf("@%s", contributor)) + fmt.Fprintf(&md, "@%s", contributor) if i < len(release.NewContributors)-1 { md.WriteString(", ") } @@ -108,7 +108,7 @@ func FormatReleaseMarkdown(release *models.Release, notes *models.ReleaseNotes, md.WriteString(trans.GetMessage("release.all_contributors", 0, nil)) md.WriteString("\n") for _, contributor := range release.Contributors { - md.WriteString(fmt.Sprintf("- @%s\n", contributor)) + fmt.Fprintf(&md, "- @%s\n", contributor) } md.WriteString("\n") } @@ -117,15 +117,15 @@ func FormatReleaseMarkdown(release *models.Release, notes *models.ReleaseNotes, md.WriteString("## ") md.WriteString(trans.GetMessage("release.md_stats", 0, nil)) md.WriteString("\n\n") - md.WriteString(fmt.Sprintf("- %s: **%d**\n", + fmt.Fprintf(&md, "- %s: **%d**\n", trans.GetMessage("release.files_changed", 0, nil), - release.FileStats.FilesChanged)) - md.WriteString(fmt.Sprintf("- %s: **+%d**\n", + release.FileStats.FilesChanged) + fmt.Fprintf(&md, "- %s: **+%d**\n", trans.GetMessage("release.insertions", 0, nil), - release.FileStats.Insertions)) - md.WriteString(fmt.Sprintf("- %s: **-%d**\n", + release.FileStats.Insertions) + fmt.Fprintf(&md, "- %s: **-%d**\n", trans.GetMessage("release.deletions", 0, nil), - release.FileStats.Deletions)) + release.FileStats.Deletions) md.WriteString("\n") } return content + md.String() diff --git a/internal/services/issue_generator_service.go b/internal/services/issue_generator_service.go index 6500c55..e5b9cc3 100644 --- a/internal/services/issue_generator_service.go +++ b/internal/services/issue_generator_service.go @@ -288,7 +288,7 @@ func (s *IssueGeneratorService) GenerateFromPR(ctx context.Context, prNumber int "diff_size", len(prData.Diff)) var contextBuilder strings.Builder - contextBuilder.WriteString(fmt.Sprintf("Pull Request #%d: %s\n\n", prNumber, prData.Title)) + fmt.Fprintf(&contextBuilder, "Pull Request #%d: %s\n\n", prNumber, prData.Title) if prData.Description != "" { contextBuilder.WriteString("PR Description:\n") @@ -299,7 +299,7 @@ func (s *IssueGeneratorService) GenerateFromPR(ctx context.Context, prNumber int if len(prData.Commits) > 0 { contextBuilder.WriteString("Commits:\n") for _, commit := range prData.Commits { - contextBuilder.WriteString(fmt.Sprintf("- %s\n", commit)) + fmt.Fprintf(&contextBuilder, "- %s\n", commit) } contextBuilder.WriteString("\n") } @@ -423,21 +423,21 @@ func (s *IssueGeneratorService) SelectTemplateWithAI(ctx context.Context, title, var templateListBuilder strings.Builder for _, t := range templates { - templateListBuilder.WriteString(fmt.Sprintf("- %s: %s\n", t.Name, t.About)) + fmt.Fprintf(&templateListBuilder, "- %s: %s\n", t.Name, t.About) } var contextBuilder strings.Builder if title != "" { - contextBuilder.WriteString(fmt.Sprintf("Title: %s\n", title)) + fmt.Fprintf(&contextBuilder, "Title: %s\n", title) } if description != "" { - contextBuilder.WriteString(fmt.Sprintf("Description: %s\n", description)) + fmt.Fprintf(&contextBuilder, "Description: %s\n", description) } if len(changedFiles) > 0 { - contextBuilder.WriteString(fmt.Sprintf("Changed files: %s\n", strings.Join(changedFiles, ", "))) + fmt.Fprintf(&contextBuilder, "Changed files: %s\n", strings.Join(changedFiles, ", ")) } if len(labels) > 0 { - contextBuilder.WriteString(fmt.Sprintf("Labels: %s\n", strings.Join(labels, ", "))) + fmt.Fprintf(&contextBuilder, "Labels: %s\n", strings.Join(labels, ", ")) } prompt := fmt.Sprintf(`You are an intelligent assistant helping to select the correct issue template for a software project. diff --git a/internal/services/pull_request_service.go b/internal/services/pull_request_service.go index c68482c..fb1d42c 100644 --- a/internal/services/pull_request_service.go +++ b/internal/services/pull_request_service.go @@ -407,7 +407,7 @@ func (s *PRService) generateTestPlan(prData models.PRData) string { if len(prData.RelatedIssues) > 0 { testPlan.WriteString("### Associated Issues\n") for _, issue := range prData.RelatedIssues { - testPlan.WriteString(fmt.Sprintf("- [ ] Verify #%d is fully resolved\n", issue.Number)) + fmt.Fprintf(&testPlan, "- [ ] Verify #%d is fully resolved\n", issue.Number) } testPlan.WriteString("\n") } @@ -438,7 +438,7 @@ func (s *PRService) addBreakingChangesToSummary(summary models.PRSummary, breaki breakingSection.WriteString("\n\n## Breaking Changes\n\n") for _, change := range breakingChanges { - breakingSection.WriteString(fmt.Sprintf("- %s\n", change)) + fmt.Fprintf(&breakingSection, "- %s\n", change) } summary.Body += breakingSection.String() diff --git a/internal/services/release_changelog.go b/internal/services/release_changelog.go index db2ecb8..f01ca1e 100644 --- a/internal/services/release_changelog.go +++ b/internal/services/release_changelog.go @@ -459,7 +459,7 @@ func (s *ReleaseService) buildChangelogFromNotes(ctx context.Context, release *m sb.WriteString(versionHeader + "\n\n") if notes.Summary != "" { - sb.WriteString(fmt.Sprintf("%s\n\n", notes.Summary)) + fmt.Fprintf(&sb, "%s\n\n", notes.Summary) } usedReferences := make(map[string]bool) @@ -467,9 +467,9 @@ func (s *ReleaseService) buildChangelogFromNotes(ctx context.Context, release *m if len(notes.Sections) > 0 { for _, section := range notes.Sections { if section.Title != "" && len(section.Items) > 0 { - sb.WriteString(fmt.Sprintf("### %s\n\n", section.Title)) + fmt.Fprintf(&sb, "### %s\n\n", section.Title) for _, item := range section.Items { - sb.WriteString(fmt.Sprintf("- %s\n", s.formatNoteBulletWithReference(release, item, owner, repo, provider, usedReferences))) + fmt.Fprintf(&sb, "- %s\n", s.formatNoteBulletWithReference(release, item, owner, repo, provider, usedReferences)) } sb.WriteString("\n") } @@ -477,7 +477,7 @@ func (s *ReleaseService) buildChangelogFromNotes(ctx context.Context, release *m } else if len(notes.Highlights) > 0 { sb.WriteString("### Highlights\n\n") for _, highlight := range notes.Highlights { - sb.WriteString(fmt.Sprintf("- %s\n", s.formatNoteBulletWithReference(release, highlight, owner, repo, provider, usedReferences))) + fmt.Fprintf(&sb, "- %s\n", s.formatNoteBulletWithReference(release, highlight, owner, repo, provider, usedReferences)) } sb.WriteString("\n") } @@ -485,7 +485,7 @@ func (s *ReleaseService) buildChangelogFromNotes(ctx context.Context, release *m if len(notes.BreakingChanges) > 0 { sb.WriteString("### Breaking Changes\n\n") for _, bc := range notes.BreakingChanges { - sb.WriteString(fmt.Sprintf("- %s\n", s.formatNoteBulletWithReference(release, bc, owner, repo, provider, usedReferences))) + fmt.Fprintf(&sb, "- %s\n", s.formatNoteBulletWithReference(release, bc, owner, repo, provider, usedReferences)) } sb.WriteString("\n") } @@ -494,7 +494,7 @@ func (s *ReleaseService) buildChangelogFromNotes(ctx context.Context, release *m if len(references) > 0 { sb.WriteString("### References\n\n") for _, reference := range references { - sb.WriteString(fmt.Sprintf("- %s\n", reference)) + fmt.Fprintf(&sb, "- %s\n", reference) } sb.WriteString("\n") } @@ -503,9 +503,9 @@ func (s *ReleaseService) buildChangelogFromNotes(ctx context.Context, release *m sb.WriteString("### Pull Requests\n\n") for _, pr := range release.MergedPRs { if pr.URL != "" { - sb.WriteString(fmt.Sprintf("- [#%d](%s) %s (by @%s)\n", pr.Number, pr.URL, pr.Title, pr.Author)) + fmt.Fprintf(&sb, "- [#%d](%s) %s (by @%s)\n", pr.Number, pr.URL, pr.Title, pr.Author) } else { - sb.WriteString(fmt.Sprintf("- #%d %s (by @%s)\n", pr.Number, pr.Title, pr.Author)) + fmt.Fprintf(&sb, "- #%d %s (by @%s)\n", pr.Number, pr.Title, pr.Author) } } sb.WriteString("\n") @@ -515,7 +515,7 @@ func (s *ReleaseService) buildChangelogFromNotes(ctx context.Context, release *m sb.WriteString("### Contributors\n\n") sb.WriteString("Thanks to ") for i, contributor := range release.Contributors { - sb.WriteString(fmt.Sprintf("@%s", contributor)) + fmt.Fprintf(&sb, "@%s", contributor) if i < len(release.Contributors)-1 { sb.WriteString(", ") } @@ -655,7 +655,7 @@ func (s *ReleaseService) BuildChangelogPreview(ctx context.Context, release *mod func (s *ReleaseService) buildChangelog(release *models.Release) string { var sb strings.Builder - sb.WriteString(fmt.Sprintf("## %s\n\n", release.Version)) + fmt.Fprintf(&sb, "## %s\n\n", release.Version) if len(release.Breaking) > 0 { sb.WriteString("### BREAKING CHANGES\n\n") diff --git a/internal/vcs/github/client_pr.go b/internal/vcs/github/client_pr.go index 2daabba..0309a27 100644 --- a/internal/vcs/github/client_pr.go +++ b/internal/vcs/github/client_pr.go @@ -255,12 +255,12 @@ func (ghc *GitHubClient) getDiffFromCommits(ctx context.Context, commits []*gith } if fullCommit.GetStats().GetTotal() > 0 { - combinedDiff.WriteString(fmt.Sprintf("\n# Commit: %s\n", sha[:8])) - combinedDiff.WriteString(fmt.Sprintf("# Message: %s\n\n", strings.Split(commit.GetCommit().GetMessage(), "\n")[0])) + fmt.Fprintf(&combinedDiff, "\n# Commit: %s\n", sha[:8]) + fmt.Fprintf(&combinedDiff, "# Message: %s\n\n", strings.Split(commit.GetCommit().GetMessage(), "\n")[0]) for _, file := range fullCommit.Files { if file.Patch != nil { - combinedDiff.WriteString(fmt.Sprintf("diff --git a/%s b/%s\n", file.GetFilename(), file.GetFilename())) + fmt.Fprintf(&combinedDiff, "diff --git a/%s b/%s\n", file.GetFilename(), file.GetFilename()) combinedDiff.WriteString(*file.Patch) combinedDiff.WriteString("\n") } From 72037256399c793ec3e7c3cc987db169aee0e2b9 Mon Sep 17 00:00:00 2001 From: Thomas Vilte Date: Fri, 31 Jul 2026 16:54:50 -0300 Subject: [PATCH 2/2] chore(ci): update golangci-lint action to v9 --- .github/workflows/golangci-lint.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 24c357e..305c7e5 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -17,10 +17,11 @@ jobs: go-version: '1.25' cache: false - name: golangci-lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v9 with: # golangci-lint stopped cutting v1.x releases; "latest" here still # resolves to the last v1.x tag (v1.64.8, built with go1.24), which # can't lint a module whose go.mod requires go1.25+. Pin an actual - # v2 release explicitly instead of trusting "latest". + # v2 release explicitly instead of trusting "latest" — and the + # action itself has to be v7+, since v6 hard-rejects v2 versions. version: v2.12.2