# Compila no GitHub, publica no Gitea. # # O GitHub entra só como máquina de build — é dele que vêm os runners Windows # de que o módulo nativo de áudio precisa. A distribuição fica no Gitea, que # serve os arquivos a qualquer um: assim o electron-updater não precisa de # credencial embutida no app, o que aconteceria com um repositório privado no # GitHub. name: Publicar no Gitea on: push: tags: ['v*'] workflow_dispatch: inputs: tag: description: Tag a publicar (ex. v1.1.0) required: true type: string permissions: contents: read jobs: build: strategy: fail-fast: false matrix: include: - os: windows-2022 args: --win --x64 - os: ubuntu-latest args: --linux --x64 runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - name: Install Linux build dependencies if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y \ libx11-dev libxtst-dev libxt-dev \ libxkbcommon-dev libxkbcommon-x11-dev libxkbfile-dev \ libxrandr-dev libxinerama-dev libx11-xcb-dev - name: Setup pnpm uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 with: version: 10.34.3 - name: Setup Node.js uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: node-version: 20 cache: pnpm - name: Cache Electron binaries uses: actions/cache@v4 with: path: | ~/.cache/electron ~/.cache/electron-builder ~\AppData\Local\electron\Cache ~\AppData\Local\electron-builder\Cache key: electron-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: electron-cache-${{ runner.os }}- - name: Install dependencies run: pnpm install --frozen-lockfile - name: Build shared package run: pnpm --filter @backspace/shared build # O postinstall termina em `|| console.warn` para quem não tem ferramentas # de build. No CI isso esconde falha: o instalador sairia sem captura de # áudio do sistema e ninguém saberia. Verifica-se o resultado. - name: Verify native audio module compiled if: runner.os == 'Windows' shell: bash run: | found=$(find node_modules/.pnpm -path '*electron-native-screenshare*' -name '*.node' | head -5) [ -n "$found" ] || { echo "::error::sem .node compilado — instalador sairia sem áudio do sistema"; exit 1; } echo "$found" - name: Compile desktop TypeScript working-directory: packages/desktop run: pnpm exec tsc # --publish never: o electron-builder não sabe enviar para o Gitea. Ele # gera os instaladores e o latest.yml (o índice que o app consulta), e o # passo seguinte faz o upload. - name: Build installers working-directory: packages/desktop run: pnpm exec electron-builder ${{ matrix.args }} --publish never env: CSC_IDENTITY_AUTO_DISCOVERY: "false" - name: Upload to Gitea release shell: bash env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_API: https://git.resenha.website/api/v1/repos/devsyncwrld/backspace TAG: latest run: | set -euo pipefail if [ -z "${GITEA_TOKEN:-}" ]; then echo "::error::segredo GITEA_TOKEN não configurado no repositório" exit 1 fi # A release `latest` é recriada a cada publicação: o electron-updater # busca latest.yml antes de saber qual versão existe, então a URL não # pode conter número de versão. ID=$(curl -sf -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_API/releases/tags/$TAG" | python3 -c \ "import json,sys;print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true) if [ -n "$ID" ]; then echo "release existente ($ID) — removendo anexos desta plataforma" curl -sf -H "Authorization: token $GITEA_TOKEN" "$GITEA_API/releases/$ID/assets" \ | 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 *.exe|*.AppImage|*.deb|latest*.yml) curl -s -o /dev/null -X DELETE -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_API/releases/$ID/assets/$aid" ;; esac done else ID=$(curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \ -H 'Content-Type: application/json' \ -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'])") echo "release criada: $ID" fi shopt -s nullglob sent=0 for f in packages/desktop/dist-electron/*.exe \ packages/desktop/dist-electron/*.AppImage \ packages/desktop/dist-electron/*.deb \ packages/desktop/dist-electron/latest*.yml; do name=$(basename "$f") echo "enviando $name" curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \ -F "attachment=@$f" "$GITEA_API/releases/$ID/assets?name=$name" > /dev/null sent=$((sent+1)) done [ "$sent" -gt 0 ] || { echo "::error::nada para enviar — o build não produziu instaladores"; exit 1; } echo "$sent arquivo(s) publicados"