mirror of
https://gitea.com/gitea/runner.git
synced 2026-11-06 23:30:29 +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))
|
||||
return false
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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]",
|
||||
},
|
||||
},
|
||||
{
|
||||
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",
|
||||
steps: [][]string{{"::stop-commands::resume-token", "::add-mask::kept", "::set-output name=a::b", "::RESUME-TOKEN::", "::add-mask::masked"}},
|
||||
log: []string{"::stop-commands::resume-token", "::add-mask::kept", "::set-output name=a::b", "::RESUME-TOKEN::"},
|
||||
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", " \t::GrOuP::kept%3B", "prefix ##[EnDgRoUp]", "::RESUME-TOKEN::"},
|
||||
masks: []string{"resume-token", "masked"},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -136,7 +136,7 @@ func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.
|
||||
followSymlink := false
|
||||
|
||||
for i, p := range v {
|
||||
s := p.String()
|
||||
s := exprparser.CoerceToString(p)
|
||||
if i == 0 && strings.HasPrefix(s, "--") {
|
||||
if strings.EqualFold(s, "--follow-symbolic-links") {
|
||||
followSymlink = true
|
||||
|
||||
@@ -178,7 +178,7 @@ func (c *hashFilesContainer) ReplaceLogWriter(stdout, stderr io.Writer) (io.Writ
|
||||
}
|
||||
|
||||
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 {
|
||||
name 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: "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: "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: "node missing", execErr: fmt.Errorf("wrapped: %w", container.ExitCodeError(127)), 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.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, 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, workdir)
|
||||
return func(_ctx context.Context) error {
|
||||
@@ -223,7 +223,7 @@ func TestGetHashFilesFunction(t *testing.T) {
|
||||
result, err := getHashFilesFunction(ctx, &RunContext{
|
||||
Config: &Config{Workdir: "/workspace"},
|
||||
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 == "" {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user