deploy_skill: soporte para Coolify v4.1.2 (API /applications 404) + flujo UI Playwright

Aprendido desplegando cotizador (Next.js+FastAPI+Postgres, Docker Compose,
repo privado) en coolify.urieljareth.org (v4.1.2):

- Documenta que /applications/* devuelve 404 en esta instancia y que configurar
  apps git build-from-source solo es posible por la UI web.
- Nuevos scripts scripts/coolify-ui/: coolify-login.mjs (guarda storageState) y
  Configure-CoolifyComposeApp.mjs (build pack -> Docker Compose, Reload Compose
  File, env vars por Developer view, dominios por servicio).
- references/coolify-4.1.2-notes.md: mapa de API funcional/404, gotchas (BOM
  UTF-8 rompe el parser YAML de Coolify; Reload Compose File obligatorio; pin de
  dominios por servicio o 503; no encolar deploys concurrentes; PowerShell
  [IO.File]::ReadAllText para payloads de llaves).
- env.local.template.ps1: COOLIFY_EMAIL/COOLIFY_PASSWORD para la UI.
- SKILL.md/TOOLS.md: seccion "instance reality" y flujo UI paso a paso.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
urieljareth
2026-07-08 00:42:12 -06:00
co-authored by Claude Opus 4.8
parent cd998ce6b0
commit e7d1c33cd5
22 changed files with 2935 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
param(
[ValidateSet("GET", "POST", "PATCH", "PUT", "DELETE")]
[string]$Method = "GET",
[Parameter(Mandatory = $true)]
[string]$Path,
[string]$BodyJson,
[switch]$Raw
)
$ErrorActionPreference = "Stop"
if ([string]::IsNullOrWhiteSpace($env:GITHUB_TOKEN)) {
throw "Set GITHUB_TOKEN before calling the GitHub API. Generate a PAT at https://github.com/settings/tokens (scope 'repo') and store it in .env.local.ps1."
}
if (-not (Get-Command curl.exe -ErrorAction SilentlyContinue)) {
throw "curl.exe not found in PATH."
}
$base = if ($env:GITHUB_API_URL) { $env:GITHUB_API_URL.TrimEnd("/") } else { "https://api.github.com" }
$cleanPath = $Path.TrimStart("/")
$uri = "$base/$cleanPath"
$tmpBody = $null
$args = @("-sS", "-i", "-X", $Method.ToUpper(), "-H", "Authorization: Bearer $env:GITHUB_TOKEN", "-H", "Accept: application/vnd.github+json", "-H", "X-GitHub-Api-Version: 2022-11-28", "-H", "User-Agent: coolify-deploy-skill")
if ($PSBoundParameters.ContainsKey("BodyJson")) {
try { $null = $BodyJson | ConvertFrom-Json } catch { throw "BodyJson is not valid JSON: $($_.Exception.Message)" }
$tmpBody = [System.IO.Path]::GetTempFileName()
Set-Content -LiteralPath $tmpBody -Value $BodyJson -NoNewline -Encoding utf8
$args += @("--data", "@$tmpBody", "-H", "Content-Type: application/json")
}
try {
$output = & curl.exe @args $uri
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) { throw "GitHub API request failed with exit code $exitCode." }
$rawStr = ($output | Out-String)
$parts = $rawStr -split "(?:`r`n`r`n|`n`n)", 2
$headersBlock = if ($parts.Count -ge 1) { $parts[0] } else { "" }
$bodyBlock = if ($parts.Count -ge 2) { $parts[1] } else { "{}" }
$statusLine = ($headersBlock -split "`n" | Select-Object -First 1).Trim()
if ($statusLine -notmatch " 20[04-9] ") {
$snippet = $bodyBlock.Trim()
if ($snippet.Length -gt 400) { $snippet = $snippet.Substring(0, 400) + "..." }
throw "GitHub API HTTP error: $statusLine`nBody: $snippet"
}
if ($Raw) {
[pscustomobject]@{ Status = $statusLine; Headers = $headersBlock; Body = $bodyBlock }
} else {
try { $bodyBlock | ConvertFrom-Json }
catch { $bodyBlock }
}
}
finally {
if ($tmpBody -and (Test-Path -LiteralPath $tmpBody)) { Remove-Item -LiteralPath $tmpBody -Force -ErrorAction SilentlyContinue }
}