name: Release # Tag-triggered: when `git push origin ` lands, this builds the # release tarball + the live-installer ISO, and publishes them both to # the Forgejo releases page. Boxes POST /api/furtka/update to pull the # tarball; fresh-install users download the ISO from the release page. # # Runs on the self-hosted runner because iso/build.sh needs privileged # docker access (mkarchiso wants root + loop mounts), and because the # ubuntu-latest Forgejo hosted runner doesn't carry the docker socket # bind-mount the build needs. Self-hosted adds ~5-7 min to the release # (ISO build) but keeps the release page self-contained. # # Version tags only (CalVer like 26.0-alpha, 26.1, 27.0-beta). Random # tags are ignored by the [0-9]* prefix. on: push: tags: ['[0-9]*'] jobs: release: runs-on: self-hosted timeout-minutes: 45 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # changelog section extraction needs history - name: Install prerequisites # Alpine runner is near-empty: we need curl + python3 for the # publish script, bash for the build scripts. run: apk add --no-cache curl python3 bash - name: Build release tarball run: ./scripts/build-release-tarball.sh "${GITHUB_REF_NAME}" - name: Build live-installer ISO # Same script build-iso.yml uses on every main push. Re-running # here is intentional: guarantees the ISO matches the exact # tagged commit without coordinating across workflows. Step-level # continue-on-error so an ISO build flake doesn't block the # core tarball (which is what boxes need for self-update) from # publishing. continue-on-error: true id: build_iso run: ./iso/build.sh - name: Move ISO into dist/ # publish-release.sh attaches dist/furtka-.iso if present. # Skipped gracefully when the build step above failed. if: steps.build_iso.outcome == 'success' run: | iso=$(ls iso/out/*.iso | head -1) cp "$iso" "dist/furtka-${GITHUB_REF_NAME}.iso" - name: Publish to Forgejo releases env: FORGEJO_TOKEN: ${{ secrets.FORGEJO_RELEASE_TOKEN }} run: ./scripts/publish-release.sh "${GITHUB_REF_NAME}"