From 1996e4589fbc2819b5f1f16a3856f67459cf2ec7 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Sun, 12 Nov 2023 13:11:41 +0100 Subject: [PATCH] Add support for pre-commit-commands Signed-off-by: Knut Ahlers --- assets/git_changerelease.yaml | 12 +++++++++ config.go | 2 ++ go.mod | 1 + go.sum | 12 ++++++--- main.go | 47 +++++++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/assets/git_changerelease.yaml b/assets/git_changerelease.yaml index f14edb7..8c63d0c 100644 --- a/assets/git_changerelease.yaml +++ b/assets/git_changerelease.yaml @@ -23,4 +23,16 @@ match_major: # which will be used to add the tag to. release_commit_message: "prepare release {{.Version}}" +# Commands to run before committing the changelog and adding the tag. +# Therefore these can add content to be included into the release- +# commit. These commands have access to the `TAG_VERSION` variable +# which contains the tag to be applied after the commit. If the +# command specified here is prefixed with a `-` sign, the exit status +# will not fail the release process. If it is not prefixed with a `-` +# a non-zero exit status will terminate the release process. The +# commands will be run from the repostory root, so sub-dirs MUST be +# specified. All commands are run as `bash -ec "..."` so you can use +# bash inside the commands. +pre_commit_commands: [] + ... diff --git a/config.go b/config.go index 08b0d01..1a13040 100644 --- a/config.go +++ b/config.go @@ -19,6 +19,8 @@ type configFile struct { ReleaseCommitMessage string `yaml:"release_commit_message"` IgnoreMessages []string `yaml:"ignore_messages"` + + PreCommitCommands []string `yaml:"pre_commit_commands"` } func loadConfig(configFiles ...string) (*configFile, error) { diff --git a/go.mod b/go.mod index 5e369cb..2553d38 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/Luzifer/git-changerelease go 1.21 require ( + github.com/Luzifer/go_helpers/v2 v2.21.0 github.com/Luzifer/rconfig/v2 v2.4.0 github.com/Masterminds/semver/v3 v3.2.1 github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index 64c7a65..d702645 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/Luzifer/go_helpers/v2 v2.21.0 h1:kR0kdpTkYpkou3qOr2E+sXh0FxG85Mof4BlRhfSB790= +github.com/Luzifer/go_helpers/v2 v2.21.0/go.mod h1:cIIqMPu3NT8/6kHke+03hVznNDLLKVGA74Lz47CWJyA= github.com/Luzifer/rconfig/v2 v2.4.0 h1:MAdymTlExAZ8mx5VG8xOFAtFQSpWBipKYQHPOmYTn9o= github.com/Luzifer/rconfig/v2 v2.4.0/go.mod h1:hWF3ZVSusbYlg5bEvCwalEyUSY+0JPJWUiIu7rBmav8= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= @@ -7,8 +9,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -18,8 +20,9 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -30,5 +33,6 @@ gopkg.in/validator.v2 v2.0.1 h1:xF0KWyGWXm/LM2G1TrEjqOu4pa6coO9AlWSf3msVfDY= gopkg.in/validator.v2 v2.0.1/go.mod h1:lIUZBlB3Im4s/eYp39Ry/wkR02yOPhZ9IwIRBjuPuG8= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 9ed0d21..d28127c 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ import ( "github.com/mitchellh/go-homedir" "github.com/sirupsen/logrus" + "github.com/Luzifer/go_helpers/v2/env" "github.com/Luzifer/rconfig/v2" ) @@ -152,6 +153,12 @@ func main() { logrus.WithError(err).Fatal("writing changelog") } + for _, pc := range config.PreCommitCommands { + if err = runUserCommand(pc, map[string]string{"TAG_VERSION": newVersion.String()}); err != nil { + logrus.WithError(err).WithField("cmd", pc).Fatal("executing pre-commit-commands") + } + } + // Write the tag if err = applyTag("v" + newVersion.String()); err != nil { logrus.WithError(err).Fatal("applying tag") @@ -260,3 +267,43 @@ func renderTemplate(name string, tplSrc []byte, values any) ([]byte, error) { return buf.Bytes(), nil } + +func runUserCommand(command string, extraEnv map[string]string) error { + if len(command) == 0 { + return errors.New("empty command specified") + } + + // Check whether command is prefixed with a minus: If so the error + // will only be logged and is not fatal to the changerelease run + fatal := command[0] != '-' + if !fatal { + command = command[1:] + } + + logrus.WithField("fatal", fatal).WithField("command", command).Trace("running pre_commit_commands") + + envVars := env.ListToMap(os.Environ()) + for k, v := range extraEnv { + envVars[k] = v + } + + wd, err := filenameInGitRoot(".") + if err != nil { + return fmt.Errorf("determining workdir for commands: %w", err) + } + + cmd := exec.Command("/usr/bin/env", "bash", "-ec", command) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + cmd.Env = env.MapToList(envVars) + cmd.Dir = wd + + if err = cmd.Run(); err != nil { + if fatal { + return fmt.Errorf("command had error: %w", err) + } + logrus.WithError(err).WithField("cmd", command).Warn("command had error, marked as non-fatal") + } + + return nil +}