Skip to content

Conversation

@ksylvan
Copy link
Collaborator

@ksylvan ksylvan commented Dec 16, 2025

modernize: update GitHub Actions and modernize Go code

Summary

This PR modernizes the codebase by upgrading GitHub Actions dependencies and adopting Go 1.23+ standard library improvements. The changes focus on using newer string manipulation functions (strings.CutPrefix, strings.CutSuffix, strings.SplitSeq) and slice utilities (slices.Contains) to replace older, more verbose patterns. Additionally, GitHub Actions are updated to their latest versions, and a new modernization check is added to the CI pipeline.

Related Issues

Closes #1873

Files Changed

GitHub Actions Workflows

  • .github/workflows/ci.yml: Updated action versions, reordered steps, and added modernization check
  • .github/workflows/patterns.yaml: Bumped actions/checkout@v6 and actions/upload-artifact@v6
  • .github/workflows/release.yml: Updated actions/checkout@v6 and actions/setup-go@v6
  • .github/workflows/update-version-and-create-tag.yml: Updated action versions and fixed conditional syntax

Go Source Files

  • cmd/generate_changelog/internal/changelog/generator.go: Adopted strings.SplitSeq for iterating over lines
  • cmd/generate_changelog/internal/changelog/processing.go: Used strings.CutSuffix for cleaner string manipulation
  • internal/cli/flags.go: Refactored using strings.CutPrefix and slices.Contains
  • internal/cli/help.go: Simplified flag parsing and padding calculation with max() function
  • internal/cli/output.go: Replaced manual loop with slices.Contains
  • internal/domain/file_manager.go: Used slices.Contains for escape sequence validation
  • internal/plugins/ai/gemini/voices.go: Migrated to strings.Builder for efficient string concatenation
  • internal/plugins/ai/lmstudio/lmstudio.go: Adopted bytes.CutPrefix
  • internal/plugins/ai/openai/openai_image.go: Simplified model checking with slices.Contains
  • internal/plugins/ai/perplexity/perplexity.go: Used strings.Builder for content assembly
  • internal/plugins/template/extension_executor_test.go: Converted to strings.Builder in test setup
  • internal/server/ollama.go: Used fmt.Appendf and strings.SplitSeq

Code Changes

GitHub Actions Dependency Updates

Updated all GitHub Actions to their latest major versions for improved security and performance:

- uses: actions/checkout@v5
+ uses: actions/checkout@v6

- uses: actions/setup-go@v5
+ uses: actions/setup-go@v6

- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v6

- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@v21

New Modernization Check

Added an automated check to identify further modernization opportunities:

- name: Check for modernization opportunities
  run: |
    go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest ./...

String Manipulation Improvements

Replaced verbose prefix/suffix checking patterns with cleaner Go 1.20+ functions:

Before:

if strings.HasPrefix(arg, "--debug=") {
    if lvl, err := strconv.Atoi(strings.TrimPrefix(arg, "--debug=")); err == nil {
        return lvl
    }
}

After:

if after, ok := strings.CutPrefix(arg, "--debug="); ok {
    if lvl, err := strconv.Atoi(after); err == nil {
        return lvl
    }
}

Slice Contains Simplification

Replaced manual loops with slices.Contains for readability:

Before:

valid := false
for _, validSize := range validSizes {
    if size == validSize {
        valid = true
        break
    }
}

After:

valid := slices.Contains(validSizes, size)

Iterator-Based String Splitting

Adopted strings.SplitSeq for memory-efficient iteration over split strings:

Before:

lines := strings.Split(pr.Body, "\n")
for _, line := range lines {
    // process line
}

After:

lines := strings.SplitSeq(pr.Body, "\n")
for line := range lines {
    // process line
}

String Builder Pattern

Replaced string concatenation with strings.Builder for better performance:

Before:

result := "Available Gemini Text-to-Speech voices:\n\n"
result += fmt.Sprintf("%s:\n", groupName)
return result

After:

var result strings.Builder
result.WriteString("Available Gemini Text-to-Speech voices:\n\n")
result.WriteString(fmt.Sprintf("%s:\n", groupName))
return result.String()

Reason for Changes

  1. Security and Stability: GitHub Actions v6 includes security improvements and bug fixes
  2. Performance: strings.Builder and iterator-based splitting reduce memory allocations
  3. Readability: Modern Go idioms (CutPrefix, CutSuffix, slices.Contains) are more expressive
  4. Maintainability: Cleaner code is easier to understand and modify
  5. Future-proofing: Adopting Go 1.23+ patterns prepares the codebase for future Go versions
  6. Automation: The modernization check prevents regression to older patterns

Impact of Changes

Positive Impacts

  • Improved Performance: String operations allocate less memory and run faster
  • Enhanced Readability: Code is more concise and self-documenting
  • Better CI/CD: Updated actions provide improved performance and security
  • Reduced Cognitive Load: Simpler patterns are easier to reason about

Potential Risks

  • Go Version Requirement: Code now requires Go 1.23+ for strings.SplitSeq and other features
  • Behavioral Changes: While semantically equivalent, iterator-based approaches may have subtle differences in error handling
  • Action Breaking Changes: GitHub Actions major version updates may introduce breaking changes (though v5→v6 transitions are generally smooth)

Test Plan

  1. Unit Tests: All existing Go tests should pass with go test -v ./...
  2. CI Pipeline: The workflow changes will be validated on the next push to a branch
  3. Manual Testing: Verify that:
    • String parsing logic behaves identically (flag parsing, file validation)
    • Iterator-based loops produce the same output
    • String building produces identical results
    • GitHub Actions complete successfully in CI
  4. Integration Testing: Run full build and release workflows to ensure action updates don't break deployment

Additional Notes

Breaking Changes

  • Go Version: This PR effectively raises the minimum Go version to 1.23. The go.mod file should be updated accordingly if not already set.

Potential Bugs

  1. Iterator Edge Cases: strings.SplitSeq behavior differs slightly from strings.Split for edge cases (empty strings, single elements). Verified behavior is identical for all usage patterns in this codebase.
  2. Conditional Syntax Fix: The workflow file had incorrect YAML syntax (${{ }}) that was removed. This was a bug fix rather than a potential issue.
  3. Buffer Reuse: Using fmt.Appendf(nil, ...) creates a new buffer each time, which is semantically equivalent to the original code.

ksylvan and others added 2 commits December 15, 2025 23:55
…dlib features

## CHANGES

- Upgrade GitHub Actions to latest versions (v6, v21)
- Add modernization check step in CI workflow
- Replace strings manipulation with `strings.CutPrefix` and `strings.CutSuffix`
- Replace manual loops with `slices.Contains` for validation
- Use `strings.SplitSeq` for iterator-based string splitting
- Replace `bytes.TrimPrefix` with `bytes.CutPrefix` for clarity
- Use `strings.Builder` instead of string concatenation
- Replace `fmt.Sprintf` with `fmt.Appendf` for efficiency
- Simplify padding calculation with `max` builtin
@ksylvan ksylvan self-assigned this Dec 16, 2025
@ksylvan ksylvan merged commit 201d1fb into danielmiessler:main Dec 16, 2025
1 check passed
@ksylvan ksylvan deleted the kayvan/modernize-part4-string-and-slice-syntax branch December 16, 2025 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Go codebase modernize fixes

1 participant