API Call to Create Release
Asked by matt_dolan_advantasure_com:

Hi- I've been banging my head up against the wall attempting to create a deployment release via API call from a PowerShell script. (Nearly all of my attempts at retrieving via GET to Bamboo APIs are succeeding; just this POST that is killing me).

My Powershell script which accepts Method (ie. Get or Post) and URI is below.

The URI I'm passing is: http://\<bamboo server\>/rest/api/latest/deploy/project/\<project id\>/version.json

The project ID I am passing is correct and verified with other GET calls

param(\[string\]$method, \[string\]$uri)

$user = "\<my user name\>"  
$pass = "\<my pass\>"  
$pair = "${user}:${pass}"

$bytes = \[System.Text.Encoding\]::ASCII.GetBytes($pair)  
$base64 = \[System.Convert\]::ToBase64String($bytes)

$basicAuthValue = "Basic $base64"

$headers = @{ Authorization = $basicAuthValue }

$body = @"  
{  
"planResultKey": "UAT-TEST-111",  
"name": "release-7"  
}  
"@

Invoke-RestMethod -method $method -body $body -uri $uri -Headers $headers -ContentType "application/json"

So after all the credentials are verified (this works great with other Bamboo APIs) I am in essence running:

Invoke-RestMethod -method post -body $body -uri http://\<bamboo server\>/rest/api/latest/deploy/project/\<project id\>/version.json -Headers $headers -ContentType "application/json"

I get "The remote server returned an error: (404) Not Found."

Please advise. Thanks!!


Answers:
author: rsperafico
body: Hello [@matt_dolan_advantasure_com](/t5/user/viewprofilepage/user-id/1198988),

As my colleague [@Jeremy Owen](/t5/user/viewprofilepage/user-id/73944) mentioned, it is important to review what is the Bamboo version you are running the endpoints against.

