fix(ci): install pipewire headers, and make the Gitea upload diagnosable
OpenSSF Scorecard / Scorecard analysis (push) Waiting to run
CI / Build & test (Node 20) (push) Canceled after 0s
CI / Build & test (Node 24) (push) Canceled after 0s
CI / Build & test (push) Canceled after 0s
CodeQL / Analyze (javascript-typescript) (push) Canceled after 0s
Security / Secret scan (gitleaks) (push) Canceled after 0s
Security / Dependency scan (OSV-Scanner) (push) Canceled after 0s
Security / IaC/config scan (Trivy) (push) Canceled after 0s
Security / License compliance scan (Trivy) (push) Canceled after 0s

Two separate failures on the first run.

Linux could not compile the native module: it needs libpipewire-0.3-dev, which
its README states and the apt list omitted.

Windows built everything, native module verified, then died on the upload with
a bare JSONDecodeError. The cause was curl -sf, which discards the error body,
so a failed release creation surfaced as an empty pipe and no reason at all.
The step now captures status and body and prints them, treats a failed create
as possibly the other matrix job having just created it, and passes
target_commitish so the tag can be created.

Embedded python gave way to jq: a multi-line heredoc inside a YAML literal
block ends the block at the first unindented line, which is how the file became
invalid YAML in the first place.
This commit is contained in:
2026-09-01 15:58:26 -03:00
parent 9f7723d104
commit 9ea399ded5
+57 -29
View File
@@ -43,7 +43,8 @@ jobs:
sudo apt-get install -y \ sudo apt-get install -y \
libx11-dev libxtst-dev libxt-dev \ libx11-dev libxtst-dev libxt-dev \
libxkbcommon-dev libxkbcommon-x11-dev libxkbfile-dev \ libxkbcommon-dev libxkbcommon-x11-dev libxkbfile-dev \
libxrandr-dev libxinerama-dev libx11-xcb-dev libxrandr-dev libxinerama-dev libx11-xcb-dev \
libpipewire-0.3-dev
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
@@ -104,36 +105,60 @@ jobs:
GITEA_API: https://git.resenha.website/api/v1/repos/devsyncwrld/backspace GITEA_API: https://git.resenha.website/api/v1/repos/devsyncwrld/backspace
TAG: latest TAG: latest
run: | run: |
set -euo pipefail set -uo pipefail
if [ -z "${GITEA_TOKEN:-}" ]; then if [ -z "${GITEA_TOKEN:-}" ]; then
echo "::error::segredo GITEA_TOKEN não configurado no repositório" echo "::error::segredo GITEA_TOKEN não configurado"
exit 1 exit 1
fi fi
# A release `latest` é recriada a cada publicação: o electron-updater # Sem -f e imprimindo o corpo: a versão anterior usava `curl -sf`, que
# busca latest.yml antes de saber qual versão existe, então a URL não # engole a resposta de erro, então uma falha aqui só aparecia como um
# pode conter número de versão. # JSONDecodeError sem dizer o motivo.
ID=$(curl -sf -H "Authorization: token $GITEA_TOKEN" \ api() {
"$GITEA_API/releases/tags/$TAG" | python3 -c \ local method=$1 path=$2; shift 2
"import json,sys;print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true) curl -s -w '\n%{http_code}' -X "$method" \
-H "Authorization: token $GITEA_TOKEN" "$GITEA_API$path" "$@"
}
body() { sed '$d' <<<"$1"; }
code() { tail -n1 <<<"$1"; }
# jq em vez de python embutido: um heredoc multilinha dentro de um
# bloco literal de YAML encerra o bloco na primeira linha sem recuo.
json_id() { jq -r '.id // empty'; }
if [ -n "$ID" ]; then find_release() {
echo "release existente ($ID) — removendo anexos desta plataforma" local r; r=$(api GET "/releases/tags/$TAG")
curl -sf -H "Authorization: token $GITEA_TOKEN" "$GITEA_API/releases/$ID/assets" \ [ "$(code "$r")" = "200" ] && body "$r" | json_id || echo ""
| python3 -c "import json,sys;[print(a['id'],a['name']) for a in json.load(sys.stdin)]" \ }
| while read -r aid aname; do
case "$aname" in ID=$(find_release)
*.exe|*.AppImage|*.deb|latest*.yml) if [ -z "$ID" ]; then
curl -s -o /dev/null -X DELETE -H "Authorization: token $GITEA_TOKEN" \ R=$(api POST "/releases" -H 'Content-Type: application/json' \
"$GITEA_API/releases/$ID/assets/$aid" ;; -d "{\"tag_name\":\"$TAG\",\"name\":\"Última versão\",\"target_commitish\":\"main\",\"body\":\"Instaladores publicados pelo CI.\"}")
esac if [ "$(code "$R")" = "201" ]; then
done ID=$(body "$R" | json_id)
echo "release criada: $ID"
else
echo "criação retornou HTTP $(code "$R"): $(body "$R")"
# O outro job da matriz pode tê-la criado no mesmo instante.
ID=$(find_release)
[ -n "$ID" ] || { echo "::error::não foi possível obter nem criar a release"; exit 1; }
echo "release encontrada após corrida: $ID"
fi
else else
ID=$(curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \ echo "release existente: $ID"
-H 'Content-Type: application/json' \ fi
-d "{\"tag_name\":\"$TAG\",\"name\":\"Última versão\",\"body\":\"Instaladores publicados automaticamente pelo CI.\"}" \
"$GITEA_API/releases" | python3 -c "import json,sys;print(json.load(sys.stdin)['id'])") # Remove só os anexos que esta plataforma vai repor, para os dois jobs
echo "release criada: $ID" # não apagarem o trabalho um do outro.
R=$(api GET "/releases/$ID/assets")
if [ "$(code "$R")" = "200" ]; then
body "$R" | jq -r '.[] | "\(.id) \(.name)"' | while read -r aid aname; do
case "$aname" in
${{ runner.os == 'Windows' && '*.exe|latest.yml' || '*.AppImage|*.deb|latest-linux.yml' }})
echo "removendo anexo antigo: $aname"
api DELETE "/releases/$ID/assets/$aid" > /dev/null ;;
esac
done
fi fi
shopt -s nullglob shopt -s nullglob
@@ -143,10 +168,13 @@ jobs:
packages/desktop/dist-electron/*.deb \ packages/desktop/dist-electron/*.deb \
packages/desktop/dist-electron/latest*.yml; do packages/desktop/dist-electron/latest*.yml; do
name=$(basename "$f") name=$(basename "$f")
echo "enviando $name" R=$(api POST "/releases/$ID/assets?name=$name" -F "attachment=@$f")
curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \ if [ "$(code "$R")" != "201" ]; then
-F "attachment=@$f" "$GITEA_API/releases/$ID/assets?name=$name" > /dev/null echo "::error::falha ao enviar $name — HTTP $(code "$R"): $(body "$R")"
exit 1
fi
echo "enviado: $name"
sent=$((sent+1)) sent=$((sent+1))
done done
[ "$sent" -gt 0 ] || { echo "::error::nada para enviar — o build não produziu instaladores"; exit 1; } [ "$sent" -gt 0 ] || { echo "::error::o build não produziu instaladores"; exit 1; }
echo "$sent arquivo(s) publicados" echo "$sent arquivo(s) publicados"