1

I have this line in a GitHub Action:

curl https://api.github.com/repos/JJ/raku-advent-calendar-article-2019/issues/$ENV:ISSUE/comments -H "Authorization: token $ENV:TOKEN"  -H "Content-Type: application/json" --data $output

I haven't found a way to assign values to $data to make it work. GitHub Actions, or Powershell, or both, cut it, generally at a quote, but I really couldn't find out what it does and where.

This was the last I tried:

'{ `"body`": `"Merry Xmas to you too!`"}'

Note the Powershell-escapes for the double quotes. This returned this error:

curl: (6) Could not resolve host: Xmas

So, for some reason, it stopped at Merry. Any idea?

This question is similar, however, they are not using a variable to hold the result, which I need.

jjmerelo
  • 22,578
  • 8
  • 40
  • 86
  • As an aside: The [linked question's accepted answer](https://stackoverflow.com/a/24929803/45375) doesn't actually work, and the basic problem is the same as here. – mklement0 Dec 04 '19 at 18:41
  • 1
    Curl is actually an alias for invoke-webrequest in powershell for windows. – js2010 Dec 04 '19 at 18:50
  • Good point, @js2010, but the syntax of the command in the question and the error message imply that it is the `curl` utility (external program) that is being used. – mklement0 Dec 04 '19 at 21:32

2 Answers2

4

If you are using PowerShell, use the native PowerShell functions, like Invoke-RestMethod, which accept PowerShell data structures instead of worrying about serialization/deserialization.

Invoke-RestMethod -Uri $Uri -Headers @{Authorization = "token $env:TOKEN"; "Content-Type" = "application/json"} -Body @{body = "Merry Xmas to you too!"}
twinlakes
  • 9,438
  • 6
  • 31
  • 42
3
  • '...' are verbatim strings in PowerShell, so embedded " require no escaping - your ` chars. are treated as literals.

  • However, sadly, PowerShell's handling of embedded " when calling external programs such as curl is fundamentally broken, requiring you to manually \-escape them in all PowerShell versions up to v7.2.x.

    • This long-standing problem is fixed in PowerShell (Core) 7.3+, but with selective exceptions on Windows - see this answer.

Therefore:

$jsonForCurl = '{ \"body\": \"Merry Xmas to you too!\" }'

To apply this escaping to an existing string value, programmatically, use the following:

$json = '{ "body": "Merry Xmas to you too!" }'
$jsonForCurl = $json -replace '"', '\"'

See this answer for how to apply this technique to expandable strings ("...") and for how to make the regex more robust to also deal with preexisting \" sequences in the data correctly.

mklement0
  • 382,024
  • 64
  • 607
  • 775