diff --git a/.github/workflows/build-iso.yml b/.github/workflows/build-iso.yml index fca0ad5..e45c81a 100644 --- a/.github/workflows/build-iso.yml +++ b/.github/workflows/build-iso.yml @@ -236,8 +236,12 @@ jobs: with: subject-path: 'build/out/*.iso.part-*' - - name: Publish to ci-latest rolling prerelease - if: success() && github.ref == 'refs/heads/main' + # GitHub-only: softprops/action-gh-release uses the GitHub REST API + # which Forgejo doesn't expose at the same endpoints. When this + # workflow runs on git.s8n.ru the step below (Forgejo) handles + # publishing instead. + - name: Publish to ci-latest rolling prerelease (GitHub) + if: success() && github.ref == 'refs/heads/main' && github.server_url == 'https://github.com' # Pinned to last v2 tag confirmed to ship on node20. uses: softprops/action-gh-release@v2.0.4 with: @@ -264,6 +268,67 @@ jobs: build/out/*.pem build/out/*.spdx.json + # Forgejo equivalent: drop+recreate ci-latest release via the + # Forgejo REST API, then upload chunks. Only runs when not on GitHub. + # All ${{ }} interpolations are vetted (repo coords + signed SHA). + - name: Publish to ci-latest rolling prerelease (Forgejo) + if: success() && github.ref == 'refs/heads/main' && github.server_url != 'https://github.com' + env: + FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FORGEJO_API: ${{ github.server_url }}/api/v1 + REPO: ${{ github.repository }} + GIT_SHA: ${{ github.sha }} + run: | + set -euo pipefail + TAG="ci-latest" + REL_JSON=$(curl -fsSL -H "Authorization: token ${FORGEJO_TOKEN}" \ + "${FORGEJO_API}/repos/${REPO}/releases/tags/${TAG}" 2>/dev/null || echo "") + if [ -n "$REL_JSON" ]; then + REL_ID=$(echo "$REL_JSON" | grep -oE '"id":\s*[0-9]+' | head -1 | grep -oE '[0-9]+') + if [ -n "$REL_ID" ]; then + echo "[INFO] deleting existing ci-latest release id=$REL_ID" + curl -fsSL -X DELETE -H "Authorization: token ${FORGEJO_TOKEN}" \ + "${FORGEJO_API}/repos/${REPO}/releases/${REL_ID}" || true + curl -fsSL -X DELETE -H "Authorization: token ${FORGEJO_TOKEN}" \ + "${FORGEJO_API}/repos/${REPO}/git/refs/tags/${TAG}" || true + fi + fi + BODY="Rolling auto-build from main. Latest commit: ${GIT_SHA}. + + ISO is split into chunks. Reassemble: + cat veilor-os-*.iso.part-* > veilor-os.iso + sha256sum -c veilor-os-*.iso.parts.sha256 + + Or use test/auto-install.sh (handles reassembly automatically). + + Not a stable release — for testing only." + PAYLOAD=$(BODY="$BODY" TAG="$TAG" python3 -c " + import json,os + print(json.dumps({ + 'tag_name': os.environ['TAG'], + 'target_commitish': 'main', + 'name': 'ci-latest (auto)', + 'body': os.environ['BODY'], + 'prerelease': True, + 'draft': False, + }))") + REL_ID=$(curl -fsSL -X POST -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "$PAYLOAD" \ + "${FORGEJO_API}/repos/${REPO}/releases" | \ + grep -oE '"id":\s*[0-9]+' | head -1 | grep -oE '[0-9]+') + [ -n "$REL_ID" ] || { echo "[ERR] failed to create Forgejo release"; exit 1; } + echo "[OK] Forgejo release id=$REL_ID created" + cd build/out + for f in *.iso.part-* *.sha256; do + [ -f "$f" ] || continue + echo "[INFO] uploading $f" + curl -fsSL -X POST -H "Authorization: token ${FORGEJO_TOKEN}" \ + -F "attachment=@${f}" \ + "${FORGEJO_API}/repos/${REPO}/releases/${REL_ID}/assets?name=${f}" + done + echo "[OK] all assets uploaded to Forgejo ci-latest" + # Build log on failure: print inline + skip artifact upload to avoid # quota wall. Job log retains everything anyway. - name: Print build log on failure @@ -274,11 +339,36 @@ jobs: echo "─── anaconda program.log ───" find build/out/build/anaconda -name 'program.log' -exec tail -100 {} \; 2>/dev/null || echo "(no anaconda log)" - - name: Attach to release on tag - if: github.event_name == 'release' + # GitHub-only: same restriction as ci-latest publish. + - name: Attach to release on tag (GitHub) + if: github.event_name == 'release' && github.server_url == 'https://github.com' # Pinned to last v2 tag confirmed to ship on node20. uses: softprops/action-gh-release@v2.0.4 with: files: | build/out/*.iso build/out/*.sha256 + + # Forgejo equivalent for tag-driven release uploads. The release + # is assumed to already exist (Forgejo creates it from the tag); + # we only attach assets here. + - name: Attach to release on tag (Forgejo) + if: github.event_name == 'release' && github.server_url != 'https://github.com' + env: + FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FORGEJO_API: ${{ github.server_url }}/api/v1 + REPO: ${{ github.repository }} + REF_NAME: ${{ github.ref_name }} + run: | + set -euo pipefail + REL_JSON=$(curl -fsSL -H "Authorization: token ${FORGEJO_TOKEN}" \ + "${FORGEJO_API}/repos/${REPO}/releases/tags/${REF_NAME}") + REL_ID=$(echo "$REL_JSON" | grep -oE '"id":\s*[0-9]+' | head -1 | grep -oE '[0-9]+') + [ -n "$REL_ID" ] || { echo "[ERR] no Forgejo release for tag ${REF_NAME}"; exit 1; } + cd build/out + for f in *.iso *.sha256; do + [ -f "$f" ] || continue + curl -fsSL -X POST -H "Authorization: token ${FORGEJO_TOKEN}" \ + -F "attachment=@${f}" \ + "${FORGEJO_API}/repos/${REPO}/releases/${REL_ID}/assets?name=${f}" + done