name: OTA build on: push: branches: - '**' workflow_dispatch: jobs: build-ota: runs-on: ubuntu-latest timeout-minutes: 60 steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install PlatformIO run: | python -m pip install --upgrade pip pip install platformio - name: Build OTA package run: python scripts/build_ota_package.py - name: Prepare direct OTA files run: | set -eu rm -rf dist/ota mkdir -p dist/ota found=0 for pkg in dist/*.tslpkg; do [ -f "$pkg" ] || continue cp "$pkg" dist/ota/ found=1 done if [ "$found" -eq 0 ]; then echo 'No .tslpkg OTA package was produced.' >&2 exit 1 fi find dist/ota -maxdepth 1 -type f | sort - name: Upload backup OTA artifact ZIP uses: actions/upload-artifact@v3 with: name: ota-files path: dist/ota/* if-no-files-found: error - name: Publish raw OTA files to rolling release env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} run: | python - <<'PY' import json import mimetypes import os import sys from pathlib import Path from urllib.request import Request, urlopen from urllib.error import HTTPError server = os.environ['GITHUB_SERVER_URL'] repo = os.environ['GITHUB_REPOSITORY'] token = os.environ.get('GITEA_TOKEN') if not token: print('GITEA_TOKEN missing', file=sys.stderr) sys.exit(1) api = f"{server}/api/v1/repos/{repo}" headers = { 'Authorization': f'token {token}', 'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': 'Hermes-Agent' } tag = 'ota-builds' release_name = 'OTA Builds' body = 'Rolling OTA files from the latest successful push build.' def req(url, method='GET', data=None, extra_headers=None): h = dict(headers) if extra_headers: h.update(extra_headers) payload = None if data is None else json.dumps(data).encode() r = Request(url, data=payload, headers=h, method=method) with urlopen(r, timeout=120) as resp: body = resp.read() if not body: return None text = body.decode() try: return json.loads(text) except json.JSONDecodeError: return text try: release = req(f"{api}/releases/tags/{tag}") except HTTPError as e: if e.code != 404: raise release = req(f"{api}/releases", method='POST', data={ 'tag_name': tag, 'target': os.environ.get('GITHUB_SHA', ''), 'name': release_name, 'body': body, 'draft': False, 'prerelease': True, }) release_id = release['id'] existing = req(f"{api}/releases/{release_id}/assets") or [] for asset in existing: rid = asset['id'] req(f"{api}/releases/{release_id}/assets/{rid}", method='DELETE') for path in sorted(Path('dist/ota').glob('*')): if not path.is_file(): continue mime = mimetypes.guess_type(path.name)[0] or 'application/octet-stream' upload_headers = { 'Authorization': f'token {token}', 'Content-Type': mime, 'Accept': 'application/json', 'User-Agent': 'Hermes-Agent' } url = f"{api}/releases/{release_id}/assets?name={path.name}" data = path.read_bytes() r = Request(url, data=data, headers=upload_headers, method='POST') with urlopen(r, timeout=240) as resp: print(resp.read().decode()) PY