Respect directory option for steps again (#4319)

This commit is contained in:
6543 2024-11-06 23:21:56 +01:00 committed by GitHub
parent c9752bb735
commit bf5405b6cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 96 additions and 61 deletions

View file

@ -18,15 +18,15 @@ import (
"encoding/base64" "encoding/base64"
) )
func GenerateContainerConf(commands []string, goos string) (env map[string]string, entry []string) { func GenerateContainerConf(commands []string, goos, workDir string) (env map[string]string, entry []string) {
env = make(map[string]string) env = make(map[string]string)
if goos == "windows" { if goos == "windows" {
env["CI_SCRIPT"] = base64.StdEncoding.EncodeToString([]byte(generateScriptWindows(commands))) env["CI_SCRIPT"] = base64.StdEncoding.EncodeToString([]byte(generateScriptWindows(commands, workDir)))
env["SHELL"] = "powershell.exe" env["SHELL"] = "powershell.exe"
// cspell:disable-next-line // cspell:disable-next-line
entry = []string{"powershell", "-noprofile", "-noninteractive", "-command", "[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Env:CI_SCRIPT)) | iex"} entry = []string{"powershell", "-noprofile", "-noninteractive", "-command", "[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Env:CI_SCRIPT)) | iex"}
} else { } else {
env["CI_SCRIPT"] = base64.StdEncoding.EncodeToString([]byte(generateScriptPosix(commands))) env["CI_SCRIPT"] = base64.StdEncoding.EncodeToString([]byte(generateScriptPosix(commands, workDir)))
env["SHELL"] = "/bin/sh" env["SHELL"] = "/bin/sh"
entry = []string{"/bin/sh", "-c", "echo $CI_SCRIPT | base64 -d | /bin/sh -e"} entry = []string{"/bin/sh", "-c", "echo $CI_SCRIPT | base64 -d | /bin/sh -e"}
} }

View file

@ -17,16 +17,22 @@ package common
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"text/template"
"al.essio.dev/pkg/shellescape" "al.essio.dev/pkg/shellescape"
) )
// generateScriptPosix is a helper function that generates a step script // generateScriptPosix is a helper function that generates a step script
// for a linux container using the given. // for a linux container using the given.
func generateScriptPosix(commands []string) string { func generateScriptPosix(commands []string, workDir string) string {
var buf bytes.Buffer var buf bytes.Buffer
buf.WriteString(setupScript) if err := setupScriptTmpl.Execute(&buf, map[string]string{
"WorkDir": workDir,
}); err != nil {
// should never happen but well we have an error to trance
return fmt.Sprintf("echo 'failed to generate posix script from commands: %s'; exit 1", err.Error())
}
for _, command := range commands { for _, command := range commands {
buf.WriteString(fmt.Sprintf( buf.WriteString(fmt.Sprintf(
@ -39,9 +45,9 @@ func generateScriptPosix(commands []string) string {
return buf.String() return buf.String()
} }
// setupScript is a helper script this is added to the step script to ensure // setupScriptProto is a helper script this is added to the step script to ensure
// a minimum set of environment variables are set correctly. // a minimum set of environment variables are set correctly.
const setupScript = ` const setupScriptProto = `
if [ -n "$CI_NETRC_MACHINE" ]; then if [ -n "$CI_NETRC_MACHINE" ]; then
cat <<EOF > $HOME/.netrc cat <<EOF > $HOME/.netrc
machine $CI_NETRC_MACHINE machine $CI_NETRC_MACHINE
@ -53,10 +59,12 @@ fi
unset CI_NETRC_USERNAME unset CI_NETRC_USERNAME
unset CI_NETRC_PASSWORD unset CI_NETRC_PASSWORD
unset CI_SCRIPT unset CI_SCRIPT
mkdir -p "$CI_WORKSPACE" mkdir -p "{{.WorkDir}}"
cd "$CI_WORKSPACE" cd "{{.WorkDir}}"
` `
var setupScriptTmpl, _ = template.New("").Parse(setupScriptProto)
// traceScript is a helper script that is added to the step script // traceScript is a helper script that is added to the step script
// to trace a command. // to trace a command.
const traceScript = ` const traceScript = `

View file

@ -16,6 +16,7 @@ package common
import ( import (
"testing" "testing"
"text/template"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -39,8 +40,8 @@ fi
unset CI_NETRC_USERNAME unset CI_NETRC_USERNAME
unset CI_NETRC_PASSWORD unset CI_NETRC_PASSWORD
unset CI_SCRIPT unset CI_SCRIPT
mkdir -p "$CI_WORKSPACE" mkdir -p "/woodpecker/some"
cd "$CI_WORKSPACE" cd "/woodpecker/some"
echo + 'echo ${PATH}' echo + 'echo ${PATH}'
echo ${PATH} echo ${PATH}
@ -54,7 +55,13 @@ go test
}, },
} }
for _, test := range testdata { for _, test := range testdata {
script := generateScriptPosix(test.from) script := generateScriptPosix(test.from, "/woodpecker/some")
assert.EqualValues(t, test.want, script, "Want encoded script for %s", test.from) assert.EqualValues(t, test.want, script, "Want encoded script for %s", test.from)
} }
} }
func TestSetupScriptProtoParse(t *testing.T) {
// just ensure that we have a working `setupScriptTmpl` on runntime
_, err := template.New("").Parse(setupScriptProto)
assert.NoError(t, err)
}

View file

@ -21,16 +21,16 @@ import (
) )
const ( const (
windowsScriptBase64 = "CiRFcnJvckFjdGlvblByZWZlcmVuY2UgPSAnU3RvcCc7CmlmIChbRW52aXJvbm1lbnRdOjpHZXRFbnZpcm9ubWVudFZhcmlhYmxlKCdDSV9XT1JLU1BBQ0UnKSkgeyBpZiAoLW5vdCAoVGVzdC1QYXRoICIkZW52OkNJX1dPUktTUEFDRSIpKSB7IE5ldy1JdGVtIC1QYXRoICIkZW52OkNJX1dPUktTUEFDRSIgLUl0ZW1UeXBlIERpcmVjdG9yeSAtRm9yY2UgfX07CmlmICgtbm90IFtFbnZpcm9ubWVudF06OkdldEVudmlyb25tZW50VmFyaWFibGUoJ0hPTUUnKSkgeyBbRW52aXJvbm1lbnRdOjpTZXRFbnZpcm9ubWVudFZhcmlhYmxlKCdIT01FJywgJ2M6XHJvb3QnKSB9OwppZiAoLW5vdCAoVGVzdC1QYXRoICIkZW52OkhPTUUiKSkgeyBOZXctSXRlbSAtUGF0aCAiJGVudjpIT01FIiAtSXRlbVR5cGUgRGlyZWN0b3J5IC1Gb3JjZSB9OwppZiAoJEVudjpDSV9ORVRSQ19NQUNISU5FKSB7CiRuZXRyYz1bc3RyaW5nXTo6Rm9ybWF0KCJ7MH1cX25ldHJjIiwkRW52OkhPTUUpOwoibWFjaGluZSAkRW52OkNJX05FVFJDX01BQ0hJTkUiID4+ICRuZXRyYzsKImxvZ2luICRFbnY6Q0lfTkVUUkNfVVNFUk5BTUUiID4+ICRuZXRyYzsKInBhc3N3b3JkICRFbnY6Q0lfTkVUUkNfUEFTU1dPUkQiID4+ICRuZXRyYzsKfTsKW0Vudmlyb25tZW50XTo6U2V0RW52aXJvbm1lbnRWYXJpYWJsZSgiQ0lfTkVUUkNfUEFTU1dPUkQiLCRudWxsKTsKW0Vudmlyb25tZW50XTo6U2V0RW52aXJvbm1lbnRWYXJpYWJsZSgiQ0lfU0NSSVBUIiwkbnVsbCk7CmlmIChbRW52aXJvbm1lbnRdOjpHZXRFbnZpcm9ubWVudFZhcmlhYmxlKCdDSV9XT1JLU1BBQ0UnKSkgeyBjZCAiJGVudjpDSV9XT1JLU1BBQ0UiIH07CgpXcml0ZS1PdXRwdXQgKCcrICJlY2hvIGhlbGxvIHdvcmxkIicpOwomIGVjaG8gaGVsbG8gd29ybGQ7IGlmICgkTEFTVEVYSVRDT0RFIC1uZSAwKSB7ZXhpdCAkTEFTVEVYSVRDT0RFfQoK" windowsScriptBase64 = "CiRFcnJvckFjdGlvblByZWZlcmVuY2UgPSAnU3RvcCc7CmlmICgtbm90IChUZXN0LVBhdGggIi93b29kcGVja2VyL3NvbWUiKSkgeyBOZXctSXRlbSAtUGF0aCAiL3dvb2RwZWNrZXIvc29tZSIgLUl0ZW1UeXBlIERpcmVjdG9yeSAtRm9yY2UgfTsKaWYgKC1ub3QgW0Vudmlyb25tZW50XTo6R2V0RW52aXJvbm1lbnRWYXJpYWJsZSgnSE9NRScpKSB7IFtFbnZpcm9ubWVudF06OlNldEVudmlyb25tZW50VmFyaWFibGUoJ0hPTUUnLCAnYzpccm9vdCcpIH07CmlmICgtbm90IChUZXN0LVBhdGggIiRlbnY6SE9NRSIpKSB7IE5ldy1JdGVtIC1QYXRoICIkZW52OkhPTUUiIC1JdGVtVHlwZSBEaXJlY3RvcnkgLUZvcmNlIH07CmlmICgkRW52OkNJX05FVFJDX01BQ0hJTkUpIHsKJG5ldHJjPVtzdHJpbmddOjpGb3JtYXQoInswfVxfbmV0cmMiLCRFbnY6SE9NRSk7CiJtYWNoaW5lICRFbnY6Q0lfTkVUUkNfTUFDSElORSIgPj4gJG5ldHJjOwoibG9naW4gJEVudjpDSV9ORVRSQ19VU0VSTkFNRSIgPj4gJG5ldHJjOwoicGFzc3dvcmQgJEVudjpDSV9ORVRSQ19QQVNTV09SRCIgPj4gJG5ldHJjOwp9OwpbRW52aXJvbm1lbnRdOjpTZXRFbnZpcm9ubWVudFZhcmlhYmxlKCJDSV9ORVRSQ19QQVNTV09SRCIsJG51bGwpOwpbRW52aXJvbm1lbnRdOjpTZXRFbnZpcm9ubWVudFZhcmlhYmxlKCJDSV9TQ1JJUFQiLCRudWxsKTsKY2QgIi93b29kcGVja2VyL3NvbWUiOwoKV3JpdGUtT3V0cHV0ICgnKyAiZWNobyBoZWxsbyB3b3JsZCInKTsKJiBlY2hvIGhlbGxvIHdvcmxkOyBpZiAoJExBU1RFWElUQ09ERSAtbmUgMCkge2V4aXQgJExBU1RFWElUQ09ERX0K"
posixScriptBase64 = "CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiJENJX1dPUktTUEFDRSIKY2QgIiRDSV9XT1JLU1BBQ0UiCgplY2hvICsgJ2VjaG8gaGVsbG8gd29ybGQnCmVjaG8gaGVsbG8gd29ybGQK" posixScriptBase64 = "CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiL3dvb2RwZWNrZXIvc29tZSIKY2QgIi93b29kcGVja2VyL3NvbWUiCgplY2hvICsgJ2VjaG8gaGVsbG8gd29ybGQnCmVjaG8gaGVsbG8gd29ybGQK"
) )
func TestGenerateContainerConf(t *testing.T) { func TestGenerateContainerConf(t *testing.T) {
gotEnv, gotEntry := GenerateContainerConf([]string{"echo hello world"}, "windows") gotEnv, gotEntry := GenerateContainerConf([]string{"echo hello world"}, "windows", "/woodpecker/some")
assert.Equal(t, windowsScriptBase64, gotEnv["CI_SCRIPT"]) assert.Equal(t, windowsScriptBase64, gotEnv["CI_SCRIPT"])
assert.Equal(t, "powershell.exe", gotEnv["SHELL"]) assert.Equal(t, "powershell.exe", gotEnv["SHELL"])
assert.Equal(t, []string{"powershell", "-noprofile", "-noninteractive", "-command", "[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Env:CI_SCRIPT)) | iex"}, gotEntry) assert.Equal(t, []string{"powershell", "-noprofile", "-noninteractive", "-command", "[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Env:CI_SCRIPT)) | iex"}, gotEntry)
gotEnv, gotEntry = GenerateContainerConf([]string{"echo hello world"}, "linux") gotEnv, gotEntry = GenerateContainerConf([]string{"echo hello world"}, "linux", "/woodpecker/some")
assert.Equal(t, posixScriptBase64, gotEnv["CI_SCRIPT"]) assert.Equal(t, posixScriptBase64, gotEnv["CI_SCRIPT"])
assert.Equal(t, "/bin/sh", gotEnv["SHELL"]) assert.Equal(t, "/bin/sh", gotEnv["SHELL"])
assert.Equal(t, []string{"/bin/sh", "-c", "echo $CI_SCRIPT | base64 -d | /bin/sh -e"}, gotEntry) assert.Equal(t, []string{"/bin/sh", "-c", "echo $CI_SCRIPT | base64 -d | /bin/sh -e"}, gotEntry)

View file

@ -18,10 +18,19 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"strings" "strings"
"text/template"
) )
func generateScriptWindows(commands []string) string { func generateScriptWindows(commands []string, workDir string) string {
var buf bytes.Buffer var buf bytes.Buffer
if err := setupScriptWinTmpl.Execute(&buf, map[string]string{
"WorkDir": workDir,
}); err != nil {
// should never happen but well we have an error to trance
return fmt.Sprintf("echo 'failed to generate posix script from commands: %s'; exit 1", err.Error())
}
for _, command := range commands { for _, command := range commands {
escaped := fmt.Sprintf("%q", command) escaped := fmt.Sprintf("%q", command)
escaped = strings.ReplaceAll(escaped, "$", `\$`) escaped = strings.ReplaceAll(escaped, "$", `\$`)
@ -31,16 +40,13 @@ func generateScriptWindows(commands []string) string {
command, command,
)) ))
} }
script := fmt.Sprintf(
setupScriptWin, return buf.String()
buf.String(),
)
return script
} }
const setupScriptWin = ` const setupScriptWinProto = `
$ErrorActionPreference = 'Stop'; $ErrorActionPreference = 'Stop';
if ([Environment]::GetEnvironmentVariable('CI_WORKSPACE')) { if (-not (Test-Path "$env:CI_WORKSPACE")) { New-Item -Path "$env:CI_WORKSPACE" -ItemType Directory -Force }}; if (-not (Test-Path "{{.WorkDir}}")) { New-Item -Path "{{.WorkDir}}" -ItemType Directory -Force };
if (-not [Environment]::GetEnvironmentVariable('HOME')) { [Environment]::SetEnvironmentVariable('HOME', 'c:\root') }; if (-not [Environment]::GetEnvironmentVariable('HOME')) { [Environment]::SetEnvironmentVariable('HOME', 'c:\root') };
if (-not (Test-Path "$env:HOME")) { New-Item -Path "$env:HOME" -ItemType Directory -Force }; if (-not (Test-Path "$env:HOME")) { New-Item -Path "$env:HOME" -ItemType Directory -Force };
if ($Env:CI_NETRC_MACHINE) { if ($Env:CI_NETRC_MACHINE) {
@ -51,10 +57,11 @@ $netrc=[string]::Format("{0}\_netrc",$Env:HOME);
}; };
[Environment]::SetEnvironmentVariable("CI_NETRC_PASSWORD",$null); [Environment]::SetEnvironmentVariable("CI_NETRC_PASSWORD",$null);
[Environment]::SetEnvironmentVariable("CI_SCRIPT",$null); [Environment]::SetEnvironmentVariable("CI_SCRIPT",$null);
if ([Environment]::GetEnvironmentVariable('CI_WORKSPACE')) { cd "$env:CI_WORKSPACE" }; cd "{{.WorkDir}}";
%s
` `
var setupScriptWinTmpl, _ = template.New("").Parse(setupScriptWinProto)
// traceScript is a helper script that is added to the step script // traceScript is a helper script that is added to the step script
// to trace a command. // to trace a command.
const traceScriptWin = ` const traceScriptWin = `

