Write-Warning from a library module does not show as a warning

I have a module that can write out a warning. The code looks like this:

if ($isToVersionAlreadyMade) {
    Write-Warning "Version $toVersion already exists for $packageName in feed '$toFeed'.  NO PROMOTION will happen.  The existing version will be used."
    return;
}

When this writes to the log like this:

##octopus[stdout-warning]
Version 1.9.0 already exists for runtime/shipment-tracking-service in feed ‘application’. NO PROMOTION will happen. The existing version will be used.

Here is a screen shot (just to be clear):

From the added ##octopus[stdout-warning] it looks like octopus sees it was a warning, but the Task Summary screen does not show that there was a warning, and there is no highlighting to make the warning more visible.

How can I get this warning to show up as a warning?

Hi @OctopusSchaff,

Thanks for getting in touch! That certainly doesn’t look like the correct expected behavior. I ran through a couple attempts to reproduce this, however the warning is treated as a warning and the task summary correctly highlights it in yellow to make it stand out. Could you let me know which version of Octopus are you currently running?

Best regards,

Kenny

Glad to hear it is not the normal behavior.

I am running Octopus Deploy 2020.6.4688

Hi @OctopusSchaff ,

Thanks for following up! Strangely I still haven’t had any luck reproducing this behavior, and I can’t see any changes between these versions that might explain this difference in behavior. Would you be willing to send the full code block you have in your module so I can run through a perfectly accurate test? Feel free to mark this thread as private, or email it to support@octopus.com if it’s in any way sensitive.

I look forward to getting to the bottom of this one!

Best regards,

Kenny

This is the full code of the module:

function PromoteContainerImage() {

	param (
		[string] $packageName = $(throw "-packageName is required.  This is the namespace and image name.  For example: library/my-container-image"),
		[string] $fromFeed = $(throw "-fromFeed is required"),
		[string] $toFeed = $(throw "-toFeed is required"),
		[string] $fromVersion = $(throw "-fromVersion is required.  This is the current tag on the container in the fromFeed."),        
		[string] $comments = "Promoted by automation",
		[string] $apiKey = $(throw "-apiKey is required"),
		[string] $progetBaseUrl = $(throw "-progetBaseUrl is required")
	)
	
	$toVersion =  $fromVersion -replace '(\d+\.\d+\.\d+).*', '$1'

	# Check to see if the pre-release version has already been promoted or if the release version has already been made.
	$isToVersionAlreadyMade = CheckIfImageExists $packageName $toFeed $toVersion $apiKey $progetBaseUrl
	$isFromVersionAlreadyPromoted = CheckIfImageExists $packageName $toFeed $fromVersion $apiKey $progetBaseUrl

	if ($isToVersionAlreadyMade) {
		Write-Warning "Version $toVersion already exists for $packageName in feed '$toFeed'.  NO PROMOTION will happen.  The existing version will be used."
		return;
	}
	if ($isFromVersionAlreadyPromoted) {
		Write-Warning "Version $fromVersion already exists for $packageName in feed '$toFeed'.  A re-promotion will be attempted."    
	}


	Write-Host "Promoting $packageName from $fromVersion to $toVersion.  Copying from the '$fromFeed' Docker Feed to the '$toFeed' Docker Feed."

	$postBody = @{
		packageName="$packageName";
		groupName="";
		version="$fromVersion";
		fromFeed="$fromFeed";
		toFeed="$toFeed";
		comments="$comments"
	} 
	# Promote the Container Image
	$promoteResponse = Invoke-WebRequest -Uri "$progetBaseUrl/api/promotions/promote" -Method POST -Body $postBody -Headers @{"X-ApiKey"="$apiKey"}
	Write-Host "Promotion call returned a status of: $($promoteResponse.BaseResponse.StatusCode)"

	Try {
		# Retag the container image by downloading the manifest and then re-uploading it as the new version
		$manifestResponse = Invoke-WebRequest -Uri "$progetBaseUrl/v2/$toFeed/$packageName/manifests/$fromVersion" -Method GET -Headers @{"X-ApiKey"="$apiKey";"accept"="application/vnd.docker.distribution.manifest.v2+json"}
		Write-Host "Get Manifest call returned a status of: $($manifestResponse.BaseResponse.StatusCode)"
		
		$retagResponse = Invoke-WebRequest -Uri "$progetBaseUrl/v2/$toFeed/$packageName/manifests/$toVersion" -Method PUT -Body $manifestResponse.ToString() -Headers @{"X-ApiKey"="$apiKey";"content-type"="application/vnd.docker.distribution.manifest.v2+json"}
		Write-Host "Add Tag call returned a status of: $($retagResponse.BaseResponse.StatusCode)"
	} Catch {        
		if($_.ErrorDetails.Message) {
			Write-Error "Failed to retag the image $($_.ErrorDetails.Message)"
		} else {
			Write-Error "Failed to retag the image $_"
		}
	}
}

function CheckIfImageExists(){

	param (
		[string] $packageName = $(throw "-packageName is required.  This is the namespace and image name.  For example: library/my-container-image"),
		[string] $feed = $(throw "-feed is required"),
		[string] $version = $(throw "-version is required."),
		[string] $apiKey = $(throw "-apiKey is required"),
		[string] $progetBaseUrl = $(throw "-progetBaseUrl is required")
	)

	Try {
		# Retag the container image by downloading the manifest and then re-uploading it as the new version
		$manifestResponse = Invoke-WebRequest -Uri "$progetBaseUrl/v2/$feed/$packageName/manifests/$version" -Method GET -Headers @{"X-ApiKey"="$apiKey";"accept"="application/vnd.docker.distribution.manifest.v2+json"}
		if ($manifestResponse.BaseResponse.StatusCode -eq 'OK') {
			return $true
		} else {
			Write-Error "Check 'if image exits' returned an status code: $($manifestResponse.BaseResponse.StatusCode)"
		}
	} Catch {        
		if($_.ErrorDetails.Message -and $_.ErrorDetails.Message -match 'MANIFEST_UNKNOWN') {
			return $false    
		} else {
			if($_.ErrorDetails.Message) {
				Write-Error "Check 'if image exits' returned an unexpected result: $($_.ErrorDetails.Message)"
			} else {
				Write-Error "Check 'if image exits' returned an unexpected result: $_"
			}
		}
	}
}

Hi,

Thanks for following up and sharing your code. That totally looks fine, though I’m still unable to reproduce this, so I’m left scratching my head. Could you let me know which version of Octopus you’re currently running (my tests so far have been in 2021.1.7274)? Would you be willing to enable verbose logging and send a resulting task log where this issue is occurring?

I look forward to hearing back!

Best regards,

Kenny

I am currently running version: 2020.6.4688

I enabled the two settings you indicated. It now gives this warning when I run a deploy:

I sent the deployment log to support@octopus.com.

I am staring to notice this issue being more widespread. (I am getting similar issues from a Runbook I am working on that is using Write-Verbose)

Kenneth,

I just wanted to let you know that we updated to Octopus Deploy Version 2021.1 (Build 7316) today and this issue is still present.

I can’t seem to nail down why one script will do it and another will not. (Though, it is usually in my most complex scripts.)

OK, I dug into this some more and here is a stab and some steps to reproduce this issue:

  1. Create a new Project (Mine is in my second space and was called (Testing Logging Bug")
  2. Create a new RunBook (Mine was called “Testing”)
  3. Add a Powershell Script step to the RunBook
  4. Assign it to run only on the Worker
  5. I assigned mine to run on a tentacle running in docker (my Default Worker has some issues).
  6. Set its powershell script to be:

$catalogResponse = Invoke-WebRequest -Uri “https://www.google.com/
Write-Warning “This Should Log as a Warning”

  1. Save the RunBook
  2. Run the RunBook on an Environment that is setup for the worker.

Result: This is printed to the log:

##octopus[stdout-warning]
This Should Log as a Warning

Please let me know if this allows you to reproduce this.