Add Octopus Deploy Platform Hub knowledge base
New files: - PLATFORMHUB.md: index for Platform Hub guidance - platformhub/architecture.md: Git→PlatformHub→Projects model - platformhub/ocl-syntax.md: complete OCL reference for templates - platformhub/process-template-patterns.md: 5 proven patterns - platformhub/gotchas.md: every error hit and how to fix it - platformhub/api-reference.md: API vs UI capabilities - best-practices/octopus-process-templates.md: consolidated best practices Learned from building PlatformHub-Demo (30 microservices, 3 clouds). Key discoveries: step templates are space-scoped (can't cross-reference), worker_pool parameter is mandatory, publishing/sharing is UI-only. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
189
platformhub/api-reference.md
Normal file
189
platformhub/api-reference.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Platform Hub API Reference
|
||||
|
||||
What can and cannot be managed via the Octopus Deploy API versus the UI.
|
||||
|
||||
## API-Manageable Resources
|
||||
|
||||
These can be created, read, updated, and deleted via the REST API:
|
||||
|
||||
| Resource | Endpoint | Notes |
|
||||
|----------|----------|-------|
|
||||
| Spaces | `POST /api/spaces` | Requires `SpaceManagersTeamMembers` |
|
||||
| Environments | `POST /api/{SpaceId}/environments` | |
|
||||
| Lifecycles | `POST /api/{SpaceId}/lifecycles` | Include phase definitions |
|
||||
| Project Groups | `POST /api/{SpaceId}/projectgroups` | |
|
||||
| Docker Feeds | `POST /api/{SpaceId}/feeds` | `FeedType: "Docker"` |
|
||||
| Step Templates | `POST /api/{SpaceId}/actiontemplates` | Space-scoped |
|
||||
| Projects | `POST /api/{SpaceId}/projects` | |
|
||||
| Channels | `POST /api/{SpaceId}/channels` | With lifecycle assignment |
|
||||
| Releases | `POST /api/{SpaceId}/releases` | With channel and package selection |
|
||||
| Runbooks | `POST /api/{SpaceId}/runbooks` | |
|
||||
| Deployment Processes | `GET/PUT /api/{SpaceId}/deploymentprocesses/{id}` | |
|
||||
| Variables | `GET/PUT /api/{SpaceId}/variables/{id}` | |
|
||||
|
||||
## UI-Only Operations
|
||||
|
||||
These **cannot** be done via API or CLI — must use the Octopus web UI:
|
||||
|
||||
| Operation | Why |
|
||||
|-----------|-----|
|
||||
| **Publish process template** (create version) | Platform Hub feature, no API endpoint |
|
||||
| **Share process template** with spaces | Platform Hub feature, no API endpoint |
|
||||
| **Configure Platform Hub Git connection** | Instance-level setting |
|
||||
| **Convert project to Config as Code** | `POST .../git/convert` exists but requires Git credentials interactively |
|
||||
|
||||
## Common API Patterns
|
||||
|
||||
### Authentication
|
||||
|
||||
All API calls require the `X-Octopus-ApiKey` header:
|
||||
|
||||
```bash
|
||||
API_KEY=$(grep 'value:' ~/dev/claude/secrets/taniwha.octopus.app/api_key | awk '{print $2}')
|
||||
curl -s -H "X-Octopus-ApiKey: $API_KEY" \
|
||||
"https://taniwha.octopus.app/api/Spaces-103/environments"
|
||||
```
|
||||
|
||||
### Create a Space
|
||||
|
||||
```bash
|
||||
curl -s -H "X-Octopus-ApiKey: $API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-X POST "https://taniwha.octopus.app/api/spaces" \
|
||||
-d '{
|
||||
"Name": "My Space",
|
||||
"SpaceManagersTeamMembers": ["Users-21"],
|
||||
"IsDefault": false
|
||||
}'
|
||||
```
|
||||
|
||||
Note: `SpaceManagersTeamMembers` must not be empty — at least one user or team required.
|
||||
|
||||
### Create Environments
|
||||
|
||||
```bash
|
||||
for env in Development Staging Production; do
|
||||
curl -s -H "X-Octopus-ApiKey: $API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-X POST "https://taniwha.octopus.app/api/$SPACE_ID/environments" \
|
||||
-d "{\"Name\": \"$env\"}"
|
||||
done
|
||||
```
|
||||
|
||||
### Create Lifecycles with Auto-Deploy Phases
|
||||
|
||||
```bash
|
||||
# Non-Prod: Dev → Staging (auto-deploy both)
|
||||
curl -s -H "X-Octopus-ApiKey: $API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-X POST "https://taniwha.octopus.app/api/$SPACE_ID/lifecycles" \
|
||||
-d '{
|
||||
"Name": "Non-Prod",
|
||||
"Phases": [
|
||||
{
|
||||
"Name": "Development",
|
||||
"AutomaticDeploymentTargets": ["Environments-104"],
|
||||
"OptionalDeploymentTargets": [],
|
||||
"MinimumEnvironmentsBeforePromotion": 0,
|
||||
"IsOptionalPhase": false
|
||||
},
|
||||
{
|
||||
"Name": "Staging",
|
||||
"AutomaticDeploymentTargets": ["Environments-105"],
|
||||
"OptionalDeploymentTargets": [],
|
||||
"MinimumEnvironmentsBeforePromotion": 0,
|
||||
"IsOptionalPhase": false
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### Create Docker Feed (GHCR)
|
||||
|
||||
```bash
|
||||
curl -s -H "X-Octopus-ApiKey: $API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-X POST "https://taniwha.octopus.app/api/$SPACE_ID/feeds" \
|
||||
-d '{
|
||||
"FeedType": "Docker",
|
||||
"Name": "GHCR Non-Prod",
|
||||
"FeedUri": "https://ghcr.io"
|
||||
}'
|
||||
```
|
||||
|
||||
### Create Step Template (Action Template)
|
||||
|
||||
```bash
|
||||
curl -s -H "X-Octopus-ApiKey: $API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-X POST "https://taniwha.octopus.app/api/$SPACE_ID/actiontemplates" \
|
||||
-d '{
|
||||
"Name": "Run Unit Tests",
|
||||
"Description": "Language-specific unit test suite",
|
||||
"ActionType": "Octopus.Script",
|
||||
"Properties": {
|
||||
"Octopus.Action.Script.ScriptSource": "Inline",
|
||||
"Octopus.Action.Script.Syntax": "PowerShell",
|
||||
"Octopus.Action.Script.ScriptBody": "Write-Host \"Running tests...\""
|
||||
},
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "Language",
|
||||
"Label": "Programming Language",
|
||||
"DefaultValue": "go",
|
||||
"DisplaySettings": {
|
||||
"Octopus.ControlType": "SingleLineText"
|
||||
}
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### Create Release via API (CI-driven)
|
||||
|
||||
```bash
|
||||
curl -s -X POST \
|
||||
-H "X-Octopus-ApiKey: $API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://taniwha.octopus.app/api/$SPACE_ID/releases" \
|
||||
-d '{
|
||||
"ProjectId": "Projects-XXX",
|
||||
"ChannelId": "Channels-XXX",
|
||||
"Version": "1.2.3+202603251530",
|
||||
"SelectedPackages": [{
|
||||
"ActionName": "Deploy Non-Prod Image",
|
||||
"PackageReferenceName": "service-image",
|
||||
"Version": "1.2.3+202603251530"
|
||||
}]
|
||||
}'
|
||||
```
|
||||
|
||||
## Idempotent Script Pattern
|
||||
|
||||
For automation scripts that may be re-run:
|
||||
|
||||
```bash
|
||||
# Check if resource exists before creating
|
||||
existing=$(curl -s -H "X-Octopus-ApiKey: $API_KEY" \
|
||||
"https://taniwha.octopus.app/api/$SPACE_ID/projectgroups?take=100" \
|
||||
| python3 -c "
|
||||
import sys, json
|
||||
name = sys.argv[1]
|
||||
for item in json.load(sys.stdin).get('Items', []):
|
||||
if item['Name'] == name:
|
||||
print(item['Id'])
|
||||
break
|
||||
" "Marketplace" 2>/dev/null || echo "")
|
||||
|
||||
if [[ -n "$existing" ]]; then
|
||||
echo "Already exists: $existing"
|
||||
else
|
||||
# Create it
|
||||
curl -s -X POST ...
|
||||
fi
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Octopus REST API](https://octopus.com/docs/octopus-rest-api)
|
||||
- [API Examples (GitHub)](https://github.com/OctopusDeploy/OctopusDeploy-Api)
|
||||
Reference in New Issue
Block a user