mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 11:51:02 +00:00
Move "skip ci" logic into global pipeline conditions (#2216)
... and make custom errors follow std err conventions this fix a 500 response if the whole pipeline is filtered out
This commit is contained in:
parent
2222638b10
commit
a5ef372190
6 changed files with 41 additions and 20 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -16,6 +16,7 @@
|
||||||
"prettier.configPath": "./web/.prettierrc.js",
|
"prettier.configPath": "./web/.prettierrc.js",
|
||||||
"prettier.ignorePath": "./web/.prettierignore",
|
"prettier.ignorePath": "./web/.prettierignore",
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"Curr",
|
||||||
"doublestar",
|
"doublestar",
|
||||||
"multierr"
|
"multierr"
|
||||||
]
|
]
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -168,7 +168,7 @@ test-server-datastore-coverage: ## Test server datastore with coverage report
|
||||||
|
|
||||||
test-ui: ui-dependencies ## Test UI code
|
test-ui: ui-dependencies ## Test UI code
|
||||||
(cd web/; pnpm run lint)
|
(cd web/; pnpm run lint)
|
||||||
(cd web/; pnpm run formatcheck)
|
(cd web/; pnpm run format:check)
|
||||||
(cd web/; pnpm run typecheck)
|
(cd web/; pnpm run typecheck)
|
||||||
(cd web/; pnpm run test)
|
(cd web/; pnpm run test)
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,12 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/antonmedv/expr"
|
"github.com/antonmedv/expr"
|
||||||
"github.com/bmatcuk/doublestar/v4"
|
"github.com/bmatcuk/doublestar/v4"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
@ -29,6 +31,8 @@ import (
|
||||||
yaml_base_types "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types/base"
|
yaml_base_types "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var skipRe = regexp.MustCompile(`\[(?i:ci *skip|skip *ci)\]`)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// When defines a set of runtime constraints.
|
// When defines a set of runtime constraints.
|
||||||
When struct {
|
When struct {
|
||||||
|
@ -78,6 +82,16 @@ func (when *When) IsEmpty() bool {
|
||||||
|
|
||||||
// Returns true if at least one of the internal constraints is true.
|
// Returns true if at least one of the internal constraints is true.
|
||||||
func (when *When) Match(metadata metadata.Metadata, global bool, env map[string]string) (bool, error) {
|
func (when *When) Match(metadata metadata.Metadata, global bool, env map[string]string) (bool, error) {
|
||||||
|
if global {
|
||||||
|
// skip the whole workflow if any case-insensitive combination of the words "skip" and "ci"
|
||||||
|
// wrapped in square brackets appear in the commit message
|
||||||
|
skipMatch := skipRe.FindString(metadata.Curr.Commit.Message)
|
||||||
|
if len(skipMatch) > 0 {
|
||||||
|
log.Debug().Msgf("skip workflow as keyword to do so was detected in commit message '%s'", metadata.Curr.Commit.Message)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, c := range when.Constraints {
|
for _, c := range when.Constraints {
|
||||||
match, err := c.Match(metadata, global, env)
|
match, err := c.Match(metadata, global, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
@ -35,8 +34,6 @@ import (
|
||||||
"github.com/woodpecker-ci/woodpecker/shared/token"
|
"github.com/woodpecker-ci/woodpecker/shared/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
var skipRe = regexp.MustCompile(`\[(?i:ci *skip|skip *ci)\]`)
|
|
||||||
|
|
||||||
// GetQueueInfo
|
// GetQueueInfo
|
||||||
//
|
//
|
||||||
// @Summary Get pipeline queue information
|
// @Summary Get pipeline queue information
|
||||||
|
@ -140,21 +137,6 @@ func PostHook(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Skip if commit message contains skip-ci
|
|
||||||
// TODO: move into global pipeline conditions logic
|
|
||||||
//
|
|
||||||
|
|
||||||
// skip the tmpPipeline if any case-insensitive combination of the words "skip" and "ci"
|
|
||||||
// wrapped in square brackets appear in the commit message
|
|
||||||
skipMatch := skipRe.FindString(tmpPipeline.Message)
|
|
||||||
if len(skipMatch) > 0 {
|
|
||||||
msg := fmt.Sprintf("ignoring hook: %s found in %s", skipMatch, tmpPipeline.Commit)
|
|
||||||
log.Debug().Msg(msg)
|
|
||||||
c.String(http.StatusNoContent, msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 2. Get related repo from store and take repo renaming into account
|
// 2. Get related repo from store and take repo renaming into account
|
||||||
//
|
//
|
||||||
|
|
|
@ -66,7 +66,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline
|
||||||
filtered, parseErr = checkIfFiltered(repo, pipeline, forgeYamlConfigs)
|
filtered, parseErr = checkIfFiltered(repo, pipeline, forgeYamlConfigs)
|
||||||
if parseErr == nil {
|
if parseErr == nil {
|
||||||
if filtered {
|
if filtered {
|
||||||
err := ErrFiltered{Msg: "branch does not match restrictions defined in yaml"}
|
err := ErrFiltered{Msg: "global when filter of all workflows do skip this pipeline"}
|
||||||
log.Debug().Str("repo", repo.FullName).Msgf("%v", err)
|
log.Debug().Str("repo", repo.FullName).Msgf("%v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,14 @@ func (e ErrNotFound) Error() string {
|
||||||
return e.Msg
|
return e.Msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e ErrNotFound) Is(target error) bool {
|
||||||
|
_, ok := target.(ErrNotFound) //nolint:errorlint
|
||||||
|
if !ok {
|
||||||
|
_, ok = target.(*ErrNotFound) //nolint:errorlint
|
||||||
|
}
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
type ErrBadRequest struct {
|
type ErrBadRequest struct {
|
||||||
Msg string
|
Msg string
|
||||||
}
|
}
|
||||||
|
@ -30,6 +38,14 @@ func (e ErrBadRequest) Error() string {
|
||||||
return e.Msg
|
return e.Msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e ErrBadRequest) Is(target error) bool {
|
||||||
|
_, ok := target.(ErrBadRequest) //nolint:errorlint
|
||||||
|
if !ok {
|
||||||
|
_, ok = target.(*ErrBadRequest) //nolint:errorlint
|
||||||
|
}
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
type ErrFiltered struct {
|
type ErrFiltered struct {
|
||||||
Msg string
|
Msg string
|
||||||
}
|
}
|
||||||
|
@ -37,3 +53,11 @@ type ErrFiltered struct {
|
||||||
func (e ErrFiltered) Error() string {
|
func (e ErrFiltered) Error() string {
|
||||||
return "ignoring hook: " + e.Msg
|
return "ignoring hook: " + e.Msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *ErrFiltered) Is(target error) bool {
|
||||||
|
_, ok := target.(ErrFiltered) //nolint:errorlint
|
||||||
|
if !ok {
|
||||||
|
_, ok = target.(*ErrFiltered) //nolint:errorlint
|
||||||
|
}
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue