Publish packages in a release from a DEV Octopus Server to a PROD Octopus Server

Hello,

At our client, they have two Octopus Servers, one for the DEV labs and one for Production. Both Octopus Servers are managed by different team for security purposes. Not ideal, but it’s what we have.

We have duplications of Projects across both Octopus instances, and just want the ability to promote the packages from a DEV release through to the PROD Octopus Server.

Is there a way we can determine what packages are utilised given a Release Id? Once we have the packages, we can then "push’ them to the Production Octopus internal nuget Package server, where a release can be created there.

It does not seem to be trivial via the REST API, not sure if there are some Octopus system variables that could be queried?
Or is there a better approach you could suggest?

Thanks!

Matt

Hi there Matt,

You could use an approach like this one:

From your DEV Octopus

  • Lets say you have Dev and QA running here
  • You usually push your package from your build server to this instance, and then deploy it to Dev and promote it to QA
  • Add an extra environment and call it PreProduction
  • Add a step to you deployment process that simply runs Nuget.exe push to push your package to your PROD Octopus instance. Scope this step to PreProduction only.
  • Once you deployed to Dev, then QA and you are finally ready to move to your PROD Octopus instance, simply promote it to PreProduction which should only run the Nuget.exe push step.

From your PROD Octopus

  • Once the package arrives to this instance, deploy it as usual.

Let me know if that makes sense. I made the description very brief cause I know you are an advanced user :wink:

Cheers!
Dalmiro

Hey there Dalmiro!

Thanks for your feedback!

Yeah I understand what you’re saying, it’s just for the step:

Add a step to you deployment process that simply runs Nuget.exe push to push your package to yourPROD Octopus instance. Scope this step to PreProduction only.

I want to make a script template and was unsure how to dynamically determine the packages in the release that would need to be published via Nuget.

I ended up using parameters where the user can specify which steps have a package, and other parameters to define the destination octopus server URL, API key and the package folder on the octopus server.

I am not sure if there in any easier approach I am overlooking?


That approach makes perfect sense actually.

Let me know if it works or if you need extra help.

I thought about it some more, and think I have worked out how to get the packages and versions via the REST API. That might be better than having to ask the user which steps the package it is… let PowerShell find it for you! :slight_smile:

This is the script I ended up utilising:

$destOctoServer = $OctopusParameters['DestinationOctopusServer']
$destOctoServerAPIKey = $OctopusParameters['DestinationOctopusAPIKey']
$octopusPackageFolder = $OctopusParameters['SourceOctopusPackageFolder']
$actionSteps = @()
$actionSteps += $OctopusParameters['FirstActionStepName']
$actionSteps += $OctopusParameters['SecondActionStepName']
$actionSteps += $OctopusParameters['ThirdActionStepName']

$packages = @()
foreach ($actionStep in $actionSteps)
{
    if (($actionStep -ne $null) -and ($actionStep -ne ""))
    {
        Write-Output "Looking for package in Step '$actionStep'"
        $packageId = $OctopusParameters["Octopus.Action[$actionStep].Package.NuGetPackageId"] 
        $versionNum = $OctopusParameters["Octopus.Action[$actionStep].Package.NuGetPackageVersion"] 

        $packageFile = "$octopusPackageFolder\$packageId\$packageId.$versionNum.nupkg"

        if ((Test-Path -Path $packageFile -PathType Leaf) -and ($packages -notcontains $packageFile))
        {
            Write-Output "Adding Package: $packageFile"
            $packages += $packageFile
        }
    }
}
if ($packages.Length -eq 0)
{
    Write-Error "Unablr to find any packages to publish. Check the configuration and try again."
}
Write-Output "Completed looking for packages. Now pushing packages to $destOctoServer..."
$wc = New-Object System.Net.WebClient
foreach ($package in $packages)
{
    Write-Output "Pushing package '$package' to the destination Octopus Server."
    $wc.UploadFile("$destOctoServer/api/packages/raw?apiKey=$destOctoServerAPIKey", $package) | Out-Null
}
Write-Output "All done."

I was going to use the REST API to look up the list of packages rather than imposing a limit of 3. But we have can tokens in the config package name and if was going to start to evaluate those it was a bit too far down the rabbit hole for me! :slight_smile:

99% of our releases only have 1 package. some might have 2, it would be very rare for them to have 3. so having the three options should cover most scenarios.