Pia variables: the double-$ problem and other things I stopped declaring

The thing that confused me longest in Pia was how variables get from a package into an activity. I assumed it worked like most platforms: a global exists, my script can see it. It doesn't.

Nothing is injected for you

Package variables do not automatically show up inside your custom activities. If your activity needs the ticket ID, an API URL, or a key, you pass it in through the inputs: block in the YAML, and you declare it on the Variables tab of the activity as an input.

- task: add_cw_internal_note
  inputs:
    TicketId: =$Ctx_CW_Ticket_Id
    NoteText: =build.NoteText

When an activity can't see something, it's almost always because I forgot to pass it.

The one exception that isn't an exception

Here's the one that took me the longest to work out. For a handful of variables, the ones that already exist as global Pia variables (credentials and integration keys, mostly), you do not declare them in the activity editor. You pass them through the YAML and leave the Variables tab alone.

If you declare them in both places, you can end up with a doubled $$ in front of the name and the script just stops finding the thing. It looks like a typo. In my experience it comes from the underscore naming those globals use colliding with what the editor generates. I don't claim to know the exact mechanism, only that the fix is reliable: YAML only.

So for credentials, the rule I follow is:

  1. Pass it in the YAML inputs.
  2. Don't add it to the activity's variable list.
  3. Reference it in the script as a normal variable.

Defensive input checks

Because variables silently go missing so easily, every activity of mine starts with a verify function that refuses to run if an input is empty. Listing the required names keeps it to one place:

Function VerifyActivity()
{
    # bail out early if any required input never arrived
    foreach ($name in @('TicketId', 'NoteText'))
    {
        $v = Get-Variable -Name $name -ErrorAction SilentlyContinue
        if (-not $v -or [string]::IsNullOrWhiteSpace([string]$v.Value)) { return $false }
    }
    return $true
}

Much better to fail up front with "input missing" than to send a half-empty request to an API and wonder what went wrong.

Naming

And the four syntaxes I keep on a sticky note:

WhereEarlier task's outputPackage variable
YAML=alias.output$Name
Chat text{=alias.output}{$Name}

All writing