mirror of
https://gitea.com/gitea/runner.git
synced 2026-11-08 08:10:30 +00:00
enhance: improve hashFiles coercion and log grouping (#1394)
- Fix `hashFiles()` argument conversion for numbers, booleans, and null to match GitHub expression semantics. - Fix rendering of mixed-case, indented, and prefixed legacy group commands while preserving recognized prefixes and escaping. Reviewed-on: https://gitea.com/gitea/runner/pulls/1394 Reviewed-by: bircni <[email protected]> Co-authored-by: silverwind <[email protected]>
This commit is contained in:
1 parent
c8b16f4792
commit
db76fd5159
4 files changed
+25
-8
No files matched your search
@@ -118,7 +118,11 @@ func (rc *RunContext) commandHandler(ctx context.Context) common.LineHandler {
|
|||||||
rawLogger.Infof("%s", formatAnnotation(command, kvPairs, arg))
|
rawLogger.Infof("%s", formatAnnotation(command, kvPairs, arg))
|
||||||
return false
|
return false
|
||||||
case "group", "endgroup":
|
case "group", "endgroup":
|
||||||
return true
|
if strings.HasPrefix(line, "::"+command+"::") || strings.HasPrefix(line, "##["+command+"]") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
rawLogger.Infof("::%s::%s", command, EscapeCommandData(arg))
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return echoed
|
return echoed
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,10 +240,23 @@ func TestCommandLogWriter(t *testing.T) {
|
|||||||
"::notice::title: m", "::error::x: m", "::error::x:1: m", "::notice::std::vector", "::error::x;y: m]",
|
"::notice::title: m", "::error::x: m", "::error::x:1: m", "::notice::std::vector", "::error::x;y: m]",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "groups normalize unsupported prefixes and preserve recognized prefixes",
|
||||||
|
steps: [][]string{{
|
||||||
|
"::group::a%3Bb%5Dc%250A", "::endgroup::", "##[group]a%3Bb%5Dc%250A", "##[endgroup]",
|
||||||
|
"::GrOuP::a%25b%0Ac", "::EnDgRoUp::", " \t::group::indented", " \t::endgroup::",
|
||||||
|
"prefix ##[GrOuP]a%3Bb%5Dc%253B%0A", "prefix ##[EnDgRoUp]",
|
||||||
|
}},
|
||||||
|
log: []string{
|
||||||
|
"::group::a%3Bb%5Dc%250A", "::endgroup::", "##[group]a%3Bb%5Dc%250A", "##[endgroup]",
|
||||||
|
"::group::a%25b%0Ac", "::endgroup::", "::group::indented", "::endgroup::",
|
||||||
|
"::group::a;b]c%253B%0A", "::endgroup::",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "stop-commands keeps lines verbatim until resumed",
|
name: "stop-commands keeps lines verbatim until resumed",
|
||||||
steps: [][]string{{"::stop-commands::resume-token", "::add-mask::kept", "::set-output name=a::b", "::RESUME-TOKEN::", "::add-mask::masked"}},
|
steps: [][]string{{"::stop-commands::resume-token", "::add-mask::kept", "::set-output name=a::b", " \t::GrOuP::kept%3B", "prefix ##[EnDgRoUp]", "::RESUME-TOKEN::", "::add-mask::masked"}},
|
||||||
log: []string{"::stop-commands::resume-token", "::add-mask::kept", "::set-output name=a::b", "::RESUME-TOKEN::"},
|
log: []string{"::stop-commands::resume-token", "::add-mask::kept", "::set-output name=a::b", " \t::GrOuP::kept%3B", "prefix ##[EnDgRoUp]", "::RESUME-TOKEN::"},
|
||||||
masks: []string{"resume-token", "masked"},
|
masks: []string{"resume-token", "masked"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.
|
|||||||
followSymlink := false
|
followSymlink := false
|
||||||
|
|
||||||
for i, p := range v {
|
for i, p := range v {
|
||||||
s := p.String()
|
s := exprparser.CoerceToString(p)
|
||||||
if i == 0 && strings.HasPrefix(s, "--") {
|
if i == 0 && strings.HasPrefix(s, "--") {
|
||||||
if strings.EqualFold(s, "--follow-symbolic-links") {
|
if strings.EqualFold(s, "--follow-symbolic-links") {
|
||||||
followSymlink = true
|
followSymlink = true
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ func (c *hashFilesContainer) ReplaceLogWriter(stdout, stderr io.Writer) (io.Writ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetHashFilesFunction(t *testing.T) {
|
func TestGetHashFilesFunction(t *testing.T) {
|
||||||
const failureMessage = "hashFiles('dir''file, *.sum') failed. Fail to hash files under directory '/workspace'"
|
const failureMessage = "hashFiles('dir''file, *.sum, 123, true, ') failed. Fail to hash files under directory '/workspace'"
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
name string
|
name string
|
||||||
output string
|
output string
|
||||||
@@ -192,7 +192,7 @@ func TestGetHashFilesFunction(t *testing.T) {
|
|||||||
{name: "success", output: "patterns __OUTPUT__wrong__OUTPUT__ echoed\n__OUTPUT__digest__OUTPUT__", hash: "digest"},
|
{name: "success", output: "patterns __OUTPUT__wrong__OUTPUT__ echoed\n__OUTPUT__digest__OUTPUT__", hash: "digest"},
|
||||||
{name: "no matches", output: "__OUTPUT____OUTPUT__"},
|
{name: "no matches", output: "__OUTPUT____OUTPUT__"},
|
||||||
{name: "script failure", output: "Cannot find: node in PATH\n__OUTPUT__digest__OUTPUT__", execErr: container.ExitCodeError(1), err: failureMessage},
|
{name: "script failure", output: "Cannot find: node in PATH\n__OUTPUT__digest__OUTPUT__", execErr: container.ExitCodeError(1), err: failureMessage},
|
||||||
{name: "timeout", execErr: context.DeadlineExceeded, err: "hashFiles('dir''file, *.sum') couldn't finish within 120 seconds"},
|
{name: "timeout", execErr: context.DeadlineExceeded, err: "hashFiles('dir''file, *.sum, 123, true, ') couldn't finish within 120 seconds"},
|
||||||
{name: "job deadline", execErr: context.DeadlineExceeded, expired: true, err: context.DeadlineExceeded.Error()},
|
{name: "job deadline", execErr: context.DeadlineExceeded, expired: true, err: context.DeadlineExceeded.Error()},
|
||||||
{name: "node missing", execErr: fmt.Errorf("wrapped: %w", container.ExitCodeError(127)), warning: true},
|
{name: "node missing", execErr: fmt.Errorf("wrapped: %w", container.ExitCodeError(127)), warning: true},
|
||||||
{name: "node not executable", execErr: container.ExitCodeError(126), warning: true},
|
{name: "node not executable", execErr: container.ExitCodeError(126), warning: true},
|
||||||
@@ -205,7 +205,7 @@ func TestGetHashFilesFunction(t *testing.T) {
|
|||||||
jobContainer := &hashFilesContainer{stdout: stdout, stderr: stderr, copyErr: test.copyErr}
|
jobContainer := &hashFilesContainer{stdout: stdout, stderr: stderr, copyErr: test.copyErr}
|
||||||
jobContainer.execute = func(command []string, env map[string]string, user, workdir string) common.Executor {
|
jobContainer.execute = func(command []string, env map[string]string, user, workdir string) common.Executor {
|
||||||
assert.Equal(t, []string{"node", "/var/run/act/workflow/hashfiles/index.js"}, command)
|
assert.Equal(t, []string{"node", "/var/run/act/workflow/hashfiles/index.js"}, command)
|
||||||
assert.Equal(t, map[string]string{"patterns": "dir'file\n*.sum", "followSymbolicLinks": "true"}, env)
|
assert.Equal(t, map[string]string{"patterns": "dir'file\n*.sum\n123\ntrue\n", "followSymbolicLinks": "true"}, env)
|
||||||
assert.Empty(t, user)
|
assert.Empty(t, user)
|
||||||
assert.Empty(t, workdir)
|
assert.Empty(t, workdir)
|
||||||
return func(_ctx context.Context) error {
|
return func(_ctx context.Context) error {
|
||||||
@@ -223,7 +223,7 @@ func TestGetHashFilesFunction(t *testing.T) {
|
|||||||
result, err := getHashFilesFunction(ctx, &RunContext{
|
result, err := getHashFilesFunction(ctx, &RunContext{
|
||||||
Config: &Config{Workdir: "/workspace"},
|
Config: &Config{Workdir: "/workspace"},
|
||||||
JobContainer: jobContainer,
|
JobContainer: jobContainer,
|
||||||
})([]reflect.Value{reflect.ValueOf("--follow-symbolic-links"), reflect.ValueOf("dir'file"), reflect.ValueOf("*.sum")})
|
})([]reflect.Value{reflect.ValueOf("--follow-symbolic-links"), reflect.ValueOf("dir'file"), reflect.ValueOf("*.sum"), reflect.ValueOf(float64(123)), reflect.ValueOf(true), {}})
|
||||||
if test.err == "" {
|
if test.err == "" {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in new issue
Block a user