Files
claude-foundations/platformhub/gotchas.md
Paul O'Reilly 6c0f2db169 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>
2026-03-25 09:54:09 +13:00

161 lines
5.2 KiB
Markdown

# Platform Hub Gotchas and Troubleshooting
Every error encountered while building the PlatformHub-Demo project, and how to fix it.
## OCL Parse Errors
### "Action Template with ID 'ActionTemplates-XX' and version v0 specified in OCL was not found"
**Cause:** Process template references a step template (ActionTemplate) by ID, but step templates are space-scoped. Platform Hub operates at instance level and can't see step templates in individual spaces.
**Fix:** Don't reference step templates in process template OCL. Use inline `action_type` definitions instead:
```hcl
# WRONG — cross-space reference
action {
properties = {
Octopus.Action.Template.Id = "ActionTemplates-64"
Octopus.Action.Template.Version = "0"
}
}
# RIGHT — inline action
action {
action_type = "Octopus.Script"
properties = {
Octopus.Action.RunOnServer = "true"
Octopus.Action.Script.ScriptSource = "Inline"
Octopus.Action.Script.Syntax = "PowerShell"
Octopus.Action.Script.ScriptBody = <<-EOT
Write-Host "Inline script here"
EOT
OctopusUseBundledTooling = "False"
}
worker_pool_variable = "worker_pool"
}
```
### "A step must specify a worker pool parameter"
**Cause:** Every step in a process template must have a worker pool, either directly or via a variable. The template itself must define a `WorkerPool` parameter.
**Fix:** Add a `worker_pool` parameter to the template and reference it from every action:
```hcl
# Add this parameter to the template
parameter "worker_pool" {
display_settings = {
Octopus.ControlType = "WorkerPool"
}
help_text = "Worker pool for server-side steps"
label = "Worker Pool"
}
# On EVERY action (both RunOnServer=true and RunOnServer=false):
action {
action_type = "Octopus.Script"
properties = { ... }
worker_pool_variable = "worker_pool" # Must reference the parameter
}
```
Note: `worker_pool_variable = ""` (empty string) will NOT work. It must reference an actual parameter name.
### "Name value contains invalid characters"
**Cause:** Template or step names contain characters outside the allowed set.
**Allowed:** Letters, numbers, periods, commas, dashes, underscores, hashes
**Not allowed:** Parentheses `()`, slashes `/`, ampersands `&`, colons `:`, at-signs `@`
```
# WRONG
name = "Run Security Scan (SAST/SCA)"
# RIGHT
name = "Run Security Scan - SAST and SCA"
```
## API and Scripting Issues
### Step template names created as numbers instead of text
**Cause:** The bash variable `GROUPS` is pre-set by bash completion scripts (contains numeric group IDs). Assigning to `GROUPS` in a script that sources other files will silently use the pre-existing value.
**Fix:** Use a unique variable name that won't collide with shell builtins or completion scripts:
```bash
# WRONG — GROUPS may already be set by bash completion
GROUPS=("Marketplace" "Payments" "Orders")
# RIGHT — use a unique name
PROJECT_GROUPS=("Marketplace" "Payments" "Orders")
```
### Action template (step template) creation: HTTP 400 with name errors
**Cause:** Same name restriction as process templates. The API enforces the same character rules.
### Octopus API POST with nested command substitution loses values
**Cause:** Nested `$(...)` in bash can mangle variable expansion. Avoid constructing JSON inside `$(octopus_post "/endpoint" "$(python3 ...)")`.
**Fix:** Build the JSON body in a separate variable first:
```bash
# WRONG — nested substitution
response=$(octopus_post "/projectgroups" "$(python3 -c "..." "$name")")
# RIGHT — build body first
body="{\"Name\": \"$name\"}"
response=$(octopus_post "/projectgroups" "$body")
```
## Publishing and Sharing
### Templates visible in Platform Hub but not in project spaces
**Cause:** Templates must be explicitly published (versioned) and shared with target spaces. Both operations are UI-only — there is no API or CLI for this.
**Fix:** For each template:
1. Go to Platform Hub in the Octopus UI
2. Click the template → Publish (creates a version)
3. Click Share → select target spaces → Save
### Template changes not reflected in consuming projects
**Cause:** Template versioning. Changes in Git are picked up by Platform Hub but won't affect projects until a new version is published. Projects with `version_mask = "1.X"` will auto-update on minor/patch publications.
## OCL Syntax Specifics
### Heredoc for multi-line scripts
PowerShell scripts with double quotes need heredoc syntax:
```hcl
Octopus.Action.Script.ScriptBody = <<-EOT
$name = $OctopusParameters['Octopus.Project.Name']
Write-Host "Deploying $name"
EOT
```
The `<<-EOT` variant (with dash) allows the closing `EOT` to be indented. Without the dash, `EOT` must be at column 0.
### Parameter references: single vs double braces
- `#{param_name}` — standard Octopus variable substitution (most properties)
- `#{{param_name}}` — escaped substitution (used in some properties like `GitRepository.FilePathFilters`)
### PowerShell variable access in scripts
Inside script bodies, use `$OctopusParameters['Variable.Name']`, not `#{Variable.Name}`:
```powershell
# In script body:
$project = $OctopusParameters['Octopus.Project.Name']
$cloud = $OctopusParameters['cloud_target']
# NOT this (only works in OCL properties, not script text):
# #{Octopus.Project.Name}
```