pipeline { agent { label 'Win10-BuildMachine' } tools { git 'Default' } parameters { string(name: 'buildPath', defaultValue: 'C:/Jenkins/workspace/Azaion/suite', description: 'Path to folder containing zip builds.') } environment { GOOGLE_DRIVE_FOLDER = 'AzaionSuiteBuilds' RCLONE_CONFIG = 'C:/Program Files/rclone/rclone.conf' LATEST_ZIP_FILENAME = '' // Initial value } stages { stage('Initialize Workspace') { steps { echo 'Initializing workspace on Windows agent...' powershell ''' $uploadDir = "temp_upload" if (-Not (Test-Path $uploadDir)) { New-Item -ItemType Directory -Path $uploadDir | Out-Null } ''' } } stage('Find Latest Zip') { steps { script { echo "Using build path: ${params.buildPath}" def latestZip = '' dir("${params.buildPath}") { def output = powershell(returnStdout: true, script: ''' $pattern = "AzaionSuite*.zip" $zipFiles = Get-ChildItem -Filter $pattern | Sort-Object Name -Descending if ($zipFiles.Count -gt 0) { Write-Output "::SET-ENV::LATEST_ZIP_FILENAME=$($zipFiles[0].Name)" } else { Write-Output "::SET-ENV::LATEST_ZIP_FILENAME=" } ''').trim() echo "PowerShell output: ${output}" def match = (output =~ /::SET-ENV::LATEST_ZIP_FILENAME=(.+)/) if (match) { latestZip = match[0][1] echo "✅ Latest zip file selected: ${latestZip}" } else { echo "⚠️ No zip found." latestZip = 'none' // Handle case where no file is found } } // Directly assign the value to the env variable for use in other stages env.LATEST_ZIP_FILENAME = latestZip } } } stage('Upload If Not Exists & Always Remove Local') { when { expression { return env.LATEST_ZIP_FILENAME != 'none' && env.LATEST_ZIP_FILENAME != '' } } steps { echo "Uploading ${env.LATEST_ZIP_FILENAME} if needed..." powershell """ \$fileName = "${env.LATEST_ZIP_FILENAME}" \$folder = "${GOOGLE_DRIVE_FOLDER}" \$rcloneRemote = "AzaionGoogleDrive:\$folder" \$localPath = "${params.buildPath}/\$fileName" Write-Output "Existing on drive:" \$existing = rclone lsf --files-only \$rcloneRemote Write-Output \$existing if (\$existing -match "^\$fileName\$") { Write-Output "Already exists; skipping upload." } else { Write-Output "Uploading..." rclone copy \$localPath \$rcloneRemote --drive-chunk-size 64M --progress } if (Test-Path \$localPath) { Remove-Item -Force \$localPath Write-Output "Local deleted." } """ } } stage('Cleanup Older Files on Google Drive') { when { expression { return env.LATEST_ZIP_FILENAME != 'none' && env.LATEST_ZIP_FILENAME != '' } } steps { echo "Cleaning up older files..." powershell """ \$folder = "${GOOGLE_DRIVE_FOLDER}" \$files = rclone lsf --files-only AzaionGoogleDrive:\$folder | Where-Object { \$_ -match '^AzaionSuite.*\\.zip\$' } # Build an array of objects with parsed DateTime \$meta = foreach (\$f in \$files) { if (\$f -match 'AzaionSuite\\.Iterative\\.(\\d{8})-(\\d{6})\\.zip') { \$dt = [datetime]::ParseExact(\$matches[1] + \$matches[2], 'yyyyMMddHHmmss', \$null) } elseif (\$f -match 'AzaionSuite1\\.\\d+\\.\\d+\\.\\d+-(\\d{8})-(\\d{6})\\.zip') { \$dt = [datetime]::ParseExact(\$matches[1] + \$matches[2], 'yyyyMMddHHmmss', \$null) } else { # if it doesn't match expected formats, skip continue } [PSCustomObject]@{ Name = \$f; Date = \$dt } } # Sort by Date descending, skip the first 3 (newest), delete the rest \$toDelete = \$meta | Sort-Object Date -Descending | Select-Object -Skip 3 if (\$toDelete) { Write-Output "Deleting:\" \$toDelete | ForEach-Object { Write-Output \$_ .Name; rclone deletefile AzaionGoogleDrive:\$folder/\$($_.Name) } } else { Write-Output "Nothing to delete." } """ } } } post { always { echo 'Cleaning up temp files...' powershell ''' if (Test-Path temp_upload) { Remove-Item -Recurse -Force temp_upload } ''' } failure { echo 'Pipeline failed; check the logs above.' } } }