Fix the randomize shell selection in Windows shell executor

What does this MR do?

Why was this MR needed?

GetDefaultShell() in common/shell.go iterates over a map[string]Shell:

func GetDefaultShell() string {
    for _, shell := range shells {
        if shell.IsDefault() {
            return shell.GetName()
        }
    }
    panic("no default shell defined")
}

On Windows, both pwsh and powershell return true from IsDefault().

// shells/powershell.go


func (b *PowerShell) IsDefault() bool {
    return runtime.GOOS == OSWindows  // true for both shells, pwsh and powershell
}

Go map iteration order is randomized by the language spec, regardless of insertion order. The init() in shells/powershell.go registers pwsh first, but this has no effect on iteration:

func init() {
    // ...
    common.RegisterShell(WrapShell(&PowerShell{Shell: SNPwsh, EOL: eol}))
    common.RegisterShell(WrapShell(&PowerShell{Shell: SNPowershell, EOL: "\r\n"}))
}

This means GetDefaultShell() can return either pwsh or powershell non-deterministically.

What's the best way to test this MR?

  1. set shell runner without setting shell in [[runners]] config
  2. run job on the runner and make sure the shell in pwsh
  3. repet step 2 couple of times

What are the relevant issue numbers?

#39378 (closed)

Merge request reports

Loading