You could be using [Bamboo's REST API](https://docs.atlassian.com/atlassian-bamboo/REST/6.4.1/ "Bamboo's REST API") as per example below.

```
--- get build results of a given planKeycurl -k -u BAMBOO_ADMINISTRATOR \     -H "Content-type: application/json" \     -H "Accept: application/json" \     -X GET http://localhost:8085/rest/api/latest/result/PROJ-PLAN?expand=results.result
```

As a result, you would get something similar to the following:

```
{    "results": {        "size": 1,        "expand": "result",        "start-index": 0,        "max-result": 25,        "result": [{            "expand": "plan,artifacts,comments,labels,jiraIssues,stages",            "link": {                "href": "http://localhost:8085/rest/api/latest/result/PROJ-PLAN-1",                "rel": "self"            },            "plan": {                "shortName": "Plan",                "shortKey": "PLAN",                "type": "chain",                "enabled": true,                "link": {                    "href": "http://localhost:8085/rest/api/latest/plan/PROJ-PLAN",                    "rel": "self"                },                "key": "PROJ-PLAN",                "name": "Project - Plan",                "planKey": {                    "key": "PROJ-PLAN"                }            },            "planName": "Plan",            "projectName": "Project",            "buildResultKey": "PROJ-PLAN-1",            "lifeCycleState": "Finished",            "id": 1671169,            "buildStartedTime": "2017-06-16T13:22:30.555-03:00",            "prettyBuildStartedTime": "Fri, 16 Jun, 01:22 PM",            "buildCompletedTime": "2017-06-16T13:22:31.138-03:00",            "buildCompletedDate": "2017-06-16T13:22:31.138-03:00",            "prettyBuildCompletedTime": "Fri, 16 Jun, 01:22 PM",            "buildDurationInSeconds": 0,            "buildDuration": 583,            "buildDurationDescription": "< 1 second",            "buildRelativeTime": "4 minutes ago",            "buildTestSummary": "No tests found",            "successfulTestCount": 0,            "failedTestCount": 0,            "quarantinedTestCount": 0,            "skippedTestCount": 0,            "continuable": false,            "onceOff": false,            "restartable": false,            "notRunYet": false,            "finished": true,            "successful": true,            "buildReason": "Manual run by <a href=\"http://localhost:8085/browse/user/admin\">Administrator</a>",            "reasonSummary": "Manual run by <a href=\"http://localhost:8085/browse/user/admin\">Administrator</a>",            "artifacts": {                "size": 0,                "start-index": 0,                "max-result": 0            },            "comments": {                "size": 0,                "start-index": 0,                "max-result": 0            },            "labels": {                "size": 0,                "start-index": 0,                "max-result": 0            },            "jiraIssues": {                "size": 0,                "start-index": 0,                "max-result": 0            },            "stages": {                "size": 1,                "start-index": 0,                "max-result": 1            },            "key": "PROJ-PLAN-1",            "planResultKey": {                "key": "PROJ-PLAN-1",                "entityKey": {                    "key": "PROJ-PLAN"                },                "resultNumber": 1            },            "state": "Successful",            "buildState": "Successful",            "number": 1,            "buildNumber": 1        }]    },    "expand": "results",    "link": {        "href": "http://localhost:8085/rest/api/latest/result/PROJ-PLAN",        "rel": "self"    }}
```

```
--- get all Deployment Projectscurl -k -u BAMBOO_ADMINISTRATOR \     -H "Content-type: application/json" \     -H "Accept: application/json" \     -X GET http://localhost:8085/rest/api/latest/deploy/project/all
```

As a result, you would get something similar to the following:

```
[{    "id": 851969,    "oid": 19421773393035265,    "key": {        "key": "851969"    },    "name": "Deployment",    "planKey": {        "key": "PROJ-PLAN"    },    "description": "",    "environments": [{        "id": 950273,        "key": {            "key": "851969-950273"        },        "name": "Staging",        "description": "",        "deploymentProjectId": 851969,        "operations": {            "canView": true,            "canEdit": true,            "canDelete": true,            "allowedToExecute": true,            "canExecute": true,            "allowedToCreateVersion": false,            "allowedToSetVersionStatus": false        },        "position": 0,        "configurationState": "TASKED"    }, {        "id": 950274,        "key": {            "key": "851969-950274"        },        "name": "QA",        "description": "",        "deploymentProjectId": 851969,        "operations": {            "canView": true,            "canEdit": true,            "canDelete": true,            "allowedToExecute": true,            "canExecute": true,            "allowedToCreateVersion": false,            "allowedToSetVersionStatus": false        },        "position": 1,        "configurationState": "TASKED"    }],    "operations": {        "canView": true,        "canEdit": true,        "canDelete": true,        "allowedToExecute": false,        "canExecute": false,        "allowedToCreateVersion": true,        "allowedToSetVersionStatus": false    }}]
```

```
--- create release of a Branch (i.e. PROJ-PLAN0) using build number as source (i.e. PROJ-PLAN0-1)curl -k -u BAMBOO_ADMINISTRATOR \     -H "Content-type: application/json" \     -d '{"planResultKey":"PROJ-PLAN0-1","name":"fromBranchA-1","nextVersionName":"fromBranchA-2"}' \     -X POST http://localhost:8085/rest/api/latest/deploy/project/{id}/version
```

As a result, you would get something similar to the following:

```
{    "id": 1277953,    "name": "fromBranchA-1",    "creationDate": 1479153329899,    "creatorUserName": "admin",    "items": [{        "id": 1343489,        "name": "ARTIFACT",        "planResultKey": {            "key": "PROJ-PLAN0-1",            "entityKey": {                "key": "PROJ-PLAN0"            },            "resultNumber": 1        },        "type": "BAM_ARTIFACT",        "label": "ARTIFACT",        "location": "",        "copyPattern": "artifact.txt",        "size": 21,        "artifact": {            "id": 1212418,            "label": "ARTIFACT",            "size": 21,            "isSharedArtifact": true,            "isGloballyStored": false,            "linkType": "com.atlassian.bamboo.plugin.artifact.handler.local:ServerLocalArtifactHandler",            "planResultKey": {                "key": "PROJ-PLAN0-1",                "entityKey": {                    "key": "PROJ-PLAN0"                },                "resultNumber": 1            },            "archiverType": "NONE"        }    }],    "operations": {        "canView": true,        "canEdit": true,        "canDelete": true,        "allowedToExecute": false,        "canExecute": false,        "allowedToCreateVersion": true,        "allowedToSetVersionStatus": true    },    "creatorDisplayName": "Administrator",    "creatorGravatarUrl": "https://secure.gravatar.com/avatar/d15b021bee8cf2ace526260514708201.jpg?r=g&s=24&d=mm",    "planBranchName": "branchA",    "ageZeroPoint": 1479153329899}
```

```
--- deploy on Staging--- get environmentId from cURL's response #2--- get releaseId from cURL's response #3curl -k -u BAMBOO_ADMINISTRATOR \     -X POST "http://localhost:8085/rest/api/latest/queue/deployment?environmentId=950273&versionId=1277953"
```

As a result, you would get something similar to the following:

```
{    "deploymentResultId": 1376257,    "link": {        "href": "http://localhost:8085/rest/api/latest/deploy/result/1376257",        "rel": "self"    }}
```

Now, you simply need to convert cURL commands from above into Powershell scripts.

Hope it helps :)

Kind regards,

Rafael

comments: author: matt_dolan_advantasure_com
body: Thanks! I was finally able to get the Deploy APIs to work on our test Bamboo instance running 6.4


author: Jeremy Owen
body: Hey Matt,

Pretty strange indeed. The endpoint should only return a 404 if a Deployment Project with that ID cannot be found (or if the endpoint was wrong).

I know you mentioned that the ID is correct, but just to clarify:

