Automating the move of packages between two octopus servers

I have two octopus servers. One for QA and one for Production. The production server exists for PCI compliance issues. We also aren’t doing a push from our build solution to the server. Is there a way to take the package as it exists in the QA version of octopus and pull it to the production version? My thought initially was to use either nuget exe or to write a script via the octopus API and try to post the package id to move it. Would either of these work or is there any recommendations around how to do this? I didn’t’ see anything in the documentation that discussed it.

Hi Allen!

The ideal system here would be to use a shared package source, and have both the QA and Production Octopus instances use the shared package source. There are several options for an external feed for Octopus. Package repositories

It would be possible to write a script to export a package from one octopus system and store it in another, but the easiest system would be to use an external package feed instead.

Hope that helps.
Cam

Cam,

Will the external feed still have access to the retention policies that the built in feed has? I know the built in feed would have better performance than an external feed.

Hi Allen,

Ah yes an external feed would have to be managed independently in terms of retention of packages.

So, it would be possible to write a script that pulls the package from QA to Prod. Another option would be to have a “Publish to Prod” project on the QA instance that pushes the raw package from the QA server to the Prod server. It depends on how the machines are separated and if the QA server can push to the Prod server.

Hope that helps.
Cam

Cam,

There is a pull process. We are not allowing users to push to prod. Prod will need to pull from QA. Where on the API can I find the package information. I know i can find the package version under the progression of the project. Where can I find the nuget id or something that can reference the nuget id?

Does simply posting to the rest api allow for the package to be moved or is this something that needs to be done with either nuget exe or octo.exe. The push command seems to take a local file and do a push. i don’t see where i can give it a source nuget feed unless I somehow found the package on the file system and used the rest API to find the version and calling octo.exe from the script. I suppose i go do that though it’s a little messy.

Cam,

Nevermind on the last question I found that if I use http://vatscm01:8090/api/packages?nuGetPackageId=“Package ID” then I can pull back all packages for a given id. I can compare that version number with the page in the release in the progression api for waht is currently deployed to get the particular package that is deployed in the previous environment. I’m working to try to do a post request when those two environments are equal.

Cam,

how do you upload a package to the package feed? When I run

Invoke-RestMethod -Method post -Uri “http://server/api/feeds/feeds-builtin/packages” -body $nugetFeedPackage -Headers @{“X-Octopus-ApiKey” = ‘api key’}, I get “The remote server returned an error: (405) Method Not Allowed.” Is this not allowed via the api? is the feed read only?

Hi Allen,

I don’t believe the feed is read only. The suggested way to push packages is with nuget.

NuGet.exe push YourApp.1.0.0.nupkg -ApiKey <Your-API-Key> -Source http://localhost:8065/nuget/packages

Your URL looks wrong compared to the example. Maybe that’s the problem?

Hope that helps.
Cam

Can this not be done via the rest API? The url is the url directly to the package feed via the API. I reading in it’s contents, finding the package I want and doing a pull to the production package feed. My hope was to run this on production and have it pull in QA packages so that it meets our PCI requirements.

Hi Allen,

I found the REST API I think you want. Posting to /api/packages/raw should allow you to upload a nuget package.

Thanks
Cam

Awesome let me try that today and see what the results are. thank you so much for all of your help. Dealing with the nuget feed is something I have never done before.

Cam,

I’m still having some issues with it and I was hoping you could help debug. So what I have based on your suggestion and this link from the documentation https://github.com/OctopusDeploy/OctopusDeploy-Api/blob/master/Octopus.Client/LINQPad/Push%20Package%20to%20Built-In%20Repository.linq.

This is what I’m doing through the rest api
Invoke-RestMethod -Method put -Uri “http://server/api/packages/raw?replace=false” -body “C:\Users\username\Downloads\Package.1.0.8362.zip” -Headers @{“X-Octopus-ApiKey” = ‘APIKEY’}

I’m still getting the remote server returned an error that the method isn’t allowed. Do you have an example of how packages are uploaded via the rest api?

The method is post not put. It was correct in the previous version you had posted.

Also, make sure the user for the API key has the BuiltInFeedPush permission in the Configuration -> Teams -> User Roles settings.

Thanks
Cam

Cam,

i tried that and found that it is a bad request using Invoke-RestMethod -Method post -Uri “http://server/api/packages/raw?replace=false” -body “C:\Users\username\Downloads\Package.1.0.8362.zip” -Headers @{“X-Octopus-ApiKey” = ‘APIKEY’}

when using the api http://server/api/packages/raw doesn’t exist; however, http://server/api/packages?nugetPackageId=SomeApplication/raw does. How does this work to upload it? It doesn’t appear I can upload it directly to the feed using the feedapi or to packages using the packages API. Even when a package exists, and I use the second URL that doesn’t work either. Do you have a working example of uploading a package using the Rest api? The document just links to the Octopus.Client version not a rest version.

It looks like in order to upload a package the POST method takes a mulitpart form body. We have an example of how to do that here https://github.com/OctopusDeploy/OctopusDeploy-Api/blob/master/REST/PowerShell/Packages/PushPackage.ps1

The example could be modified to use Invoke-RestMethod instead of HttpWebRequest so long as the body creation is kept the same.

Thanks
Cam