Compare commits

...

11 commits

Author SHA1 Message Date
852c08ed3d
ci: fix ko settings after using mise (#246) 2025-08-24 17:39:10 +02:00
e1afa22e0a
ci: mdbooks binary is missing (#245) 2025-08-24 17:16:40 +02:00
f077b647e7
ci: separate renovate manager for toml (#244) 2025-08-24 15:07:58 +00:00
44b76e55f8
ci: allow regex manager in toml files for mise (#243) 2025-08-24 14:56:11 +00:00
e83a7c9a23
ci: mise cleanup (#242)
- Renovate does not find the "github:*" dependencies in `mise.toml`
- The `mdbooks` tools was still installed manually with our own action,
  this is removed and mise is used instead.
2025-08-24 14:52:01 +00:00
renovate[bot]
563885899c
deps: update actions/checkout action to v5 (#239)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-24 16:46:49 +02:00
renovate[bot]
16ba2c6b09
deps: update module github.com/google/go-github/v72 to v74 (#241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-24 16:46:16 +02:00
renovate[bot]
e6c8f3f93b
deps: update actions/upload-pages-artifact action to v4 (#240)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-24 16:45:41 +02:00
e6503da93a
refactor(cmd): use factories instead of global cobra command structs (#238)
This enables us to create new commands for e2e tests.
2025-08-24 14:44:05 +00:00
renovate[bot]
5b5b29c0b5
deps: update dependency go to v1.25.0 (#222)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-24 13:50:59 +00:00
c768260a2e
chore: use mise to install all tools in CI and locally (#237)
Makes sure that I have the same versions locally as CI
2025-08-24 15:49:23 +02:00
15 changed files with 179 additions and 171 deletions

View file

@ -1,16 +0,0 @@
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

View file

@ -69,6 +69,15 @@
': (?<currentValue>.+) # renovate: datasource=(?<datasource>[a-z-]+) depName=(?<depName>[^\\s]+)(?: lookupName=(?<packageName>[^\\s]+))?(?: versioning=(?<versioning>[a-z-]+))?(?: extractVersion=(?<extractVersion>[^\\s]+))?',
],
},
{
customType: 'regex',
managerFilePatterns: [
'/.+\\.toml$/'
],
matchStrings: [
'= "(?<currentValue>.+)" # renovate: datasource=(?<datasource>[a-z-]+) depName=(?<depName>[^\\s]+)(?: lookupName=(?<packageName>[^\\s]+))?(?: versioning=(?<versioning>[a-z-]+))?(?: extractVersion=(?<extractVersion>[^\\s]+))?',
],
}
],
postUpdateOptions: [
'gomodUpdateImportPaths',

View file

@ -2,7 +2,7 @@ name: ci
on:
push:
branches: [main]
branches: [ main ]
pull_request:
jobs:
@ -10,29 +10,23 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version-file: go.mod
- uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3
- name: Run golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8
with:
version: v2.4.0 # renovate: datasource=github-releases depName=golangci/golangci-lint
install-mode: none
args: --timeout 5m
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version-file: go.mod
- uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3
- name: Run tests
run: go test -v -race -coverpkg=./... -coverprofile=coverage.txt ./...
@ -46,12 +40,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version-file: go.mod
- uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3
- name: Run go mod tidy
run: go mod tidy

View file

@ -13,13 +13,11 @@ jobs:
id-token: write # To update the deployment status
steps:
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
lfs: "true"
- uses: ./.github/actions/setup-mdbook
with:
version: v0.4.52 # renovate: datasource=github-releases depName=rust-lang/mdbook
- uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3
- name: Build Book
working-directory: docs
@ -29,7 +27,7 @@ jobs:
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
- name: Upload artifact
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4
with:
# Upload entire repository
path: "docs/book"

View file

@ -11,7 +11,7 @@ jobs:
REMOTE: mirror
steps:
- name: Checkout
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
# Need all to fetch all tags so we can push them
fetch-depth: 0

View file

@ -14,12 +14,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version-file: go.mod
- 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
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
- run: ko build --bare --tags ${{ github.ref_name }} github.com/apricote/releaser-pleaser/cmd/rp

View file

@ -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,23 +25,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
ref: main
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version-file: go.mod
- uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3
# 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: mkdir -p .github/actions/releaser-pleaser
- run: "sed -i 's|image: .*$|image: docker://ghcr.io/apricote/releaser-pleaser:ci|g' action.yml"
- run: "sed -i 's|image: .*$|image: docker://ko.local:ci|g' action.yml"
# Dogfood the action to make sure it works for users.
- name: releaser-pleaser

View file

@ -7,21 +7,23 @@ import (
"os/signal"
"runtime/debug"
"syscall"
"time"
"github.com/lmittmann/tint"
"github.com/spf13/cobra"
)
var logger *slog.Logger
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 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
cmd.AddCommand(newRunCommand())
return cmd
}
func version() string {
@ -66,24 +68,13 @@ 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()
logger.InfoContext(ctx, "Received shutdown signal, stopping...")
slog.InfoContext(ctx, "Received shutdown signal, stopping...")
stop()
}()
err := rootCmd.ExecuteContext(ctx)
err := NewRootCmd().ExecuteContext(ctx)
if err != nil {
logger.ErrorContext(ctx, err.Error())
slog.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)
}

View file

@ -2,6 +2,7 @@ package cmd
import (
"fmt"
"log/slog"
"slices"
"strings"
@ -12,103 +13,104 @@ 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"
)
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,
func newRunCommand() *cobra.Command {
var (
flagForge string
flagBranch string
flagOwner string
flagRepo string
flagExtraFiles string
flagUpdaters []string
)
var f forge.Forge
var cmd = &cobra.Command{
Use: "run",
RunE: func(cmd *cobra.Command, _ []string) error {
ctx := cmd.Context()
logger := log.GetLogger(cmd.ErrOrStderr())
forgeOptions := forge.Options{
Repository: flagRepo,
BaseBranch: flagBranch,
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)
},
}
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)
}
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{}, "")
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)
return cmd
}
func parseExtraFiles(input string) []string {

View file

@ -2,6 +2,7 @@ package main
import (
"github.com/apricote/releaser-pleaser/cmd/rp/cmd"
_ "github.com/apricote/releaser-pleaser/internal/log"
)
func main() {

4
go.mod
View file

@ -2,13 +2,13 @@ module github.com/apricote/releaser-pleaser
go 1.23.2
toolchain go1.24.6
toolchain go1.25.0
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/v72 v72.0.0
github.com/google/go-github/v74 v74.0.0
github.com/leodido/go-conventionalcommits v0.12.0
github.com/lmittmann/tint v1.1.2
github.com/spf13/cobra v1.9.1

4
go.sum
View file

@ -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/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM=
github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg=
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-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=

View file

@ -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/v72/github"
"github.com/google/go-github/v74/github"
"github.com/apricote/releaser-pleaser/internal/forge"
"github.com/apricote/releaser-pleaser/internal/git"

23
internal/log/log.go Normal file
View file

@ -0,0 +1,23 @@
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))
}

10
mise.toml Normal file
View file

@ -0,0 +1,10 @@
[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