Skip to content

Commit 0418a6f

Browse files
feat(hooks): initial
1 parent 8c89865 commit 0418a6f

File tree

12 files changed

+1809
-4
lines changed

12 files changed

+1809
-4
lines changed

cmd/semantic-release/main.go

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/Masterminds/semver/v3"
1212
"github.com/go-semantic-release/semantic-release/v2/pkg/config"
1313
"github.com/go-semantic-release/semantic-release/v2/pkg/generator"
14+
"github.com/go-semantic-release/semantic-release/v2/pkg/hooks"
1415
"github.com/go-semantic-release/semantic-release/v2/pkg/plugin/manager"
1516
"github.com/go-semantic-release/semantic-release/v2/pkg/provider"
1617
"github.com/go-semantic-release/semantic-release/v2/pkg/semrel"
@@ -114,17 +115,38 @@ func cliHandler(cmd *cobra.Command, args []string) {
114115
currentSha := ci.GetCurrentSHA()
115116
logger.Println("found current sha: " + currentSha)
116117

118+
hooksExecutor, err := pluginManager.GetChainedHooksExecutor()
119+
exitIfError(err)
120+
121+
hooksNames := hooksExecutor.GetNameVersionPairs()
122+
if len(hooksNames) > 0 {
123+
logger.Printf("hooks plugins: %s\n", strings.Join(hooksNames, ", "))
124+
}
125+
126+
exitIfError(hooksExecutor.Init(conf.HooksOpts))
127+
117128
if !conf.NoCI {
118129
logger.Println("running CI condition...")
119-
config := map[string]string{
130+
conditionConfig := map[string]string{
120131
"token": conf.Token,
121132
"defaultBranch": repoInfo.DefaultBranch,
122133
"private": fmt.Sprintf("%t", repoInfo.Private),
123134
}
124135
for k, v := range conf.CIConditionOpts {
125-
config[k] = v
136+
conditionConfig[k] = v
137+
}
138+
err = ci.RunCondition(conditionConfig)
139+
if err != nil {
140+
herr := hooksExecutor.NoRelease(&hooks.NoReleaseConfig{
141+
Reason: hooks.NoReleaseReason_CONDITION,
142+
Message: err.Error(),
143+
})
144+
if herr != nil {
145+
logger.Printf("there was an error executing the hooks plugins: %s", herr.Error())
146+
}
147+
exitIfError(err, 66)
126148
}
127-
exitIfError(ci.RunCondition(config), 66)
149+
128150
}
129151

130152
logger.Println("getting latest release...")
@@ -158,6 +180,13 @@ func cliHandler(cmd *cobra.Command, args []string) {
158180
logger.Println("calculating new version...")
159181
newVer := semrel.GetNewVersion(conf, commits, release)
160182
if newVer == "" {
183+
herr := hooksExecutor.NoRelease(&hooks.NoReleaseConfig{
184+
Reason: hooks.NoReleaseReason_NO_CHANGE,
185+
Message: "",
186+
})
187+
if herr != nil {
188+
logger.Printf("there was an error executing the hooks plugins: %s", herr.Error())
189+
}
161190
if conf.AllowNoChanges {
162191
logger.Println("no change")
163192
os.Exit(0)
@@ -215,5 +244,20 @@ func cliHandler(cmd *cobra.Command, args []string) {
215244
}
216245
}
217246

247+
herr := hooksExecutor.Success(&hooks.SuccessHookConfig{
248+
Commits: commits,
249+
PrevRelease: release,
250+
NewRelease: &semrel.Release{
251+
SHA: currentSha,
252+
Version: newVer,
253+
},
254+
Changelog: changelogRes,
255+
RepoInfo: repoInfo,
256+
})
257+
258+
if herr != nil {
259+
logger.Printf("there was an error executing the hooks plugins: %s", herr.Error())
260+
}
261+
218262
logger.Println("done.")
219263
}

pkg/config/config.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ type Config struct {
2222
Changelog string
2323
FilesUpdaterPlugins []string
2424
FilesUpdaterOpts map[string]string
25+
HooksPlugins []string
26+
HooksOpts map[string]string
2527
UpdateFiles []string
2628
Match string
2729
VersionFile bool
@@ -89,6 +91,9 @@ func NewConfig(cmd *cobra.Command) (*Config, error) {
8991
fuOpts := mergeOpts(
9092
viper.GetStringMapString("plugins.files-updater.options"),
9193
mustGetStringArray(cmd, "files-updater-opt"))
94+
hoOpts := mergeOpts(
95+
viper.GetStringMapString("plugins.hooks.options"),
96+
mustGetStringArray(cmd, "hooks-opt"))
9297

9398
conf := &Config{
9499
Token: mustGetString(cmd, "token"),
@@ -103,6 +108,8 @@ func NewConfig(cmd *cobra.Command) (*Config, error) {
103108
Changelog: mustGetString(cmd, "changelog"),
104109
FilesUpdaterPlugins: viper.GetStringSlice("plugins.files-updater.names"),
105110
FilesUpdaterOpts: fuOpts,
111+
HooksPlugins: viper.GetStringSlice("plugins.hooks.names"),
112+
HooksOpts: hoOpts,
106113
UpdateFiles: mustGetStringArray(cmd, "update"),
107114
Match: mustGetString(cmd, "match"),
108115
VersionFile: mustGetBool(cmd, "version-file"),
@@ -114,7 +121,6 @@ func NewConfig(cmd *cobra.Command) (*Config, error) {
114121
AllowNoChanges: mustGetBool(cmd, "allow-no-changes"),
115122
MaintainedVersion: viper.GetString("maintainedVersion"),
116123
}
117-
118124
return conf, nil
119125
}
120126
func must(err error) {
@@ -153,6 +159,8 @@ func InitConfig(cmd *cobra.Command) error {
153159
cmd.Flags().String("changelog", "", "creates a changelog file")
154160
cmd.Flags().StringSlice("files-updater", []string{"npm"}, "files-updater plugin names")
155161
cmd.Flags().StringArray("files-updater-opt", []string{}, "options that are passed to the files-updater plugins")
162+
cmd.Flags().StringSlice("hooks", []string{}, "hooks plugin names")
163+
cmd.Flags().StringArray("hooks-opt", []string{}, "options that are passed to the hooks plugins")
156164
cmd.Flags().StringArrayP("update", "u", []string{}, "updates the version of a certain files")
157165
cmd.Flags().String("match", "", "only consider tags matching the given glob(7) pattern, excluding the \"refs/tags/\" prefix.")
158166
cmd.Flags().String("maintained-version", "", "set the maintained version as base for new releases")
@@ -177,6 +185,7 @@ func InitConfig(cmd *cobra.Command) error {
177185
must(viper.BindPFlag("plugins.ci-condition.name", cmd.Flags().Lookup("ci-condition")))
178186
must(viper.BindPFlag("plugins.changelog-generator.name", cmd.Flags().Lookup("changelog-generator")))
179187
must(viper.BindPFlag("plugins.files-updater.names", cmd.Flags().Lookup("files-updater")))
188+
must(viper.BindPFlag("plugins.hooks.names", cmd.Flags().Lookup("hooks")))
180189

181190
if err := viper.ReadInConfig(); err != nil {
182191
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {

pkg/hooks/hooks.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package hooks
2+
3+
import "fmt"
4+
5+
type Hooks interface {
6+
Init(map[string]string) error
7+
Name() string
8+
Version() string
9+
Success(*SuccessHookConfig) error
10+
NoRelease(*NoReleaseConfig) error
11+
}
12+
13+
type ChainedHooksExecutor struct {
14+
HooksChain []Hooks
15+
}
16+
17+
func (c *ChainedHooksExecutor) Success(config *SuccessHookConfig) error {
18+
for _, h := range c.HooksChain {
19+
err := h.Success(config)
20+
if err != nil {
21+
return err
22+
}
23+
}
24+
return nil
25+
}
26+
27+
func (c *ChainedHooksExecutor) NoRelease(config *NoReleaseConfig) error {
28+
for _, h := range c.HooksChain {
29+
err := h.NoRelease(config)
30+
if err != nil {
31+
return err
32+
}
33+
}
34+
return nil
35+
}
36+
37+
func (c *ChainedHooksExecutor) Init(conf map[string]string) error {
38+
for _, h := range c.HooksChain {
39+
err := h.Init(conf)
40+
if err != nil {
41+
return err
42+
}
43+
}
44+
return nil
45+
}
46+
47+
func (c *ChainedHooksExecutor) GetNameVersionPairs() []string {
48+
ret := make([]string, len(c.HooksChain))
49+
for i, h := range c.HooksChain {
50+
ret[i] = fmt.Sprintf("%s@%s", h.Name(), h.Version())
51+
}
52+
return ret
53+
}

0 commit comments

Comments
 (0)