diff --git a/.github/actions/setup-mdbook/action.yaml b/.github/actions/setup-mdbook/action.yaml new file mode 100644 index 0000000..23e0665 --- /dev/null +++ b/.github/actions/setup-mdbook/action.yaml @@ -0,0 +1,16 @@ +name: "Setup mdbook" +inputs: + version: + description: "mdbook version" + +runs: + using: composite + steps: + - name: Setup mdbook + shell: bash + env: + url: https://github.com/rust-lang/mdbook/releases/download/${{ inputs.version }}/mdbook-${{ inputs.version }}-x86_64-unknown-linux-gnu.tar.gz + run: | + mkdir mdbook + curl -sSL "$url" | tar -xz --directory=./mdbook + echo `pwd`/mdbook >> $GITHUB_PATH diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 5110561..83d07be 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -69,15 +69,6 @@ ': (?.+) # renovate: datasource=(?[a-z-]+) depName=(?[^\\s]+)(?: lookupName=(?[^\\s]+))?(?: versioning=(?[a-z-]+))?(?: extractVersion=(?[^\\s]+))?', ], }, - { - customType: 'regex', - managerFilePatterns: [ - '/.+\\.toml$/' - ], - matchStrings: [ - '= "(?.+)" # renovate: datasource=(?[a-z-]+) depName=(?[^\\s]+)(?: lookupName=(?[^\\s]+))?(?: versioning=(?[a-z-]+))?(?: extractVersion=(?[^\\s]+))?', - ], - } ], postUpdateOptions: [ 'gomodUpdateImportPaths', diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cb821e6..9d137dc 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -2,7 +2,7 @@ name: ci on: push: - branches: [ main ] + branches: [main] pull_request: jobs: @@ -10,23 +10,29 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - - uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3 + - name: Set up Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 + with: + go-version-file: go.mod - name: Run golangci-lint uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8 with: - install-mode: none + version: v2.4.0 # renovate: datasource=github-releases depName=golangci/golangci-lint args: --timeout 5m test: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - - uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3 + - name: Set up Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 + with: + go-version-file: go.mod - name: Run tests run: go test -v -race -coverpkg=./... -coverprofile=coverage.txt ./... @@ -40,9 +46,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - - uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3 + - name: Set up Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 + with: + go-version-file: go.mod - name: Run go mod tidy run: go mod tidy diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index fcafe52..912615e 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -13,11 +13,13 @@ jobs: id-token: write # To update the deployment status steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: lfs: "true" - - uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3 + - uses: ./.github/actions/setup-mdbook + with: + version: v0.4.52 # renovate: datasource=github-releases depName=rust-lang/mdbook - name: Build Book working-directory: docs @@ -27,7 +29,7 @@ jobs: uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5 - name: Upload artifact - uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4 + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 with: # Upload entire repository path: "docs/book" diff --git a/.github/workflows/mirror.yaml b/.github/workflows/mirror.yaml index 940d149..d7feadb 100644 --- a/.github/workflows/mirror.yaml +++ b/.github/workflows/mirror.yaml @@ -11,7 +11,7 @@ jobs: REMOTE: mirror steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: # Need all to fetch all tags so we can push them fetch-depth: 0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 7da1f8a..bcc947d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -14,16 +14,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - - uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3 - - - name: Prepare ko - run: | - echo "${{ github.token }}" | ko login ghcr.io --username "dummy" --password-stdin - - repo=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') - echo "KO_DOCKER_REPO=ghcr.io/${repo}" - echo "KO_DOCKER_REPO=ghcr.io/${repo}" >> $GITHUB_ENV + - name: Set up Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 + with: + go-version-file: go.mod + - uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9 - run: ko build --bare --tags ${{ github.ref_name }} github.com/apricote/releaser-pleaser/cmd/rp diff --git a/.github/workflows/releaser-pleaser.yaml b/.github/workflows/releaser-pleaser.yaml index 8d1e62b..6e79306 100644 --- a/.github/workflows/releaser-pleaser.yaml +++ b/.github/workflows/releaser-pleaser.yaml @@ -2,7 +2,7 @@ name: releaser-pleaser on: push: - branches: [ main ] + branches: [main] # Using pull_request_target to avoid tainting the actual release PR with code from open feature pull requests pull_request_target: types: @@ -17,7 +17,7 @@ concurrency: group: releaser-pleaser cancel-in-progress: true -permissions: { } +permissions: {} jobs: releaser-pleaser: @@ -25,18 +25,23 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: ref: main - - uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3 + - name: Set up Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 + with: + go-version-file: go.mod # Build container image from current commit and replace image ref in `action.yml` # Without this, any new flags in `action.yml` would break the job in this repository until the new # version is released. But a new version can only be released if this job works. + - uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9 - run: ko build --bare --local --platform linux/amd64 --tags ci github.com/apricote/releaser-pleaser/cmd/rp - - run: "sed -i 's|image: .*$|image: docker://ko.local:ci|g' action.yml" + - run: mkdir -p .github/actions/releaser-pleaser + - run: "sed -i 's|image: .*$|image: docker://ghcr.io/apricote/releaser-pleaser:ci|g' action.yml" # Dogfood the action to make sure it works for users. - name: releaser-pleaser diff --git a/cmd/rp/cmd/root.go b/cmd/rp/cmd/root.go index f2dd180..2799e6d 100644 --- a/cmd/rp/cmd/root.go +++ b/cmd/rp/cmd/root.go @@ -7,23 +7,21 @@ import ( "os/signal" "runtime/debug" "syscall" + "time" + "github.com/lmittmann/tint" "github.com/spf13/cobra" ) -func NewRootCmd() *cobra.Command { - var cmd = &cobra.Command{ - Use: "rp", - Short: "", - Long: ``, - Version: version(), - SilenceUsage: true, // Makes it harder to find the actual error - SilenceErrors: true, // We log manually with slog - } +var logger *slog.Logger - cmd.AddCommand(newRunCommand()) - - return cmd +var rootCmd = &cobra.Command{ + Use: "rp", + Short: "", + Long: ``, + Version: version(), + SilenceUsage: true, // Makes it harder to find the actual error + SilenceErrors: true, // We log manually with slog } func version() string { @@ -68,13 +66,24 @@ func Execute() { // Make sure to stop listening on signals after receiving the first signal to hand control of the signal back // to the runtime. The Go runtime implements a "force shutdown" if the signal is received again. <-ctx.Done() - slog.InfoContext(ctx, "Received shutdown signal, stopping...") + logger.InfoContext(ctx, "Received shutdown signal, stopping...") stop() }() - err := NewRootCmd().ExecuteContext(ctx) + err := rootCmd.ExecuteContext(ctx) if err != nil { - slog.ErrorContext(ctx, err.Error()) + logger.ErrorContext(ctx, err.Error()) os.Exit(1) } } + +func init() { + logger = slog.New( + tint.NewHandler(os.Stderr, &tint.Options{ + Level: slog.LevelDebug, + TimeFormat: time.RFC3339, + }), + ) + + slog.SetDefault(logger) +} diff --git a/cmd/rp/cmd/run.go b/cmd/rp/cmd/run.go index d6bbe4b..a70e915 100644 --- a/cmd/rp/cmd/run.go +++ b/cmd/rp/cmd/run.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "log/slog" "slices" "strings" @@ -13,104 +12,103 @@ import ( "github.com/apricote/releaser-pleaser/internal/forge" "github.com/apricote/releaser-pleaser/internal/forge/github" "github.com/apricote/releaser-pleaser/internal/forge/gitlab" - "github.com/apricote/releaser-pleaser/internal/log" "github.com/apricote/releaser-pleaser/internal/updater" "github.com/apricote/releaser-pleaser/internal/versioning" ) -func newRunCommand() *cobra.Command { - var ( - flagForge string - flagBranch string - flagOwner string - flagRepo string - flagExtraFiles string - flagUpdaters []string +var runCmd = &cobra.Command{ + Use: "run", + RunE: run, +} + +var ( + flagForge string + flagBranch string + flagOwner string + flagRepo string + flagExtraFiles string + flagUpdaters []string +) + +func init() { + rootCmd.AddCommand(runCmd) + runCmd.PersistentFlags().StringVar(&flagForge, "forge", "", "") + runCmd.PersistentFlags().StringVar(&flagBranch, "branch", "main", "") + runCmd.PersistentFlags().StringVar(&flagOwner, "owner", "", "") + runCmd.PersistentFlags().StringVar(&flagRepo, "repo", "", "") + runCmd.PersistentFlags().StringVar(&flagExtraFiles, "extra-files", "", "") + runCmd.PersistentFlags().StringSliceVar(&flagUpdaters, "updaters", []string{}, "") +} + +func run(cmd *cobra.Command, _ []string) error { + ctx := cmd.Context() + + var err error + + logger.DebugContext(ctx, "run called", + "forge", flagForge, + "branch", flagBranch, + "owner", flagOwner, + "repo", flagRepo, ) - var cmd = &cobra.Command{ - Use: "run", - RunE: func(cmd *cobra.Command, _ []string) error { - ctx := cmd.Context() - logger := log.GetLogger(cmd.ErrOrStderr()) + var f forge.Forge - var err error - - logger.DebugContext(ctx, "run called", - "forge", flagForge, - "branch", flagBranch, - "owner", flagOwner, - "repo", flagRepo, - ) - - var f forge.Forge - - forgeOptions := forge.Options{ - Repository: flagRepo, - BaseBranch: flagBranch, - } - - switch flagForge { - case "gitlab": - logger.DebugContext(ctx, "using forge GitLab") - f, err = gitlab.New(logger, &gitlab.Options{ - Options: forgeOptions, - Path: fmt.Sprintf("%s/%s", flagOwner, flagRepo), - }) - if err != nil { - slog.ErrorContext(ctx, "failed to create client", "err", err) - return fmt.Errorf("failed to create gitlab client: %w", err) - } - case "github": - logger.DebugContext(ctx, "using forge GitHub") - f = github.New(logger, &github.Options{ - Options: forgeOptions, - Owner: flagOwner, - Repo: flagRepo, - }) - default: - return fmt.Errorf("unknown --forge: %s", flagForge) - } - - extraFiles := parseExtraFiles(flagExtraFiles) - - updaterNames := parseUpdaters(flagUpdaters) - updaters := []updater.Updater{} - for _, name := range updaterNames { - switch name { - case "generic": - updaters = append(updaters, updater.Generic(extraFiles)) - case "changelog": - updaters = append(updaters, updater.Changelog()) - case "packagejson": - updaters = append(updaters, updater.PackageJson()) - default: - return fmt.Errorf("unknown updater: %s", name) - } - } - - releaserPleaser := rp.New( - f, - logger, - flagBranch, - conventionalcommits.NewParser(logger), - versioning.SemVer, - extraFiles, - updaters, - ) - - return releaserPleaser.Run(ctx) - }, + forgeOptions := forge.Options{ + Repository: flagRepo, + BaseBranch: flagBranch, } - cmd.PersistentFlags().StringVar(&flagForge, "forge", "", "") - cmd.PersistentFlags().StringVar(&flagBranch, "branch", "main", "") - cmd.PersistentFlags().StringVar(&flagOwner, "owner", "", "") - cmd.PersistentFlags().StringVar(&flagRepo, "repo", "", "") - cmd.PersistentFlags().StringVar(&flagExtraFiles, "extra-files", "", "") - cmd.PersistentFlags().StringSliceVar(&flagUpdaters, "updaters", []string{}, "") + switch flagForge { + case "gitlab": + logger.DebugContext(ctx, "using forge GitLab") + f, err = gitlab.New(logger, &gitlab.Options{ + Options: forgeOptions, + Path: fmt.Sprintf("%s/%s", flagOwner, flagRepo), + }) + if err != nil { + logger.ErrorContext(ctx, "failed to create client", "err", err) + return fmt.Errorf("failed to create gitlab client: %w", err) + } + case "github": + logger.DebugContext(ctx, "using forge GitHub") + f = github.New(logger, &github.Options{ + Options: forgeOptions, + Owner: flagOwner, + Repo: flagRepo, + }) + default: + return fmt.Errorf("unknown --forge: %s", flagForge) + } - return cmd + extraFiles := parseExtraFiles(flagExtraFiles) + + updaterNames := parseUpdaters(flagUpdaters) + updaters := []updater.Updater{} + for _, name := range updaterNames { + switch name { + case "generic": + updaters = append(updaters, updater.Generic(extraFiles)) + case "changelog": + updaters = append(updaters, updater.Changelog()) + case "packagejson": + updaters = append(updaters, updater.PackageJson()) + default: + return fmt.Errorf("unknown updater: %s", name) + } + } + + releaserPleaser := rp.New( + f, + logger, + flagBranch, + conventionalcommits.NewParser(logger), + versioning.SemVer, + extraFiles, + updaters, + ) + + return releaserPleaser.Run(ctx) } func parseExtraFiles(input string) []string { diff --git a/cmd/rp/main.go b/cmd/rp/main.go index 734709c..462629b 100644 --- a/cmd/rp/main.go +++ b/cmd/rp/main.go @@ -2,7 +2,6 @@ package main import ( "github.com/apricote/releaser-pleaser/cmd/rp/cmd" - _ "github.com/apricote/releaser-pleaser/internal/log" ) func main() { diff --git a/go.mod b/go.mod index 84390a0..41f54c3 100644 --- a/go.mod +++ b/go.mod @@ -2,13 +2,13 @@ module github.com/apricote/releaser-pleaser go 1.23.2 -toolchain go1.25.0 +toolchain go1.24.6 require ( github.com/blang/semver/v4 v4.0.0 github.com/go-git/go-billy/v5 v5.6.2 github.com/go-git/go-git/v5 v5.16.2 - github.com/google/go-github/v74 v74.0.0 + github.com/google/go-github/v72 v72.0.0 github.com/leodido/go-conventionalcommits v0.12.0 github.com/lmittmann/tint v1.1.2 github.com/spf13/cobra v1.9.1 diff --git a/go.sum b/go.sum index 283db4c..bc93f70 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUv github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-github/v74 v74.0.0 h1:yZcddTUn8DPbj11GxnMrNiAnXH14gNs559AsUpNpPgM= -github.com/google/go-github/v74 v74.0.0/go.mod h1:ubn/YdyftV80VPSI26nSJvaEsTOnsjrxG3o9kJhcyak= +github.com/google/go-github/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM= +github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= diff --git a/internal/forge/github/github.go b/internal/forge/github/github.go index d01e529..f950add 100644 --- a/internal/forge/github/github.go +++ b/internal/forge/github/github.go @@ -12,7 +12,7 @@ import ( "github.com/blang/semver/v4" "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/google/go-github/v74/github" + "github.com/google/go-github/v72/github" "github.com/apricote/releaser-pleaser/internal/forge" "github.com/apricote/releaser-pleaser/internal/git" diff --git a/internal/log/log.go b/internal/log/log.go deleted file mode 100644 index 32219fd..0000000 --- a/internal/log/log.go +++ /dev/null @@ -1,23 +0,0 @@ -package log - -import ( - "io" - "log/slog" - "os" - "time" - - "github.com/lmittmann/tint" -) - -func GetLogger(w io.Writer) *slog.Logger { - return slog.New( - tint.NewHandler(w, &tint.Options{ - Level: slog.LevelDebug, - TimeFormat: time.RFC3339, - }), - ) -} - -func init() { - slog.SetDefault(GetLogger(os.Stderr)) -} diff --git a/mise.toml b/mise.toml deleted file mode 100644 index bc2630d..0000000 --- a/mise.toml +++ /dev/null @@ -1,10 +0,0 @@ -[tools] -go = "1.25.0" -golangci-lint = "v2.4.0" -goreleaser = "v2.9.0" -mdbook = "v0.4.52" # renovate: datasource=github-releases depName=rust-lang/mdbook -ko = "v0.18.0" # renovate: datasource=github-releases depName=ko-build/ko - -[settings] -# Experimental features are needed for the Go backend -experimental = true