diff --git a/Jenkinsfile b/Jenkinsfile index 92e0387b..d9e5d04f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -3,103 +3,83 @@ pipeline { options { buildDiscarder(logRotator(daysToKeepStr: '10')) - timestamps() } stages { - stage('Build') { - parallel { - stage('Windows') { - agent { - label "docker-windows" + stage('docker-inbound-agent') { + failFast true + matrix { + axes { + axis { + name 'AGENT_TYPE' + values 'linux', 'windows-2019' } - options { - timeout(time: 60, unit: 'MINUTES') - } - environment { - DOCKERHUB_ORGANISATION = "${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}" - } - stages { - stage('Build and Test') { - // This stage is the "CI" and should be run on all code changes triggered by a code change - when { - not { buildingTag() } - } - steps { - powershell '& ./build.ps1 test' - } - post { - always { - junit(allowEmptyResults: true, keepLongStdio: true, testResults: 'target/**/junit-results.xml') - } - } + } + stages { + stage('Main') { + agent { + label env.AGENT_TYPE } - stage('Deploy to DockerHub') { - // This stage is the "CD" and should only be run when a tag triggered the build - when { - buildingTag() - } - steps { - script { - infra.withDockerCredentials { - // TODO: check if this function has the same beahvior in build.ps1 vs make.ps1 - powershell '& ./build.ps1 -PushVersions -VersionTag $env:TAG_NAME publish' - } - } - } + options { + timeout(time: 30, unit: 'MINUTES') } - } - } - stage('Linux') { - agent { - label "docker&&linux" - } - options { - timeout(time: 30, unit: 'MINUTES') - } - environment { - JENKINS_REPO = "${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}/inbound-agent" - } - stages { - stage('Prepare Docker') { - steps { - sh ''' - docker buildx create --use - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - ''' - } + environment { + DOCKERHUB_ORGANISATION = "${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}" } - stage('Build and Test') { - // This stage is the "CI" and should be run on all code changes triggered by a code change - when { - not { buildingTag() } - } - steps { - sh 'make build' - sh 'make test' - // If the tests are passing for Linux AMD64, then we can build all the CPU architectures - sh 'docker buildx bake --file docker-bake.hcl linux' - } - post { - always { - junit(allowEmptyResults: true, keepLongStdio: true, testResults: 'target/*.xml') + stages { + stage('Prepare Docker') { + when { + environment name: 'AGENT_TYPE', value: 'linux' + } + steps { + sh ''' + docker buildx create --use + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + ''' } } - } - stage('Deploy to DockerHub') { - // This stage is the "CD" and should only be run when a tag triggered the build - when { - buildingTag() + stage('Build and Test') { + // This stage is the "CI" and should be run on all code changes triggered by a code change + when { + not { buildingTag() } + } + steps { + script { + if(isUnix()) { + sh 'make build' + sh 'make test' + // If the tests are passing for Linux AMD64, then we can build all the CPU architectures + sh 'docker buildx bake --file docker-bake.hcl linux' + } else { + powershell "& ./build.ps1 test" + } + } + } + post { + always { + junit(allowEmptyResults: true, keepLongStdio: true, testResults: 'target/**/junit-results.xml') + } + } } - steps { - script { - // This function is defined in the jenkins-infra/pipeline-library - infra.withDockerCredentials { - sh ''' - export IMAGE_TAG="${TAG_NAME}" - export ON_TAG=true - docker buildx bake --push --file docker-bake.hcl linux - ''' + stage('Deploy to DockerHub') { + // This stage is the "CD" and should only be run when a tag triggered the build + when { + buildingTag() + } + steps { + script { + infra.withDockerCredentials { + if (isUnix()) { + sh ''' + export IMAGE_TAG="${TAG_NAME}" + export ON_TAG=true + docker buildx bake --push --file docker-bake.hcl linux + ''' + } else { + // TODO: check if this function has the same beahvior in build.ps1 vs make.ps1 + powershell "& ./build.ps1 -PushVersions -VersionTag $env:TAG_NAME publish" + } + } } } } diff --git a/build-windows.yaml b/build-windows.yaml index 7febdfa5..a84aef9f 100644 --- a/build-windows.yaml +++ b/build-windows.yaml @@ -1,29 +1,33 @@ services: - jdk11-nanoserver-1809: - image: jdk11-nanoserver-1809 + jdk11-nanoserver: + image: jdk11-nanoserver-${NANOSERVER_VERSION_NAME} build: context: ./windows/ dockerfile: Dockerfile.nanoserver args: VERSION: ${DOCKER_AGENT_VERSION} - jdk17-nanoserver-1809: - image: jdk17-nanoserver-1809 + WINDOWS_VERSION_TAG: ${NANOSERVER_VERSION_TAG} + jdk17-nanoserver: + image: jdk17-nanoserver-${NANOSERVER_VERSION_NAME} build: context: ./windows/ dockerfile: Dockerfile.nanoserver args: VERSION: ${DOCKER_AGENT_VERSION} - jdk11-windowsservercore-ltsc2019: - image: jdk11-windowsservercore-ltsc2019 + WINDOWS_VERSION_TAG: ${NANOSERVER_VERSION_TAG} + jdk11-windowsservercore: + image: jdk11-windowsservercore-${WINDOWS_VERSION_NAME} build: context: ./windows/ dockerfile: Dockerfile.windowsservercore args: VERSION: ${DOCKER_AGENT_VERSION} - jdk17-windowsservercore-ltsc2019: - image: jdk17-windowsservercore-ltsc2019 + WINDOWS_VERSION_TAG: ${WINDOWS_VERSION_TAG} + jdk17-windowsservercore: + image: jdk17-windowsservercore-${WINDOWS_VERSION_NAME} build: context: ./windows/ dockerfile: Dockerfile.windowsservercore args: VERSION: ${DOCKER_AGENT_VERSION} + WINDOWS_VERSION_TAG: ${WINDOWS_VERSION_TAG} diff --git a/build.ps1 b/build.ps1 index 86f8102a..256a5b38 100644 --- a/build.ps1 +++ b/build.ps1 @@ -10,9 +10,10 @@ Param( # [switch] $DisableEnvProps = $false ) -$ErrorActionPreference = "Stop" +$ErrorActionPreference ='Stop' $Repository = 'inbound-agent' $Organization = 'jenkins' +$AgentType = 'windows-2019' # TODO: not needed? Commented for now, env.props contains DOCKER_AGENT_VERSION in docker-agent # if(!$DisableEnvProps) { @@ -38,6 +39,10 @@ if(![String]::IsNullOrWhiteSpace($env:DOCKER_AGENT_VERSION)) { $DockerAgentVersion = $env:DOCKER_AGENT_VERSION } +if(![String]::IsNullOrWhiteSpace($env:AGENT_TYPE)) { + $AgentType = $env:AGENT_TYPE +} + # Check for required commands Function Test-CommandExists { # From https://devblogs.microsoft.com/scripting/use-a-powershell-function-to-see-if-a-command-exists/ @@ -64,6 +69,15 @@ Function Test-CommandExists { $defaultJdk = '11' $builds = @{} $env:DOCKER_AGENT_VERSION = "$DockerAgentVersion" +$env:WINDOWS_VERSION_NAME = $AgentType.replace('windows-', 'ltsc') +$env:NANOSERVER_VERSION_NAME = $env:WINDOWS_VERSION_NAME +$env:WINDOWS_VERSION_TAG = $env:WINDOWS_VERSION_NAME +$env:NANOSERVER_VERSION_TAG = $env:WINDOWS_VERSION_NAME +# We need to keep the `jdkN-nanoserver-1809` images for now, cf https://github.com/jenkinsci/docker-agent/issues/451 +if ($AgentType -eq 'windows-2019') { + $env:NANOSERVER_VERSION_TAG = 1809 + $env:NANOSERVER_VERSION_NAME = 1809 +} $ProgressPreference = 'SilentlyContinue' # Disable Progress bar for faster downloads Test-CommandExists "docker" @@ -74,7 +88,9 @@ $baseDockerCmd = 'docker-compose --file=build-windows.yaml' $baseDockerBuildCmd = '{0} build --parallel --pull' -f $baseDockerCmd Invoke-Expression "$baseDockerCmd config --services" 2>$null | ForEach-Object { - $image = $_ + $image = '{0}-{1}' -f $_, $env:WINDOWS_VERSION_NAME + # Special case for nanoserver-1809 images + $image = $image.replace('nanoserver-ltsc2019', 'nanoserver-1809') $items = $image.Split("-") # Remove the 'jdk' prefix (3 first characters) $jdkMajorVersion = $items[0].Remove(0,3) @@ -119,7 +135,8 @@ function Test-Image { Write-Host "= TEST: Testing image ${ImageName}:" $env:AGENT_IMAGE = $ImageName - $env:IMAGE_FOLDER = Invoke-Expression "$baseDockerCmd config" 2>$null | yq -r ".services.${ImageName}.build.context" + $serviceName = $ImageName.SubString(0, $ImageName.LastIndexOf('-')) + $env:IMAGE_FOLDER = Invoke-Expression "$baseDockerCmd config" 2>$null | yq -r ".services.${serviceName}.build.context" # TODO: review build number removal (?) # $env:VERSION = "$DockerAgentVersion-$BuildNumber" $env:VERSION = $DockerAgentVersion @@ -175,6 +192,7 @@ if($target -eq "test") { if(![System.String]::IsNullOrWhiteSpace($Build) -and $builds.ContainsKey($Build)) { Test-Image $Build } else { + Write-Host "= TEST: Testing all images" foreach($image in $builds.Keys) { Test-Image $image } diff --git a/tests/inboundAgent.Tests.ps1 b/tests/inboundAgent.Tests.ps1 index dd94bb32..b81695ce 100644 --- a/tests/inboundAgent.Tests.ps1 +++ b/tests/inboundAgent.Tests.ps1 @@ -3,6 +3,7 @@ Import-Module -DisableNameChecking -Force $PSScriptRoot/test_helpers.psm1 $global:AGENT_IMAGE = Get-EnvOrDefault 'AGENT_IMAGE' '' $global:IMAGE_FOLDER = Get-EnvOrDefault 'IMAGE_FOLDER' '' $global:VERSION = Get-EnvOrDefault 'VERSION' '' +$global:WINDOWS_VERSION_TAG = Get-EnvOrDefault 'WINDOWS_VERSION_TAG' '' # TODO: make this name unique for concurency $global:CONTAINERNAME = 'pester-jenkins-inbound-agent-{0}' -f $global:AGENT_IMAGE @@ -20,6 +21,10 @@ $global:WINDOWSVERSION = $items[2] $global:CONTAINERSHELL="powershell.exe" if($global:WINDOWSFLAVOR -eq 'nanoserver') { $global:CONTAINERSHELL = "pwsh.exe" + # Special case for nanoserver-1809 + if($global:WINDOWSVERSION -eq '1809') { + $global:WINDOWS_VERSION_TAG = '1809' + } } @@ -31,7 +36,7 @@ BuildNcatImage Describe "[$global:AGENT_IMAGE] build image" { It 'builds image' { - $exitCode, $stdout, $stderr = Run-Program 'docker' "build --build-arg VERSION=${global:VERSION} --build-arg JAVA_MAJOR_VERSION=${global:JAVA_MAJOR_VERSION} --tag=${global:AGENT_IMAGE} --file ${global:IMAGE_FOLDER}/Dockerfile.${global:WINDOWSFLAVOR} ${global:IMAGE_FOLDER}" + $exitCode, $stdout, $stderr = Run-Program 'docker' "build --build-arg VERSION=${global:VERSION} --build-arg `"WINDOWS_VERSION_TAG=${global:WINDOWS_VERSION_TAG}`" --build-arg JAVA_MAJOR_VERSION=${global:JAVA_MAJOR_VERSION} --tag=${global:AGENT_IMAGE} --file ${global:IMAGE_FOLDER}/Dockerfile.${global:WINDOWSFLAVOR} ${global:IMAGE_FOLDER}" $exitCode | Should -Be 0 } } @@ -122,7 +127,7 @@ Describe "[$global:AGENT_IMAGE] custom build args" { } It 'builds image with arguments' { - $exitCode, $stdout, $stderr = Run-Program 'docker' "build --build-arg VERSION=${ARG_TEST_VERSION} --build-arg JAVA_MAJOR_VERSION=${global:JAVA_MAJOR_VERSION} --tag=${customImageName} --file=${global:IMAGE_FOLDER}/Dockerfile.${global:WINDOWSFLAVOR} ${global:IMAGE_FOLDER}" + $exitCode, $stdout, $stderr = Run-Program 'docker' "build --build-arg VERSION=${ARG_TEST_VERSION} --build-arg `"WINDOWS_VERSION_TAG=${global:WINDOWS_VERSION_TAG}`" --build-arg JAVA_MAJOR_VERSION=${global:JAVA_MAJOR_VERSION} --tag=${customImageName} --file=${global:IMAGE_FOLDER}/Dockerfile.${global:WINDOWSFLAVOR} ${global:IMAGE_FOLDER}" $exitCode | Should -Be 0 $exitCode, $stdout, $stderr = Run-Program 'docker' "run --detach --tty --name $global:CONTAINERNAME $customImageName -Cmd $global:CONTAINERSHELL" diff --git a/updatecli/updatecli.d/docker-agent.yaml b/updatecli/updatecli.d/docker-agent.yaml index f0fe347b..7a12a433 100644 --- a/updatecli/updatecli.d/docker-agent.yaml +++ b/updatecli/updatecli.d/docker-agent.yaml @@ -100,8 +100,8 @@ conditions: tag: '{{source "lastVersion" }}-jdk17-windowsservercore-ltsc2019' targets: - setJdk11AlpineDockerImage: - name: Bump the parent image `jenkins/agent` version on JDK11 Alpine + setAlpineDockerImage: + name: Bump the parent image `jenkins/agent` version on Alpine kind: dockerfile spec: file: linux/Dockerfile.alpine @@ -109,8 +109,8 @@ targets: keyword: ARG matcher: version scmid: default - setJdk11DebianDockerImage: - name: Bump the parent image `jenkins/agent` version on JDK11 Debian + setDebianDockerImage: + name: Bump the parent image `jenkins/agent` version on Debian kind: dockerfile spec: file: linux/Dockerfile.debian @@ -118,8 +118,8 @@ targets: keyword: ARG matcher: version scmid: default - setJdk11WindowsNanoserver1809DockerImage: - name: Bump the parent image `jenkins/agent` version on JDK11 Windows Nanoserver 1809 + setsNanoserverDockerImage: + name: Bump the parent image `jenkins/agent` version on Windows Nanoserver kind: dockerfile spec: file: windows/Dockerfile.nanoserver @@ -127,8 +127,8 @@ targets: keyword: ARG matcher: version scmid: default - setJdk11WindowsServer2019DockerImage: - name: Bump the parent image `jenkins/agent` version on JDK11 Windows Server 2019 + setWindowsServerCoreDockerImage: + name: Bump the parent image `jenkins/agent` version on Windows Server Core kind: dockerfile spec: file: windows/windowsservercore @@ -136,42 +136,6 @@ targets: keyword: ARG matcher: version scmid: default - setJdk17AlpineDockerImage: - name: Bump the parent image `jenkins/agent` version on JDK17 Alpine - kind: dockerfile - spec: - file: linux/Dockerfile.alpine - instruction: - keyword: ARG - matcher: version - scmid: default - setJdk17DebianDockerImage: - name: Bump the parent image `jenkins/agent` version on JDK17 Debian - kind: dockerfile - spec: - file: linux/Dockerfile.debian - instruction: - keyword: ARG - matcher: version - scmid: default - setJdk17WindowsNanoserver1809DockerImage: - name: Bump the parent image `jenkins/agent` version on JDK17 Windows Nanoserver 1809 - kind: dockerfile - spec: - file: windows/windowsservercore - instruction: - keyword: ARG - matcher: version - scmid: default - setJdk17WindowsServer2019DockerImage: - name: Bump the parent image `jenkins/agent` version on JDK17 Windows Server 2019 - kind: dockerfile - spec: - file: windows/windowsservercore-ltsc2019/Dockerfile - instruction: - keyword: ARG - matcher: version - scmid: default setDockerBakeDefaultParentImage: name: Bump the parent image `jenkins/agent` version on the docker-bake.hcl file kind: file @@ -182,11 +146,11 @@ targets: replacepattern: >- variable${1}"DOCKER_AGENT_VERSION"${2}{${3}${4}${5}default${6}= "{{ source "lastVersion" }}" scmid: default - setWindowsMakePwshParentImage: - name: Bump the parent image `jenkins/agent` version on the windows make.ps1 file + setWindowsBuildPwshParentImage: + name: Bump the parent image `jenkins/agent` version on the Windows build.ps1 powershell script kind: file spec: - file: make.ps1 + file: build.ps1 matchpattern: >- \$DockerAgentVersion(.*)=(.*), replacepattern: >- diff --git a/windows/Dockerfile.nanoserver b/windows/Dockerfile.nanoserver index c0af7bc5..4ccdc4f4 100644 --- a/windows/Dockerfile.nanoserver +++ b/windows/Dockerfile.nanoserver @@ -23,7 +23,8 @@ ARG VERSION=3131.vf2b_b_798b_ce99-3 ARG JAVA_MAJOR_VERSION=17 -FROM jenkins/agent:"${VERSION}"-jdk"${JAVA_MAJOR_VERSION}"-nanoserver-1809 +ARG WINDOWS_VERSION_TAG=1809 +FROM jenkins/agent:"${VERSION}"-jdk"${JAVA_MAJOR_VERSION}"-nanoserver-"${WINDOWS_VERSION_TAG}" ARG VERSION=3131.vf2b_b_798b_ce99-3 LABEL Description="This is a base image, which allows connecting Jenkins agents via JNLP protocols on Windows" Vendor="Jenkins Project" Version="$VERSION" diff --git a/windows/Dockerfile.windowsservercore b/windows/Dockerfile.windowsservercore index 3e7cfd72..e1a6a076 100644 --- a/windows/Dockerfile.windowsservercore +++ b/windows/Dockerfile.windowsservercore @@ -23,7 +23,8 @@ ARG VERSION=3131.vf2b_b_798b_ce99-3 ARG JAVA_MAJOR_VERSION=17 -FROM jenkins/agent:"${VERSION}"-jdk"${JAVA_MAJOR_VERSION}"-windowsservercore-ltsc2019 +ARG WINDOWS_VERSION_TAG=ltsc2019 +FROM jenkins/agent:"${VERSION}"-jdk"${JAVA_MAJOR_VERSION}"-windowsservercore-"${WINDOWS_VERSION_TAG}" ARG VERSION=3131.vf2b_b_798b_ce99-3 LABEL Description="This is a base image, which allows connecting Jenkins agents via JNLP protocols on Windows" Vendor="Jenkins Project" Version="$VERSION"