diff --git a/docker-compose.build.yml b/docker-compose.build.yml index e71b772..f2891be 100644 --- a/docker-compose.build.yml +++ b/docker-compose.build.yml @@ -52,3 +52,11 @@ services: - "./windows.ltsc2022:c:\\app" working_dir: "c:\\app" entrypoint: ["pwsh", "-file", "scripts/run-tests.ps1"] + + windows.ltsc2025: + build: windows.ltsc2025 + image: docker.packages.octopushq.com/octopusdeploy/worker-tools:${BUILD_NUMBER?err}-windows.ltsc2025 + volumes: + - "./windows.ltsc2025:c:\\app" + working_dir: "c:\\app" + entrypoint: ["pwsh", "-file", "scripts/run-tests.ps1"] diff --git a/windows.ltsc2025/Dockerfile b/windows.ltsc2025/Dockerfile new file mode 100644 index 0000000..d85c425 --- /dev/null +++ b/windows.ltsc2025/Dockerfile @@ -0,0 +1,143 @@ +# escape=` + +FROM mcr.microsoft.com/dotnet/sdk:10.0.300-windowsservercore-ltsc2025 +SHELL ["powershell", "-Command"] + +ARG 7Zip_Version=26.0.0 +ARG Argo_Cli_Version=3.4.2 +ARG Aws_Cli_Version=2.34.53 +ARG Aws_Iam_Authenticator_Version=0.7.17 +ARG Aws_Powershell_Version=5.0.218 +ARG Azure_Cli_Version=2.86.0 +ARG Azure_Powershell_Version=15.6.1 +ARG Eks_Cli_Version=0.226.0 +ARG Git_Version=2.54.0 +ARG Google_Cloud_Cli_Version=566.0.0 +ARG Helm_Version=3.20.1 +ARG Java_Jdk_Version=25.0.0.1 +ARG Kubectl_Version=1.35.1 +ARG Kubectl_Versions=1.32.12,1.33.8,1.34.4,1.35.1 +ARG Kubelogin_Version=0.2.17 +ARG Node_Version=24.16.0 +ARG Nuget_Cli_Version=7.6.0 +ARG Octopus_Cli_Legacy_Version=9.1.7 +ARG Octopus_Cli_Version=2.21.1 +ARG Octopus_Client_Version=21.11.2726 +ARG Powershell_Version=7.6.1 +ARG Python_Version=3.14.5 +ARG ScriptCs_Version=0.17.1 +ARG Service_Fabric_Version=10.1.2338.9590 +ARG Service_Fabric_Sdk_Version=7.1.2338 +ARG Terraform_Version=1.15.4 + +# Install Choco +RUN $ProgressPreference = 'SilentlyContinue'; ` + Set-ExecutionPolicy Bypass -Scope Process -Force; ` + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; ` + iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) + +# Disable .NET CLI telemetry +ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 + +# Install JDK +RUN choco install openjdk --allow-empty-checksums --y --no-progress --version $Env:Java_Jdk_Version; ` + Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1; ` + Update-SessionEnvironment + +# Install Azure CLI +RUN choco install azure-cli -y --version $Env:Azure_Cli_Version --no-progress + +# remove az cli warning - https://github.com/Azure/arm-deploy/issues/173 +RUN az config set bicep.use_binary_from_path=false + +# Install the AWS CLI +RUN choco install awscli -y --version $Env:Aws_Cli_Version --no-progress + +# Install the AWS IAM Authenticator +RUN choco install aws-iam-authenticator -y --version $Env:Aws_Iam_Authenticator_Version --no-progress + +# Install AWS PowerShell modules +# https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up-windows.html#ps-installing-awspowershellnetcore +RUN Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force; ` + Install-Module -name AWSPowerShell.NetCore -RequiredVersion $Env:Aws_Powershell_Version -Force + +# Install Azure PowerShell modules +# https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.6.1 +RUN Install-Module -Force -Name Az -AllowClobber -Scope AllUsers -MaximumVersion $Env:Azure_Powershell_Version; ` + Enable-AzureRmAlias -Scope LocalMachine + +# Install NodeJS +RUN choco install nodejs-lts -y --version $Env:Node_Version --no-progress + +# Install kubectl +RUN New-Item -ItemType Directory -Path C:\kubectl -Force | Out-Null; ` + foreach ($v in ($Env:Kubectl_Versions -split ',')) { ` + Invoke-WebRequest "https://dl.k8s.io/release/v$v/bin/windows/amd64/kubectl.exe" -OutFile "C:\kubectl\kubectl-$v.exe"; ` + } ` + Copy-Item "C:\kubectl\kubectl-$($Env:Kubectl_Version).exe" C:\Windows\system32\kubectl.exe; + +# Install Kubelogin +RUN choco install azure-kubelogin --version $Env:Kubelogin_Version --no-progress -y + +# Install helm 3 +RUN Invoke-WebRequest "https://get.helm.sh/helm-v${Env:Helm_Version}-windows-amd64.zip" -OutFile helm.zip; ` + Expand-Archive helm.zip -DestinationPath helm; ` + mv helm\windows-amd64\helm.exe C:\Windows\system32\; ` + Remove-Item -Recurse -Force helm, helm.zip + +# Install Terraform +RUN choco install -y terraform --version $Env:Terraform_Version --no-progress + +# Install python +RUN choco install -y python3 --version $Env:Python_Version --no-progress; ` + Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1; ` + Update-SessionEnvironment + +# Install 7ZIP because gcloud +RUN choco install 7zip -y --version $Env:7Zip_Version --no-progress + +# Install gcloud +RUN choco install gcloudsdk -y --version $Env:Google_Cloud_Cli_Version --no-progress + +# Install gcloud kubectl auth +RUN gcloud components install gke-gcloud-auth-plugin --quiet + +# Install ScriptCS +RUN choco install scriptcs -y --version $Env:ScriptCs_Version --no-progress + +# Install Octopus CLI +RUN choco install octopus-cli -y --version $Env:Octopus_Cli_Version --no-progress + +# Install octo +RUN choco install octopustools -y --version $Env:Octopus_Cli_Legacy_Version --no-progress + +# Install Octopus Client +RUN Install-Package Octopus.Client -source https://www.nuget.org/api/v2 -SkipDependencies -Force -RequiredVersion $Env:Octopus_Client_Version + +# Install eksctl +RUN choco install eksctl -y --version $Env:Eks_Cli_Version --no-progress + +# Install NuGet CLI +RUN choco install nuget.commandline -y --version $Env:Nuget_Cli_Version --no-progress + +# Install Microsoft Service Fabric runtime +RUN Invoke-WebRequest "https://download.microsoft.com/download/b/8/a/b8a2fb98-0ec1-41e5-be98-9d8b5abf7856/MicrosoftServiceFabric.${Env:Service_Fabric_Version}.exe" -OutFile sf-runtime.exe; ` + Start-Process .\sf-runtime.exe -ArgumentList '/accepteula', '/force', '/quiet' -Wait; ` + Remove-Item sf-runtime.exe + +# Install Microsoft Service Fabric SDK +RUN Invoke-WebRequest "https://download.microsoft.com/download/b/8/a/b8a2fb98-0ec1-41e5-be98-9d8b5abf7856/MicrosoftServiceFabricSDK.${Env:Service_Fabric_Sdk_Version}.msi" -OutFile sf-sdk.msi; ` + Start-Process msiexec.exe -ArgumentList '/i', 'sf-sdk.msi', '/quiet', '/norestart' -Wait; ` + Remove-Item sf-sdk.msi + +# PowerShell 7 is provided by the .NET SDK base image (see Powershell_Version ARG) + +# Install Git +RUN choco install git.install --yes --version $Env:Git_Version --no-progress + +# Install Argo CD +RUN choco install argocd-cli --yes --version $Env:Argo_Cli_Version --no-progress + +# Update path for new tools +ADD .\scripts\update_path.cmd C:\update_path.cmd +RUN .\update_path.cmd; diff --git a/windows.ltsc2025/README.md b/windows.ltsc2025/README.md new file mode 100644 index 0000000..567eb02 --- /dev/null +++ b/windows.ltsc2025/README.md @@ -0,0 +1,54 @@ +# Windows WorkerTools + +> Please note that we update this document periodically to match the latest version on DockerHub which is publicly available. +> This does not necessarily match the content of Dockerfiles in this repository, as they may contain changes that are not released yet. + +## Image Name + +`octopusdeploy/worker-tools` + +## Tags + +- `6.0.0-windows.ltsc2025` +- `6.0-windows.ltsc2025` +- `6-windows.ltsc2025` +- `windows.ltsc2025` + +## Digest + +`` + +## Base Image + +`mcr.microsoft.com/windows/servercore:ltsc2025-amd64` + +## Installed Software + +- .NET SDK 10.0.300 +- .NET Framework 4.8.1 +- Argo CD CLI 3.4.2 +- Aws CLI 2.34.53 +- Aws Iam Authenticator 0.7.17 +- Aws PowerShell Modules 5.0.218 +- Azure CLI 2.86.0 +- Azure PowerShell Modules 15.6.1 +- Eksctl 0.226.0 +- Google Cloud CLI 566.0.0 +- Google Cloud GKE auth plugin 566.0.0-0 +- Helm 3.20.1 +- Java Jdk 25.0.0.1 +- Kubectl 1.35.1 (also 1.34.4, 1.33.8, 1.32.12 in C:\kubectl) +- Kubelogin (azure-kubelogin) 0.2.17 +- Microsoft Service Fabric 10.1.2338.9590 +- Microsoft Service Fabric SDK 7.1.2338 +- Node 24.16.0 +- Nuget CLI 7.6.0 +- Octopus CLI Legacy 9.1.7 +- Octopus CLI 2.21.1 +- Octopus Client 21.11.2726 +- Powershell 7.6.1 +- Python 3.14.5 +- ScriptCs 0.17.1 +- Terraform 1.15.4 +- 7Zip 26.0 +- Chocolatey - Latest diff --git a/windows.ltsc2025/Tests.Dockerfile b/windows.ltsc2025/Tests.Dockerfile new file mode 100644 index 0000000..7b83e05 --- /dev/null +++ b/windows.ltsc2025/Tests.Dockerfile @@ -0,0 +1,4 @@ +ARG ContainerUnderTest=octopusdeploy/worker-tools + +FROM ${ContainerUnderTest} +SHELL ["powershell", "-Command"] \ No newline at end of file diff --git a/windows.ltsc2025/scripts/run-tests.ps1 b/windows.ltsc2025/scripts/run-tests.ps1 new file mode 100644 index 0000000..ae30688 --- /dev/null +++ b/windows.ltsc2025/scripts/run-tests.ps1 @@ -0,0 +1,22 @@ +Write-Output "##teamcity[blockOpened name='Pester tests']" + +try { + Install-Module -Name "Pester" -MinimumVersion "5.0.2" -Force + + Import-Module -Name "Pester" + + Set-Location /app/spec + + Write-Output "Running Pester Tests" + $configuration = [PesterConfiguration]::Default + $configuration.TestResult.Enabled = $true + $configuration.TestResult.OutputPath = '/app/spec/PesterTestResults.xml' + $configuration.TestResult.OutputFormat = 'NUnitXml' + $configuration.Run.PassThru = $true + $configuration.Output.Verbosity = "Detailed" + + Invoke-Pester -configuration $configuration +} catch { + exit 1 +} +Write-Output "##teamcity[blockClosed name='Pester tests']" diff --git a/windows.ltsc2025/scripts/update_path.cmd b/windows.ltsc2025/scripts/update_path.cmd new file mode 100644 index 0000000..48b17e4 --- /dev/null +++ b/windows.ltsc2025/scripts/update_path.cmd @@ -0,0 +1,2 @@ +setx /M path "%PATH%;C:\kubectl;C:\Program Files\PackageManagement\NuGet\Packages\Octopus.Client.21.11.2726\lib\net462\Octopus.Client.dll" + diff --git a/windows.ltsc2025/spec/windows.ltsc2025.tests.ps1 b/windows.ltsc2025/spec/windows.ltsc2025.tests.ps1 new file mode 100644 index 0000000..b23e7df --- /dev/null +++ b/windows.ltsc2025/spec/windows.ltsc2025.tests.ps1 @@ -0,0 +1,158 @@ +$ErrorActionPreference = "Continue" + +$pesterModules = @( Get-Module -Name "Pester"); +Write-Host 'Running tests with Pester v'+$($pesterModules[0].Version) + +Describe 'installed dependencies' { + It 'has powershell installed' { + $output = & powershell -command "`$PSVersionTable.PSVersion.ToString()" + $LASTEXITCODE | Should -be 0 + $output | Should -Match '^5\.1\.' + } + + It 'has Octopus.Client installed ' { + $expectedVersion = "21.11.2726" + Test-Path "C:\Program Files\PackageManagement\NuGet\Packages\Octopus.Client.$expectedVersion\lib\net462\Octopus.Client.dll" | Should -Be $true + [Reflection.AssemblyName]::GetAssemblyName("C:\Program Files\PackageManagement\NuGet\Packages\Octopus.Client.$expectedVersion\lib\net462\Octopus.Client.dll").Version.ToString() | Should -Match "$expectedVersion.0" + } + + It 'has dotnet installed' { + dotnet --version | Should -Match '10.0.\d+' + $LASTEXITCODE | Should -be 0 + } + + It 'has .NET Framework 4.8.1 installed' { + $release = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' -Name Release).Release + $release | Should -BeGreaterOrEqual 533320 + } + + It 'has java installed' { + java -version 2>&1 | Select-String -Pattern '25' | Should -BeLike "*25*" + $LASTEXITCODE | Should -be 0 + } + + It 'has az installed' { + $output = (& az version) | convertfrom-json + $output.'azure-cli' | Should -Be '2.86.0' + $LASTEXITCODE | Should -be 0 + } + + It 'has az powershell module installed' { + (Get-Module Az -ListAvailable).Version.ToString() | should -be '15.6.1' + } + + It 'has aws cli installed' { + aws --version 2>&1 | Should -Match '2.34.53' + } + + It 'has aws powershell installed' { + Import-Module AWSPowerShell.NetCore + Get-AWSPowerShellVersion | Should -Match '5.0.218' + } + + # There is no version command for aws-iam-authenticator, so we just check for the installed version. + It 'has aws-iam-authenticator installed' { + Test-Path 'C:\ProgramData\chocolatey\bin\aws-iam-authenticator.exe' | should -be $true + } + + It 'has node installed' { + node --version | Should -Match '24.16.0' + $LASTEXITCODE | Should -be 0 + } + + It 'has kubectl installed' { + kubectl version --client | Select-String -Pattern "1.35.1" | Should -BeLike "Client Version: v1.35.1" + $LASTEXITCODE | Should -be 0 + } + + It 'has multiple kubectl versions available' { + foreach ($v in @('1.32.12', '1.33.8', '1.34.4', '1.35.1')) { + Test-Path "C:\kubectl\kubectl-$v.exe" | Should -Be $true + (& "C:\kubectl\kubectl-$v.exe" version --client) | Select-String -Pattern $v | Should -BeLike "*v$v" + } + } + + It 'has kubelogin installed' { + kubelogin --version | Select-Object -First 1 -Skip 1 | Should -match 'v0.2.17' + $LASTEXITCODE | Should -be 0 + } + + It 'has helm installed' { + helm version | Should -Match '3.20.1' + $LASTEXITCODE | Should -be 0 + } + + # If the terraform version is not the latest, then `terraform version` returns multiple lines and a non-zero return code + It 'has terraform installed' { + terraform version | Select-Object -First 1 | Should -Match '1.15.4' + } + + It 'has python installed' { + python --version | Should -Match '3.14.5' + $LASTEXITCODE | Should -be 0 + } + + It 'has gcloud installed' { + gcloud --version | Select-String -Pattern "566.0.0" | Should -BeLike "Google Cloud SDK 566.0.0" + $LASTEXITCODE | Should -be 0 + } + + # Version follows gcloud SDK bundled plugin; pin loosely to avoid drift. + It 'has gke-gcloud-auth-plugin installed' { + gke-gcloud-auth-plugin --version | Select -First 1 | Should -BeLike "Kubernetes v*" + $LASTEXITCODE | Should -be 0 + } + + It 'has octopus cli installed' { + octopus version | Should -Match '2.21.1' + $LASTEXITCODE | Should -be 0 + } + + It 'has octo installed' { + octo --version | Should -Match '9.1.7' + $LASTEXITCODE | Should -be 0 + } + + It 'has eksctl installed' { + eksctl version | Should -Match '0.226.0' + $LASTEXITCODE | Should -be 0 + } + + It 'has 7zip installed' { + $output = (& "C:\Program Files\7-Zip\7z.exe" --help) -join "`n" + $output | Should -Match '7-Zip 26.00' + $LASTEXITCODE | Should -be 0 + } + + It 'should have installed powershell core' { + $output = & pwsh --version + $LASTEXITCODE | Should -be 0 + $output | Should -Match '^PowerShell 7\.6\.1*' + } + + It 'should have installed git' { + $output = & git --version + $LASTEXITCODE | Should -be 0 + $output | Should -Match '2.54.0' + } + + It 'should have installed argo cli' { + $output = (& argocd version --client) -join "`n" + $LASTEXITCODE | Should -be 0 + $output | Should -Match '3.4.2' + } + + It 'has nuget cli installed' { + $output = & nuget help + $LASTEXITCODE | Should -be 0 + $output | Select-Object -First 1 | Should -Match '7.6.0' + } + + It 'has Microsoft Service Fabric runtime installed' { + (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Service Fabric' -Name FabricVersion).FabricVersion | Should -Match '10.1.2338' + } + + It 'has Microsoft Service Fabric SDK installed' { + Test-Path 'C:\Program Files\Microsoft SDKs\Service Fabric' | Should -Be $true + } +}