* Does *http://\<bamboo server\>/deploy/viewDeploymentProjectEnvironments.action?id=\<project id\>* work in your browser?
* Does GET *http://\<bamboo server\>/rest/api/latest/deploy/project/\<project id\>* */* return a project?

Failing that, you could wrap the PowerShell method in a try catch block to log the actual response message to get some more info to point in the right direction:

```
try
 {
Invoke-RestMethod -method $method -body $body -uri $uri -Headers $headers -ContentType "application/json"
 }
catch
 {
 $result = $_.Exception.Response.GetResponseStream()
 $reader = New-Object System.IO.StreamReader($result)
 $reader.BaseStream.Position = 0
 $reader.DiscardBufferedData()
 $reader.ReadToEnd()
 }
```

comments: author: matt_dolan_advantasure_com
body: Thanks Jeremy!

Both of your two bullet items are successful. The browser retrieval and the GET call both work like a charm.

Thanks for the try catch advice. Below is the response I get with the troublesome POST with the try catch implemented: null for uri

\<?xml version="1.0" encoding="UTF-8" standalone="yes"?\>\<status\>\<status-code\>404\</status-code\>  
\<message\>null for uri: [http://172.25.32.241:8085/rest/api/latest/deploy/project/41091073/version\</message\>\</status]()\>


author: matt_dolan_advantasure_com
body: PS- Was starting to think that something was awry with my POST calls though successfully made the below POST call for example.

Invoke-RestMethod -method post -body $body -uri http://\<bamboo server\>/rest/api/latest/plan/\<Project Key\>-\<Build Key\>/label -Headers $headers -ContentType "application/json"


author: matt_dolan_advantasure_com
body: If I go to System Information \> Rest Resources I find: [http://\<bamboo server\>:8085/rest/api/latest/](http://172.25.32.241:8085/rest/api/latest/) which produces the below XML. Turns out I'm trying to call APIs with resource name of "deploy" which do not exist below.

Is there any way to get the deploy resource added?

(We have another test version of Bamboo running 6.4 which also does not have the deploy resource available....hmm...)

\<resources expand="resources"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/" rel="self"/](http://172.25.32.241:8085/rest/api/latest/"?rel="self"/)\>\<resources start-index="0" max-result="12" size="12"\>\<resource name="info"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/info" rel="self"/](http://172.25.32.241:8085/rest/api/latest/info"?rel="self"/)\>\</resource\>\<resource name="project"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/project" rel="self"/](http://172.25.32.241:8085/rest/api/latest/project"?rel="self"/)\>\</resource\>\<resource name="plan"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/plan" rel="self"/](http://172.25.32.241:8085/rest/api/latest/plan"?rel="self"/)\>\</resource\>\<resource name="result"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/result" rel="self"/](http://172.25.32.241:8085/rest/api/latest/result"?rel="self"/)\>\</resource\>\<resource name="chart"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/chart" rel="self"/](http://172.25.32.241:8085/rest/api/latest/chart"?rel="self"/)\>\</resource\>\<resource name="queue"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/queue" rel="self"/](http://172.25.32.241:8085/rest/api/latest/queue"?rel="self"/)\>\</resource\>\<resource name="export"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/export" rel="self"/](http://172.25.32.241:8085/rest/api/latest/export"?rel="self"/)\>\</resource\>\<resource name="clone"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/clone" rel="self"/](http://172.25.32.241:8085/rest/api/latest/clone"?rel="self"/)\>\</resource\>\<resource name="dependency"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/dependency" rel="self"/](http://172.25.32.241:8085/rest/api/latest/dependency"?rel="self"/)\>\</resource\>\<resource name="elasticConfiguration"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/elasticConfiguration" rel="self"/](http://172.25.32.241:8085/rest/api/latest/elasticConfiguration"?rel="self"/)\>\</resource\>\<resource name="reindex"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/reindex" rel="self"/](http://172.25.32.241:8085/rest/api/latest/reindex"?rel="self"/)\>\</resource\>\<resource name="currentUser"\>\<link href="[http://172.25.32.241:8085/rest/api/latest/currentUser" rel="self"/](http://172.25.32.241:8085/rest/api/latest/currentUser"?rel="self"/)\>\</resource\>\</resources\>\</resources\>


author: Jeremy Owen
body: Unfortunately we can't trust the REST resources API as a source of truth for available endpoints:

* [REST / endpoint doesn't list all resources](https://jira.atlassian.com/browse/BAM-17329)

Curiously, you mentioned your test version of Bamboo is running 6.4 but what version is the Bamboo instance you're testing this on? Is it also 6.4? We didn't add that particular API till Bamboo 5.11.


author: matt_dolan_advantasure_com
body: Thanks Jeremy! We are running 5.9.7 on the Bamboo installation for which I am unable to successfully use Deploy APIs. The good news is that the Deploy APIs on our 6.4 installation are indeed working which is great.

Thanks again! (I have a separate question regarding Bamboo Specs and how it integrates with BitBucket. Will open another question ticket for that)