mirror of
https://gitea.com/gitea/runner.git
synced 2026-09-01 00:37:44 +00:00
fix: preserve symlinked Node action entrypoints (#1202)
Node resolves an ESM main to its realpath but leaves `process.argv[1]` as passed. `/var/run/act` reaches the action through the `/var/run` -> `/run` symlink most images ship, so the two disagree and actions comparing them skip their own `run()`. Passing `--preserve-symlinks-main` makes them match. Trade-off: an action whose `runs.main` is a symlink now resolves dependencies from the link's directory rather than the target's. Fixes https://gitea.com/gitea/runner/issues/1201 Co-authored-by: silverwind <me@silverwind.io> Reviewed-on: https://gitea.com/gitea/runner/pulls/1202 Reviewed-by: silverwind <2021+silverwind@noreply.gitea.com> Co-authored-by: bircni <bircni@noreply.gitea.com>
This commit is contained in:
@@ -8,6 +8,10 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -234,7 +238,7 @@ func TestActionRunner(t *testing.T) {
|
||||
return true
|
||||
})
|
||||
|
||||
cm.On("Exec", []string{"node", "/var/run/act/actions/dir/path"}, envMatcher, "", "").Return(func(ctx context.Context) error { return nil })
|
||||
cm.On("Exec", []string{"node", "--preserve-symlinks-main", "/var/run/act/actions/dir/path"}, envMatcher, "", "").Return(func(ctx context.Context) error { return nil })
|
||||
|
||||
tt.step.getRunContext().JobContainer = cm
|
||||
|
||||
@@ -246,6 +250,32 @@ func TestActionRunner(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodeActionCommandPreservesSymlinkedEntrypoint(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("symlink creation requires privileges on Windows")
|
||||
}
|
||||
requireHostTools(t, "node")
|
||||
|
||||
actionDir := t.TempDir()
|
||||
entrypoint := filepath.Join(actionDir, "index.mjs")
|
||||
require.NoError(t, os.WriteFile(entrypoint, []byte(`
|
||||
import {fileURLToPath} from "node:url";
|
||||
const self = fileURLToPath(import.meta.url);
|
||||
if (process.argv[1] !== self) {
|
||||
console.log("argv[1]:", process.argv[1], "import.meta.url:", self);
|
||||
process.exitCode = 1;
|
||||
}
|
||||
`), 0o600))
|
||||
|
||||
symlinkedActionDir := filepath.Join(t.TempDir(), "action")
|
||||
require.NoError(t, os.Symlink(actionDir, symlinkedActionDir))
|
||||
symlinkedEntrypoint := filepath.Join(symlinkedActionDir, "index.mjs")
|
||||
|
||||
args := nodeActionCommand(symlinkedEntrypoint)
|
||||
output, err := exec.CommandContext(t.Context(), args[0], args[1:]...).CombinedOutput()
|
||||
require.NoError(t, err, "%s", output)
|
||||
}
|
||||
|
||||
func TestNewStepContainerDoesNotUseDockerSecrets(t *testing.T) {
|
||||
cm := &containerMock{}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user