View file

@ -16,6 +16,7 @@ package common
import ( import (
"testing" "testing"
"text/template"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -29,7 +30,7 @@ func TestGenerateScriptWin(t *testing.T) {
from: []string{"echo %PATH%", "go build", "go test"}, from: []string{"echo %PATH%", "go build", "go test"},
want: ` want: `
$ErrorActionPreference = 'Stop'; $ErrorActionPreference = 'Stop';
if ([Environment]::GetEnvironmentVariable('CI_WORKSPACE')) { if (-not (Test-Path "$env:CI_WORKSPACE")) { New-Item -Path "$env:CI_WORKSPACE" -ItemType Directory -Force }}; if (-not (Test-Path "/woodpecker/some")) { New-Item -Path "/woodpecker/some" -ItemType Directory -Force };
if (-not [Environment]::GetEnvironmentVariable('HOME')) { [Environment]::SetEnvironmentVariable('HOME', 'c:\root') }; if (-not [Environment]::GetEnvironmentVariable('HOME')) { [Environment]::SetEnvironmentVariable('HOME', 'c:\root') };
if (-not (Test-Path "$env:HOME")) { New-Item -Path "$env:HOME" -ItemType Directory -Force }; if (-not (Test-Path "$env:HOME")) { New-Item -Path "$env:HOME" -ItemType Directory -Force };
if ($Env:CI_NETRC_MACHINE) { if ($Env:CI_NETRC_MACHINE) {
@ -40,7 +41,7 @@ $netrc=[string]::Format("{0}\_netrc",$Env:HOME);
}; };
[Environment]::SetEnvironmentVariable("CI_NETRC_PASSWORD",$null); [Environment]::SetEnvironmentVariable("CI_NETRC_PASSWORD",$null);
[Environment]::SetEnvironmentVariable("CI_SCRIPT",$null); [Environment]::SetEnvironmentVariable("CI_SCRIPT",$null);
if ([Environment]::GetEnvironmentVariable('CI_WORKSPACE')) { cd "$env:CI_WORKSPACE" }; cd "/woodpecker/some";
Write-Output ('+ "echo %PATH%"'); Write-Output ('+ "echo %PATH%"');
& echo %PATH%; if ($LASTEXITCODE -ne 0) {exit $LASTEXITCODE} & echo %PATH%; if ($LASTEXITCODE -ne 0) {exit $LASTEXITCODE}
@ -50,12 +51,17 @@ Write-Output ('+ "go build"');
Write-Output ('+ "go test"'); Write-Output ('+ "go test"');
& go test; if ($LASTEXITCODE -ne 0) {exit $LASTEXITCODE} & go test; if ($LASTEXITCODE -ne 0) {exit $LASTEXITCODE}
`, `,
}, },
} }
for _, test := range testdata { for _, test := range testdata {
script := generateScriptWindows(test.from) script := generateScriptWindows(test.from, "/woodpecker/some")
assert.EqualValues(t, test.want, script, "Want encoded script for %s", test.from) assert.EqualValues(t, test.want, script, "Want encoded script for %s", test.from)
} }
} }
func TestSetupScriptWinProtoParse(t *testing.T) {
// just ensure that we have a working `setupScriptWinTmpl` on runntime
_, err := template.New("").Parse(setupScriptWinProto)
assert.NoError(t, err)
}

