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>
161 lines
5.2 KiB
Markdown
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}
|
|
```
|