private/ConvertTo-WpcStepSequenceValues.ps1

function ConvertTo-WpcStepSequenceValues {
    <#
    .SYNOPSIS
        Wraps scalar values of list-only step keys in a one-item list.
    .DESCRIPTION
        A whole-value placeholder that resolves to a one-item list reaches the
        compiler as a scalar. Woodpecker rejects a scalar for these step and
        service keys ("failed to unmarshal Volumes"), so they become sequences.
        Works on the parsed pipeline, so command text is never touched.
    #>

    param(
        [Parameter(Mandatory)]
        [object] $Pipeline
    )

    $sequenceKeys = @('volumes', 'networks', 'devices', 'extra_hosts', 'tmpfs', 'dns', 'dns_search')

    if ($Pipeline -isnot [System.Collections.IDictionary]) {
        return $Pipeline
    }

    foreach ($section in @('steps', 'services')) {
        if (-not (Test-WpcDictionaryKey -Dictionary $Pipeline -Key $section)) {
            continue
        }

        $containers = $Pipeline[$section]
        $containerList = if ($containers -is [System.Collections.IDictionary]) {
            @($containers.Values)
        } else {
            @($containers)
        }

        foreach ($container in $containerList) {
            if ($container -isnot [System.Collections.IDictionary]) {
                continue
            }

            foreach ($key in $sequenceKeys) {
                if (-not (Test-WpcDictionaryKey -Dictionary $container -Key $key)) {
                    continue
                }

                $value = $container[$key]
                if ($value -is [string] -and -not [string]::IsNullOrWhiteSpace($value)) {
                    $container[$key] = [object[]]@($value)
                }
            }
        }
    }

    return $Pipeline
}