The recommended approach here is to leverage the artifact feature in Octopus Deploy. One example of artifacts can be found in this database deployment. The artifact is associated with that deployment. In this example, a DBA can download the artifact, review it, then determine if the release should be promoted to the next environment.
Artifact generation was written with the assumption artifacts would be created as part of a deployment. The documentation reinforces that by only providing samples to upload via the helper method New-OctopusArtifact.
The good news is it is possible to upload an artifact to a release using the API. The tricky part is the endpoint expects a ServerTaskId, which is tied to a specific deployment. A deployment for a specific environment, and is also tied to a release, which is tied to a project, which is tied to a space.
To get that information the script will need to find (in order):
The space id from the space name
The project id from the project name
The environment id from the environment name
The release id using the project id and version number
The most recent deployment for that release using the environment id
It looks like this (if written in PowerShell):
$header = @{ "X-Octopus-ApiKey" = $APIKey }
Write-Host "Getting the space information"
$spaceList = Invoke-RestMethod -Method Get -Uri "$OctopusUrl/api/spaces?skip=0&take=10&partialName=$([System.Web.HTTPUtility]::UrlEncode($spaceName))" -Headers $header
$space = $spaceList.Items | Where-Object {$_.Name -eq $spaceName}
$spaceId = $space.Id
Write-Host "The space-id for $spaceName is $spaceId"
Write-Host "Getting the environment information"
$environmentList = Invoke-RestMethod -Method Get -Uri "$OctopusUrl/api/$spaceId/environments?skip=0&take=10&partialName=$([System.Web.HTTPUtility]::UrlEncode($environmentName))" -Headers $header
$environment = $environmentList.Items | Where-Object {$_.Name -eq $environmentName}
$environmentId = $environment.Id
Write-Host "The id of $environmentName is $environmentId"
Write-Host "Getting the project information"
$projectList = Invoke-RestMethod -Method Get -Uri "$OctopusUrl/api/$spaceId/projects?skip=0&take=10&partialName=$([System.Web.HTTPUtility]::UrlEncode($projectName))" -Headers $header
$project = $projectList.Items | Where-Object {$_.Name -eq $projectName}
$projectId = $project.Id
Write-Host "The id of $projectName is $projectId"
Write-Host "Getting the release information"
$releaseList = Invoke-RestMethod -Method Get -Uri "$OctopusUrl/api/$spaceId/projects/$projectId/releases?skip=0&take=100&searchByVersion=$releaseVersion" -Headers $header
$release = $releaseList.Items | Where-Object {$_.Version -eq $releaseVersion}
$releaseId = $release.Id
Write-Host "The id of $releaseVersion is $releaseId"
Write-Host "Getting the deployment information"
$deploymentList = Invoke-RestMethod -Method Get -Uri "$OctopusUrl/api/$spaceId/releases/$releaseId/deployments?skip=0&take=1000" -Headers $header
$deploymentsToEnivronment = @($deploymentList.Items | Where-Object {$_.EnvironmentId -eq $environmentId})
$deploymentToUse = $null
$previousDate = Get-Date
$previousDate = $previousDate.AddDays(-10000)
foreach ($deployment in $deploymentsToEnivronment)
{
if ($deployment.Created -gt $previousDate)
{
$previousDate = $deployment.Created
$deploymentToUse = $deployment
}
}
$serverTaskId = $deploymentToUse.TaskId
Write-Host "The server task id of the most recent deployment to $environmentName for release $releaseVersion is $serverTaskId"
The other tricky part is the artifact resource must exist before content can be uploaded to it. The order of operations is:
Create artifact using the server task id
Use ID returned from the POST in creating the artifact resource to upload the file content
Uploading file content in PowerShell is…quirky. This is how that looks all together: