Create the release body using Powershell with selected packages

I’m following this Create and deploy a release Octopus documentation, in order to initiate a build using a Powershell script.

I was able to initiate the build. Now I want to improve the script by just adding only selected packages in the build.

# Create the release body
$releaseBody = @{
  ChannelId        = $channel.Id
  ProjectId        = $project.Id
  Version          = $template.NextVersionIncrement
  SelectedPackages = @()
} 

I have more than 10 packages like below

Packages: [
{
StepName: "Bootstrapper",
ActionName: "Bootstrapper",
NuGetPackageId: "DIPS.OctopusDeployScripts.SL",
PackageId: "DIPS.OctopusDeployScripts.SL",
PackageReferenceName: "",
NuGetFeedId: "feeds-builtin",
FeedId: "feeds-builtin",
NuGetFeedName: "Octopus Server (built-in)",
FeedName: "Octopus Server (built-in)",
VersionSelectedLastRelease: "9.40.7",
ProjectName: null,
IsResolvable: true
},
{
StepName: "CleanClient",
ActionName: "CleanClient",
NuGetPackageId: "DIPS.OctopusDeployScripts.SL",
PackageId: "DIPS.OctopusDeployScripts.SL",
PackageReferenceName: "",
NuGetFeedId: "feeds-builtin",
FeedId: "feeds-builtin",
NuGetFeedName: "Octopus Server (built-in)",
FeedName: "Octopus Server (built-in)",
VersionSelectedLastRelease: "9.40.7",
ProjectName: null,
IsResolvable: true
},
{
StepName: "CleanService",
ActionName: "CleanService",
NuGetPackageId: "DIPS.OctopusDeployScripts.SL",
PackageId: "DIPS.OctopusDeployScripts.SL",
PackageReferenceName: "",
NuGetFeedId: "feeds-builtin",
FeedId: "feeds-builtin",
NuGetFeedName: "Octopus Server (built-in)",
FeedName: "Octopus Server (built-in)",
VersionSelectedLastRelease: "9.40.7",
ProjectName: null,
IsResolvable: true
},

Assume, I need CleanClient and CleanService packages only. Then how should I modify the above code.

I have tried several ways.

SelectedPackages = @('CleanClient', 'CleanService')

That gives following error

Error converting value “CleanClient” to type 'Octopus.Core.Resources.SelectedPackage

Glad someone can point me the correct way. Thanks

Hi Anuja,

Thanks for getting in touch!

When working with the REST API, a good tip to know is that the Octopus UI is API first. Every action taken within the UI uses the REST API, so, when you run into problems like this it can help to perform the same action in the UI and then check the responses generated to see what is needed.
e.g.
When creating a release I can use the browser dev tools (F12) to capture the POST and check the Request Payload at the bottom:

This is the Request Payload in a more readable format:

{
  "VersionControlReference": {
    
  },
  "ProjectId": "Projects-181",
  "ChannelId": "Channels-181",
  "ReleaseNotes": "**Commits:**\n#{each package in Octopus.Release.Package}\n#{each commit in package.Commits}\n- [#{commit.CommitId}] #{commit.Comment}\n#{/each}\n#{/each}",
  "Version": "0.0.25",
  "SelectedPackages": [
    {
      "ActionName": "Deploy a Package",
      "Version": "20210106.4",
      "PackageReferenceName": ""
    },
    {
      "ActionName": "Deploy a Package - clone (1)",
      "Version": "20210106.4",
      "PackageReferenceName": ""
    }
  ]
}

So, it looks like you are missing the ActionaName, Version and PackageReferenceName fields from your script.

Looking at the link you were working from, it seems that this section would build these for you:

# Set the package version to the latest for each package
# If you have channel rules that dictate what versions can be used, you'll need to account for that
Write-Host "Getting step package versions"
$template.Packages | ForEach-Object {
    $uri = "$octopusSpaceUrl/feeds/$($_.FeedId)/packages/versions?packageId=$($_.PackageId)&take=1"
    $version = Invoke-WebRequest -Uri $uri -Method GET -Headers $headers -Body $releaseBody -ErrorVariable octoError | ConvertFrom-Json
    $version = $version.Items[0].Version

    $releaseBody.SelectedPackages += @{
        ActionName           = $_.ActionName
        PackageReferenceName = $_.PackageReferenceName
        Version              = $version
    }
}

I hope that helps get you back on the right track.

One more thing I want to mention, in case you weren’t aware, we do have an Octo CLI that can be used for tasks such as creating and deploying releases.

Regards,
Paul

1 Like

Hi @paul.calvert

Thanks for the reply. As you have mentioned in the later part of your answer, I’m adding ActionName, PackageReferenceName & Version values for all the packages. What I need is, select only two packages (CleanClient & CleanService) not the all.

I was expecting that two packages can be filtered below code snippet

# Create the release body
$releaseBody = @{
  ChannelId        = $channel.Id
  ProjectId        = $project.Id
  Version          = $template.NextVersionIncrement
  SelectedPackages = @()
}

Or should I do that inside the following for-each loop

$template.Packages | ForEach-Object { // Should the logic goes here }

In the UI, it relates to below image

When you’re creating a release, it will always need to have a package selected for every step that includes a package.

The part in the UI where you can exclude steps and only deploy a selection of packages occurs after the release is already created.
So, this would be part of the deployment body, rather than the release body.

e.g.

Has a deployment body that includes SkipActions for the steps to be excluded:

{
  "ReleaseId": "Releases-848",
  "EnvironmentId": "Environments-61",
  "TenantId": null,
  "SkipActions": [
    "e3130818-b6a4-4786-90d6-b83de44c7047",
    "23604509-b3cb-4d3a-83f2-6d10a0976d7b",
    "b3f7b162-6c72-4645-b960-3dd04732e658"
  ],
  "QueueTime": null,
  "QueueTimeExpiry": null,
  "FormValues": {
    
  },
  "ForcePackageDownload": false,
  "UseGuidedFailure": true,
  "SpecificMachineIds": [
    
  ],
  "ExcludedMachineIds": [
    
  ],
  "ForcePackageRedeployment": false
}
1 Like

Hi @paul.calvert

Got it. Seems now it’s working as I expected with following changes.

# Create deployment
$deploymentBody = @{
    ReleaseId     = $release.Id
    EnvironmentId = $environment.Id
    SkipActions   = @("CleanClient", "CleanService")
} | ConvertTo-Json

Thank you very much :+1:

1 Like