Use global branch filter only on events containing branch info (#659)

- close #581
- delete unused code
- simplify code
- add check to procBuilder to fail on invalid config
This commit is contained in:
6543 2022-01-05 17:54:44 +01:00 committed by GitHub
parent abd3d1d5c3
commit dec0eeeed7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 48 deletions

View file

@ -256,7 +256,6 @@ func run(c *cli.Context) error {
func setupEvilGlobals(c *cli.Context, v store.Store, r remote.Remote) { func setupEvilGlobals(c *cli.Context, v store.Store, r remote.Remote) {
// storage // storage
server.Config.Storage.Files = v server.Config.Storage.Files = v
server.Config.Storage.Config = v
// remote // remote
server.Config.Services.Remote = r server.Config.Services.Remote = r

View file

@ -1,10 +1,6 @@
package yaml package yaml
import ( import (
"io"
"io/ioutil"
"os"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types" "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types"
@ -35,15 +31,6 @@ type (
} }
) )
// Parse parses the configuration from bytes b.
func Parse(r io.Reader) (*Config, error) {
out, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return ParseBytes(out)
}
// ParseBytes parses the configuration from bytes b. // ParseBytes parses the configuration from bytes b.
func ParseBytes(b []byte) (*Config, error) { func ParseBytes(b []byte) (*Config, error) {
out := new(Config) out := new(Config)
@ -61,13 +48,3 @@ func ParseString(s string) (*Config, error) {
[]byte(s), []byte(s),
) )
} }
// ParseFile parses the configuration from path p.
func ParseFile(p string) (*Config, error) {
f, err := os.Open(p)
if err != nil {
return nil, err
}
defer f.Close()
return Parse(f)
}

View file

@ -296,7 +296,7 @@ func PostApproval(c *gin.Context) {
} }
// fetch the build file from the database // fetch the build file from the database
configs, err := server.Config.Storage.Config.ConfigsForBuild(build.ID) configs, err := _store.ConfigsForBuild(build.ID)
if err != nil { if err != nil {
log.Error().Msgf("failure to get build config for %s. %s", repo.FullName, err) log.Error().Msgf("failure to get build config for %s. %s", repo.FullName, err)
_ = c.AbortWithError(404, err) _ = c.AbortWithError(404, err)
@ -426,7 +426,7 @@ func PostBuild(c *gin.Context) {
} }
// fetch the pipeline config from database // fetch the pipeline config from database
configs, err := server.Config.Storage.Config.ConfigsForBuild(build.ID) configs, err := _store.ConfigsForBuild(build.ID)
if err != nil { if err != nil {
log.Error().Msgf("failure to get build config for %s. %s", repo.FullName, err) log.Error().Msgf("failure to get build config for %s. %s", repo.FullName, err)
_ = c.AbortWithError(404, err) _ = c.AbortWithError(404, err)
@ -465,8 +465,7 @@ func PostBuild(c *gin.Context) {
return return
} }
err = persistBuildConfigs(configs, build.ID) if err := persistBuildConfigs(_store, configs, build.ID); err != nil {
if err != nil {
msg := fmt.Sprintf("failure to persist build config for %s.", repo.FullName) msg := fmt.Sprintf("failure to persist build config for %s.", repo.FullName)
log.Error().Err(err).Msg(msg) log.Error().Err(err).Msg(msg)
c.String(http.StatusInternalServerError, msg) c.String(http.StatusInternalServerError, msg)
@ -643,13 +642,13 @@ func updateBuildStatus(ctx context.Context, build *model.Build, repo *model.Repo
return nil return nil
} }
func persistBuildConfigs(configs []*model.Config, buildID int64) error { func persistBuildConfigs(store store.Store, configs []*model.Config, buildID int64) error {
for _, conf := range configs { for _, conf := range configs {
buildConfig := &model.BuildConfig{ buildConfig := &model.BuildConfig{
ConfigID: conf.ID, ConfigID: conf.ID,
BuildID: buildID, BuildID: buildID,
} }
err := server.Config.Storage.Config.BuildConfigCreate(buildConfig) err := store.BuildConfigCreate(buildConfig)
if err != nil { if err != nil {
return err return err
} }

View file

@ -227,7 +227,7 @@ func PostHook(c *gin.Context) {
// persist the build config for historical correctness, restarts, etc // persist the build config for historical correctness, restarts, etc
for _, remoteYamlConfig := range remoteYamlConfigs { for _, remoteYamlConfig := range remoteYamlConfigs {
_, err := findOrPersistPipelineConfig(repo, build, remoteYamlConfig) _, err := findOrPersistPipelineConfig(_store, build, remoteYamlConfig)
if err != nil { if err != nil {
msg := fmt.Sprintf("failure to find or persist pipeline config for %s", repo.FullName) msg := fmt.Sprintf("failure to find or persist pipeline config for %s", repo.FullName)
log.Error().Err(err).Msg(msg) log.Error().Err(err).Msg(msg)
@ -271,16 +271,20 @@ func PostHook(c *gin.Context) {
// TODO: parse yaml once and not for each filter function // TODO: parse yaml once and not for each filter function
func branchFiltered(build *model.Build, remoteYamlConfigs []*remote.FileMeta) (bool, error) { func branchFiltered(build *model.Build, remoteYamlConfigs []*remote.FileMeta) (bool, error) {
log.Trace().Msgf("hook.branchFiltered(): build branch: '%s' build event: '%s' config count: %d", build.Branch, build.Event, len(remoteYamlConfigs)) log.Trace().Msgf("hook.branchFiltered(): build branch: '%s' build event: '%s' config count: %d", build.Branch, build.Event, len(remoteYamlConfigs))
if build.Event == model.EventTag || build.Event == model.EventDeploy {
return false, nil
}
for _, remoteYamlConfig := range remoteYamlConfigs { for _, remoteYamlConfig := range remoteYamlConfigs {
parsedPipelineConfig, err := yaml.ParseString(string(remoteYamlConfig.Data)) parsedPipelineConfig, err := yaml.ParseBytes(remoteYamlConfig.Data)
if err != nil { if err != nil {
log.Trace().Msgf("parse config '%s': %s", remoteYamlConfig.Name, err) log.Trace().Msgf("parse config '%s': %s", remoteYamlConfig.Name, err)
return false, err return false, err
} }
log.Trace().Msgf("config '%s': %#v", remoteYamlConfig.Name, parsedPipelineConfig) log.Trace().Msgf("config '%s': %#v", remoteYamlConfig.Name, parsedPipelineConfig)
if !parsedPipelineConfig.Branches.Match(build.Branch) && build.Event != model.EventTag && build.Event != model.EventDeploy { if parsedPipelineConfig.Branches.Match(build.Branch) {
} else {
return false, nil return false, nil
} }
} }
@ -310,9 +314,9 @@ func zeroSteps(build *model.Build, remoteYamlConfigs []*remote.FileMeta) bool {
return false return false
} }
func findOrPersistPipelineConfig(repo *model.Repo, build *model.Build, remoteYamlConfig *remote.FileMeta) (*model.Config, error) { func findOrPersistPipelineConfig(store store.Store, build *model.Build, remoteYamlConfig *remote.FileMeta) (*model.Config, error) {
sha := shasum(remoteYamlConfig.Data) sha := shasum(remoteYamlConfig.Data)
conf, err := server.Config.Storage.Config.ConfigFindIdentical(build.RepoID, sha) conf, err := store.ConfigFindIdentical(build.RepoID, sha)
if err != nil { if err != nil {
conf = &model.Config{ conf = &model.Config{
RepoID: build.RepoID, RepoID: build.RepoID,
@ -320,10 +324,10 @@ func findOrPersistPipelineConfig(repo *model.Repo, build *model.Build, remoteYam
Hash: sha, Hash: sha,
Name: shared.SanitizePath(remoteYamlConfig.Name), Name: shared.SanitizePath(remoteYamlConfig.Name),
} }
err = server.Config.Storage.Config.ConfigCreate(conf) err = store.ConfigCreate(conf)
if err != nil { if err != nil {
// retry in case we receive two hooks at the same time // retry in case we receive two hooks at the same time
conf, err = server.Config.Storage.Config.ConfigFindIdentical(build.RepoID, sha) conf, err = store.ConfigFindIdentical(build.RepoID, sha)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -334,8 +338,7 @@ func findOrPersistPipelineConfig(repo *model.Repo, build *model.Build, remoteYam
ConfigID: conf.ID, ConfigID: conf.ID,
BuildID: build.ID, BuildID: build.ID,
} }
err = server.Config.Storage.Config.BuildConfigCreate(buildConfig) if err := store.BuildConfigCreate(buildConfig); err != nil {
if err != nil {
return nil, err return nil, err
} }

View file

@ -43,9 +43,8 @@ var Config = struct {
// Repos model.RepoStore // Repos model.RepoStore
// Builds model.BuildStore // Builds model.BuildStore
// Logs model.LogStore // Logs model.LogStore
Config model.ConfigStore Files model.FileStore
Files model.FileStore Procs model.ProcStore
Procs model.ProcStore
// Registries model.RegistryStore // Registries model.RegistryStore
// Secrets model.SecretStore // Secrets model.SecretStore
} }

View file

@ -100,14 +100,13 @@ func (b *ProcBuilder) Build() ([]*BuildItem, error) {
} }
// lint pipeline // lint pipeline
lerr := linter.New( if err := linter.New(
linter.WithTrusted(b.Repo.IsTrusted), linter.WithTrusted(b.Repo.IsTrusted),
).Lint(parsed) ).Lint(parsed); err != nil {
if lerr != nil { return nil, err
return nil, lerr
} }
if !parsed.Branches.Match(b.Curr.Branch) { if !parsed.Branches.Match(b.Curr.Branch) && (b.Curr.Event != model.EventDeploy && b.Curr.Event != model.EventTag) {
proc.State = model.StatusSkipped proc.State = model.StatusSkipped
} }
@ -138,9 +137,24 @@ func (b *ProcBuilder) Build() ([]*BuildItem, error) {
items = filterItemsWithMissingDependencies(items) items = filterItemsWithMissingDependencies(items)
// check if at least one proc can start, if list is not empty
procListContainsItemsToRun(items)
if len(items) > 0 && !procListContainsItemsToRun(items) {
return nil, fmt.Errorf("build has no startpoint")
}
return items, nil return items, nil
} }
func procListContainsItemsToRun(items []*BuildItem) bool {
for i := range items {
if items[i].Proc.State == model.StatusPending {
return true
}
}
return false
}
func filterItemsWithMissingDependencies(items []*BuildItem) []*BuildItem { func filterItemsWithMissingDependencies(items []*BuildItem) []*BuildItem {
itemsToRemove := make([]*BuildItem, 0) itemsToRemove := make([]*BuildItem, 0)