mirror of
https://gitea.com/gitea/act_runner
synced 2026-09-21 19:37:07 +02:00
fix: mount the job workspace above the repository (#1224)
Mount the job workspace volume, or the `bind_workdir` directory, above `<owner>/<repo>` instead of at the repository, like GitHub's work directory. With the repository as a mount point, pnpm 12 puts its store in `node_modules/.pnpm-store` (https://github.com/pnpm/pnpm/pull/13536), so a restored `setup-node` pnpm cache creates `node_modules` before install. Renames into `$RUNNER_WORKSPACE` fail with `EXDEV` and removing the workspace fails with `EBUSY`. Verified against GitHub hosted and container jobs with cold and warm caches, on volume and `bind_workdir` runners, covering checkout, cache, artifacts, github-script, the node, pnpm, bun, python, uv, go, rust, java, gradle, dotnet, ruby and terraform setup actions, docker and Dockerfile actions, buildx, compose via `GITEA_DOCKER_WORKSPACE`, services, host mode, `container.volumes` on the workspace and `exec`. --------- Co-authored-by: bircni <bircni@icloud.com> Reviewed-on: https://gitea.com/gitea/runner/pulls/1224 Co-authored-by: silverwind <2021+silverwind@noreply.gitea.com>
This commit is contained in:
committed by
bircni
co-authored by
bircni
parent
3d116eb0c2
commit
2cc3000369
@@ -18,6 +18,7 @@ import (
|
||||
maps0 "maps"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@@ -255,7 +256,7 @@ func (rc *RunContext) validVolumes() []string {
|
||||
volumes = append(volumes, sharedToolCacheVolume)
|
||||
}
|
||||
if rc.Config.BindWorkdir {
|
||||
volumes = append(volumes, rc.Config.Workdir)
|
||||
volumes = append(volumes, rc.Config.Workdir, rc.workdirMountRoot())
|
||||
}
|
||||
if rc.dockerProxy != nil {
|
||||
volumes = append(volumes, rc.dockerProxy.Socket)
|
||||
@@ -265,6 +266,13 @@ func (rc *RunContext) validVolumes() []string {
|
||||
getDockerDaemonSocketMountPath(rc.containerDaemonSocket()))
|
||||
}
|
||||
|
||||
func (rc *RunContext) workdirMountRoot() string {
|
||||
if rc.Config.PresetGitHubContext != nil {
|
||||
return filepath.Dir(filepath.Dir(rc.Config.Workdir)) // only the daemon presets, its workdir is <parent>/<owner>/<repo>
|
||||
}
|
||||
return rc.Config.Workdir
|
||||
}
|
||||
|
||||
func (rc *RunContext) jobDockerSocket() string {
|
||||
if rc.dockerProxy != nil {
|
||||
return rc.dockerProxy.Socket
|
||||
@@ -359,6 +367,11 @@ func (rc *RunContext) GetBindsAndMounts() ([]string, map[string]string, error) {
|
||||
mounts[name+"-env"] = ext.GetActPath() // runner-internal, never overridable
|
||||
|
||||
if workdir := ext.ToContainerPath(rc.Config.Workdir); !claimed[workdir] {
|
||||
source := rc.workdirMountRoot()
|
||||
target := ext.ToContainerPath(source)
|
||||
if claimed[target] {
|
||||
source, target = rc.Config.Workdir, workdir
|
||||
}
|
||||
if rc.Config.BindWorkdir {
|
||||
bindModifiers := ""
|
||||
if runtime.GOOS == "darwin" {
|
||||
@@ -367,9 +380,9 @@ func (rc *RunContext) GetBindsAndMounts() ([]string, map[string]string, error) {
|
||||
if selinux.GetEnabled() {
|
||||
bindModifiers = ":z"
|
||||
}
|
||||
binds = append(binds, fmt.Sprintf("%s:%s%s", rc.Config.Workdir, workdir, bindModifiers))
|
||||
binds = append(binds, fmt.Sprintf("%s:%s%s", source, target, bindModifiers))
|
||||
} else {
|
||||
mounts[name] = workdir
|
||||
mounts[name] = target
|
||||
}
|
||||
}
|
||||
|
||||
@@ -979,8 +992,12 @@ func (rc *RunContext) captureJobContainerInfo() common.Executor {
|
||||
return nil
|
||||
}
|
||||
rc.jobContainerID = info.ID
|
||||
if source := info.Mounts[rc.githubWorkspace()]; source != "" {
|
||||
rc.Env["GITEA_DOCKER_WORKSPACE"] = source
|
||||
workspace := rc.githubWorkspace()
|
||||
for dir := workspace; dir != "/" && dir != "."; dir = path.Dir(dir) {
|
||||
if source := info.Mounts[dir]; source != "" {
|
||||
rc.Env["GITEA_DOCKER_WORKSPACE"] = path.Join(source, strings.TrimPrefix(workspace, dir))
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user