name: Build and Release on: workflow_dispatch: schedule: # Midnight UTC every day (Actions cron is UTC). For local midnight, shift hours, e.g. 22:00 UTC ≈ midnight CET (winter). - cron: "0 0 * * *" concurrency: group: nightly-release-${{ github.repository }} cancel-in-progress: true jobs: build-and-release: runs-on: ubuntu-latest permissions: contents: write steps: # Clone from Gitea (this runner cannot reach github.com for actions/checkout@v4) - name: Checkout repository env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail cd "${GITHUB_WORKSPACE}" SERVER="${{ github.server_url }}" REPO="${{ github.repository }}" SHA="${{ github.sha }}" HOST="${SERVER#*://}" HOST="${HOST%%/*}" if [ -n "${GITHUB_TOKEN:-}" ]; then URL="https://oauth2:${GITHUB_TOKEN}@${HOST}/${REPO}.git" else URL="${SERVER}/${REPO}.git" fi git init git remote add origin "$URL" git fetch --depth 1 origin "$SHA" git checkout --force FETCH_HEAD - name: Set up build tools run: | sudo apt-get update sudo apt-get install -y zip rsync - name: Build zip package run: make zip # Gitea has no `gh` CLI; use REST API (same host as checkout). - name: Nightly release (single tag, updated in place) env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SERVER_URL: ${{ github.server_url }} run: | set -euo pipefail TAG=nightly ZIP="./output/OmniNX Downloader.zip" FULL="${{ github.repository }}" OWNER="${FULL%%/*}" REPO_NAME="${FULL#*/}" SHA="${{ github.sha }}" REF="${{ github.ref_name }}" API="${SERVER_URL%/}/api/v1" git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git tag -f "$TAG" git push origin "refs/tags/$TAG" --force NOTES="Single nightly build artifact (updated on schedule or manual run). **Commit:** \`${SHA}\` **Branch:** \`${REF}\` **Built:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" AUTH=(-H "Authorization: token ${GITHUB_TOKEN}") # Remove existing release so we can recreate with a fresh attachment (Gitea has no clobber). HTTP_CODE=$(curl -sS -o /tmp/gitea_rel.json -w "%{http_code}" "${AUTH[@]}" \ "${API}/repos/${OWNER}/${REPO_NAME}/releases/tags/${TAG}") if [ "$HTTP_CODE" = "200" ]; then RID=$(python3 -c "import json; print(json.load(open('/tmp/gitea_rel.json'))['id'])") curl -sS -X DELETE "${AUTH[@]}" \ "${API}/repos/${OWNER}/${REPO_NAME}/releases/${RID}" fi export NOTES TAG JSON_BODY=$(python3 <<'PY' import json, os print(json.dumps({ "tag_name": os.environ["TAG"], "name": "Nightly", "body": os.environ["NOTES"], "draft": False, "prerelease": True, })) PY ) curl -sS -f -X POST "${AUTH[@]}" -H "Content-Type: application/json" \ -d "$JSON_BODY" \ "${API}/repos/${OWNER}/${REPO_NAME}/releases" | tee /tmp/gitea_create.json RID=$(python3 -c "import json; print(json.load(open('/tmp/gitea_create.json'))['id'])") export ASSET_NAME="OmniNX Downloader.zip" QNAME=$(python3 -c "import urllib.parse,os; print(urllib.parse.quote(os.environ['ASSET_NAME']))") curl -sS -f -X POST "${AUTH[@]}" \ -F "attachment=@${ZIP};filename=${ASSET_NAME}" \ "${API}/repos/${OWNER}/${REPO_NAME}/releases/${RID}/assets?name=${QNAME}"