diff --git a/.gitea/scripts/publish-release.mjs b/.gitea/scripts/publish-release.mjs new file mode 100644 index 0000000..2b41c73 --- /dev/null +++ b/.gitea/scripts/publish-release.mjs @@ -0,0 +1,58 @@ +// Publish the built hub binary to a rolling "dev" release on Gitea. +// Runs in the CI job with only Node available (the runner image has no +// curl/jq/sudo), so this uses Node built-ins + global fetch/FormData/Blob. +// +// Env: TOKEN (Gitea token), SERVER (github.server_url), REPO (owner/repo), +// SHA (github.sha). Expects ./remoterig in the working dir. +import { readFileSync } from 'node:fs'; +import { createHash } from 'node:crypto'; + +const { TOKEN, SERVER, REPO, SHA } = process.env; +const BIN = 'remoterig'; +const VERSION = SHA.slice(0, 8); +const API = `${SERVER}/api/v1/repos/${REPO}`; +const H = { Authorization: `token ${TOKEN}` }; + +const ok = async (r) => { + if (!r.ok) throw new Error(`${r.status} ${r.url}\n${await r.text()}`); + const t = await r.text(); + return t ? JSON.parse(t) : null; +}; + +const bin = readFileSync(BIN); +const sha256 = createHash('sha256').update(bin).digest('hex'); +const files = { + [BIN]: bin, + [`${BIN}.sha256`]: Buffer.from(sha256 + '\n'), + 'version.txt': Buffer.from(VERSION + '\n'), +}; + +// Roll the "dev" release forward to this commit: delete the old release + tag. +const existing = await fetch(`${API}/releases/tags/dev`, { headers: H }); +if (existing.ok) { + const rel = await existing.json(); + await fetch(`${API}/releases/${rel.id}`, { method: 'DELETE', headers: H }); +} +await fetch(`${API}/tags/dev`, { method: 'DELETE', headers: H }); // ignore if absent + +const rel = await ok(await fetch(`${API}/releases`, { + method: 'POST', + headers: { ...H, 'Content-Type': 'application/json' }, + body: JSON.stringify({ + tag_name: 'dev', + target_commitish: SHA, + name: `dev (${VERSION})`, + body: `Rolling dev build ${SHA}`, + prerelease: true, + }), +})); + +for (const [name, buf] of Object.entries(files)) { + const fd = new FormData(); + fd.append('attachment', new Blob([buf]), name); + await ok(await fetch(`${API}/releases/${rel.id}/assets?name=${encodeURIComponent(name)}`, { + method: 'POST', headers: H, body: fd, + })); + console.log(`uploaded ${name}`); +} +console.log(`Published dev release ${VERSION}`); diff --git a/.gitea/workflows/build-dev.yaml b/.gitea/workflows/build-dev.yaml index c760133..68c32b4 100644 --- a/.gitea/workflows/build-dev.yaml +++ b/.gitea/workflows/build-dev.yaml @@ -42,31 +42,11 @@ jobs: # Pull-based deploy: publish the binary to a rolling "dev" release. # The Pi polls this release and self-updates (scripts/pi-update.sh); # the runner never needs to reach the closed RemoteRig network. + # Done in Node (runner image has no curl/jq/sudo; Node is present). - name: Publish to rolling dev release env: TOKEN: ${{ secrets.GITHUB_TOKEN }} SERVER: ${{ github.server_url }} REPO: ${{ github.repository }} SHA: ${{ github.sha }} - run: | - set -euo pipefail - if ! command -v jq >/dev/null; then sudo apt-get update -qq && sudo apt-get install -y -qq jq; fi - API="$SERVER/api/v1/repos/$REPO" - AUTH="Authorization: token $TOKEN" - VERSION="${SHA:0:8}" - echo "$VERSION" > version.txt - sha256sum "$BINARY_NAME" | awk '{print $1}' > "$BINARY_NAME.sha256" - - # Roll the "dev" release forward to this commit (delete old release + tag). - REL_ID=$(curl -sf -H "$AUTH" "$API/releases/tags/dev" | jq -r '.id // empty' || true) - [ -n "$REL_ID" ] && curl -sf -X DELETE -H "$AUTH" "$API/releases/$REL_ID" || true - curl -sf -X DELETE -H "$AUTH" "$API/tags/dev" || true - - REL_ID=$(curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" "$API/releases" \ - -d "{\"tag_name\":\"dev\",\"target_commitish\":\"$SHA\",\"name\":\"dev ($VERSION)\",\"body\":\"Rolling dev build $SHA\",\"prerelease\":true}" \ - | jq -r '.id') - - for f in "$BINARY_NAME" "$BINARY_NAME.sha256" version.txt; do - curl -sf -X POST -H "$AUTH" -F "attachment=@$f" "$API/releases/$REL_ID/assets?name=$f" - done - echo "Published dev release $VERSION" \ No newline at end of file + run: node .gitea/scripts/publish-release.mjs \ No newline at end of file