View file

@ -47,11 +47,14 @@ func (e *docker) toConfig(step *types.Step) *container.Config {
maps.Copy(configEnv, step.Environment) maps.Copy(configEnv, step.Environment)
if len(step.Commands) > 0 { if len(step.Commands) > 0 {
env, entry := common.GenerateContainerConf(step.Commands, e.info.OSType) env, entry := common.GenerateContainerConf(step.Commands, e.info.OSType, step.WorkingDir)
for k, v := range env { for k, v := range env {
configEnv[k] = v configEnv[k] = v
} }
config.Entrypoint = entry config.Entrypoint = entry
// step.WorkingDir will be respected by the generated script
config.WorkingDir = step.WorkspaceBase
} }
if len(step.Entrypoint) > 0 { if len(step.Entrypoint) > 0 {
config.Entrypoint = step.Entrypoint config.Entrypoint = step.Entrypoint

View file

@ -185,7 +185,7 @@ func TestToConfigSmall(t *testing.T) {
"wp_uuid": "09238932", "wp_uuid": "09238932",
}, },
Env: []string{ Env: []string{
"CI_SCRIPT=CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiJENJX1dPUktTUEFDRSIKY2QgIiRDSV9XT1JLU1BBQ0UiCgplY2hvICsgJ2dvIHRlc3QnCmdvIHRlc3QK", "CI_SCRIPT=CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiIgpjZCAiIgoKZWNobyArICdnbyB0ZXN0JwpnbyB0ZXN0Cg==",
"SHELL=/bin/sh", "SHELL=/bin/sh",
}, },
}, conf) }, conf)
@ -207,36 +207,37 @@ func TestToConfigFull(t *testing.T) {
} }
conf := engine.toConfig(&backend.Step{ conf := engine.toConfig(&backend.Step{
Name: "test", Name: "test",
UUID: "09238932", UUID: "09238932",
Type: backend.StepTypeCommands, Type: backend.StepTypeCommands,
Image: "golang:1.2.3", Image: "golang:1.2.3",
Pull: true, Pull: true,
Detached: true, Detached: true,
Privileged: true, Privileged: true,
WorkingDir: "/src/abc", WorkingDir: "/src/abc",
Environment: map[string]string{"TAGS": "sqlite"}, WorkspaceBase: "/src",
Commands: []string{"go test", "go vet ./..."}, Environment: map[string]string{"TAGS": "sqlite"},
ExtraHosts: []backend.HostAlias{{Name: "t", IP: "1.2.3.4"}}, Commands: []string{"go test", "go vet ./..."},
Volumes: []string{"/cache:/cache"}, ExtraHosts: []backend.HostAlias{{Name: "t", IP: "1.2.3.4"}},
Tmpfs: []string{"/tmp"}, Volumes: []string{"/cache:/cache"},
Devices: []string{"/dev/sdc"}, Tmpfs: []string{"/tmp"},
Networks: []backend.Conn{{Name: "extra-net", Aliases: []string{"extra.net"}}}, Devices: []string{"/dev/sdc"},
DNS: []string{"9.9.9.9", "8.8.8.8"}, Networks: []backend.Conn{{Name: "extra-net", Aliases: []string{"extra.net"}}},
DNSSearch: nil, DNS: []string{"9.9.9.9", "8.8.8.8"},
OnFailure: true, DNSSearch: nil,
OnSuccess: true, OnFailure: true,
Failure: "fail", OnSuccess: true,
AuthConfig: backend.Auth{Username: "user", Password: "123456"}, Failure: "fail",
NetworkMode: "bridge", AuthConfig: backend.Auth{Username: "user", Password: "123456"},
Ports: []backend.Port{{Number: 21}, {Number: 22}}, NetworkMode: "bridge",
Ports: []backend.Port{{Number: 21}, {Number: 22}},
}) })
assert.NotNil(t, conf) assert.NotNil(t, conf)
sort.Strings(conf.Env) sort.Strings(conf.Env)
assert.EqualValues(t, &container.Config{ assert.EqualValues(t, &container.Config{
Image: "golang:1.2.3", Image: "golang:1.2.3",
WorkingDir: "/src/abc", WorkingDir: "/src",
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
Entrypoint: []string{"/bin/sh", "-c", "echo $CI_SCRIPT | base64 -d | /bin/sh -e"}, Entrypoint: []string{"/bin/sh", "-c", "echo $CI_SCRIPT | base64 -d | /bin/sh -e"},
@ -245,7 +246,7 @@ func TestToConfigFull(t *testing.T) {
"wp_uuid": "09238932", "wp_uuid": "09238932",
}, },
Env: []string{ Env: []string{
"CI_SCRIPT=CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiJENJX1dPUktTUEFDRSIKY2QgIiRDSV9XT1JLU1BBQ0UiCgplY2hvICsgJ2dvIHRlc3QnCmdvIHRlc3QKCmVjaG8gKyAnZ28gdmV0IC4vLi4uJwpnbyB2ZXQgLi8uLi4K", "CI_SCRIPT=CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiL3NyYy9hYmMiCmNkICIvc3JjL2FiYyIKCmVjaG8gKyAnZ28gdGVzdCcKZ28gdGVzdAoKZWNobyArICdnbyB2ZXQgLi8uLi4nCmdvIHZldCAuLy4uLgo=",
"SHELL=/bin/sh", "SHELL=/bin/sh",
"TAGS=sqlite", "TAGS=sqlite",
}, },

View file

@ -183,7 +183,7 @@ func podContainer(step *types.Step, podName, goos string, options BackendOptions
container := v1.Container{ container := v1.Container{
Name: podName, Name: podName,
Image: step.Image, Image: step.Image,
WorkingDir: step.WorkspaceBase, WorkingDir: step.WorkingDir,
Ports: containerPorts(step.Ports), Ports: containerPorts(step.Ports),
SecurityContext: containerSecurityContext(options.SecurityContext, step.Privileged), SecurityContext: containerSecurityContext(options.SecurityContext, step.Privileged),
} }
@ -193,9 +193,12 @@ func podContainer(step *types.Step, podName, goos string, options BackendOptions
} }
if len(step.Commands) > 0 { if len(step.Commands) > 0 {
scriptEnv, command := common.GenerateContainerConf(step.Commands, goos) scriptEnv, command := common.GenerateContainerConf(step.Commands, goos, step.WorkingDir)
container.Command = command container.Command = command
maps.Copy(step.Environment, scriptEnv) maps.Copy(step.Environment, scriptEnv)
// step.WorkingDir will be respected by the generated script
container.WorkingDir = step.WorkspaceBase
} }
if len(step.Entrypoint) > 0 { if len(step.Entrypoint) > 0 {
container.Command = step.Entrypoint container.Command = step.Entrypoint

View file

@ -105,7 +105,7 @@ func TestTinyPod(t *testing.T) {
}, },
{ {
"name": "CI_SCRIPT", "name": "CI_SCRIPT",
"value": "CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiJENJX1dPUktTUEFDRSIKY2QgIiRDSV9XT1JLU1BBQ0UiCgplY2hvICsgJ2dyYWRsZSBidWlsZCcKZ3JhZGxlIGJ1aWxkCg==" "value": "CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiL3dvb2RwZWNrZXIvc3JjIgpjZCAiL3dvb2RwZWNrZXIvc3JjIgoKZWNobyArICdncmFkbGUgYnVpbGQnCmdyYWRsZSBidWlsZAo="
} }
], ],
"resources": {}, "resources": {},
@ -198,7 +198,7 @@ func TestFullPod(t *testing.T) {
}, },
{ {
"name": "CI_SCRIPT", "name": "CI_SCRIPT",
"value": "CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiJENJX1dPUktTUEFDRSIKY2QgIiRDSV9XT1JLU1BBQ0UiCgplY2hvICsgJ2dvIGdldCcKZ28gZ2V0CgplY2hvICsgJ2dvIHRlc3QnCmdvIHRlc3QK" "value": "CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVApta2RpciAtcCAiL3dvb2RwZWNrZXIvc3JjIgpjZCAiL3dvb2RwZWNrZXIvc3JjIgoKZWNobyArICdnbyBnZXQnCmdvIGdldAoKZWNobyArICdnbyB0ZXN0JwpnbyB0ZXN0Cg=="
}, },
{ {
"name": "SHELL", "name": "SHELL",