From a02e280f421c54ef7f0b32ccfb95350ce2dd6540 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Sun, 16 Aug 2026 14:52:23 +0200 Subject: [PATCH] ota update --- .gitea/workflows/release.yml | 29 ++++++++++++++++++++++ src/config.h | 11 +++++++-- src/ota_update.cpp | 48 ++++++++++++++++++++++-------------- src/ota_update.h | 4 +-- 4 files changed, 69 insertions(+), 23 deletions(-) create mode 100644 .gitea/workflows/release.yml diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..dd8c3ae --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,29 @@ +name: Build Release +on: + push: + tags: ['v*'] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install PlatformIO + run: pip install platformio + + - name: Build firmware + run: pio run + + - name: Upload firmware.bin to release + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ gitea.release.upload_url }} + asset_path: .pio/build/esp32dev/firmware.bin + asset_name: firmware.bin + asset_content_type: application/octet-stream \ No newline at end of file diff --git a/src/config.h b/src/config.h index 6b5d440..fcd5609 100644 --- a/src/config.h +++ b/src/config.h @@ -37,7 +37,7 @@ namespace Config { // require a meaningful User-Agent instead of the HTTPClient // default, see https://operations.osmfoundation.org/policies/nominatim/. constexpr const char* NOMINATIM_HOST = "nominatim.openstreetmap.org"; - constexpr const char* NOMINATIM_USER_AGENT = "EiswolfsFlightradarCYD (github.com/Eiswolf-BG/eiswolfs-flightradar-CYD)"; + constexpr const char* NOMINATIM_USER_AGENT = "EiswolfsFlightradarCYD (git.rasmusbendtsen.dk/rasmus/flyradar)"; struct GpsPinPair { uint8_t rx; uint8_t tx; const char* label; }; constexpr GpsPinPair GPS_PIN_CANDIDATES[] = { @@ -115,5 +115,12 @@ constexpr float RANGE_STEPS_KM[] = {10.0f, 25.0f, 50.0f, 100.0f}; constexpr const char* EMERGENCY_SQUAWKS[] = {"7500", "7600", "7700"}; constexpr uint8_t EMERGENCY_SQUAWK_COUNT = 3; - constexpr uint8_t MAX_WIFI_NETWORKS = 3; +constexpr uint8_t MAX_WIFI_NETWORKS = 3; + +// Gitea OTA update (Menu > System > "Check for update") - checks +// the latest release in a private Gitea repository and downloads +// firmware.bin from there. See ota_update.cpp. + constexpr const char* GITEA_API_BASE = "git.rasmusbendtsen.dk"; + constexpr const char* GITEA_API_PATH = "/api/v1/repos/rasmus/flyradar/releases/latest"; + constexpr const char* GITEA_API_TOKEN = "YOUR_GITEA_TOKEN_HERE"; // set this! } \ No newline at end of file diff --git a/src/ota_update.cpp b/src/ota_update.cpp index 78b9bf7..2f8a5a2 100644 --- a/src/ota_update.cpp +++ b/src/ota_update.cpp @@ -13,12 +13,11 @@ namespace OtaUpdate { namespace { constexpr const char* RELEASES_API_URL = - "https://api.github.com/repos/Eiswolf-BG/eiswolfs-flightradar-CYD/releases/latest"; -// GitHub requires a meaningful User-Agent for API requests - // (otherwise HTTP 403) - same principle as Config::NOMINATIM_USER_AGENT - // for address search. - constexpr const char* USER_AGENT = - "EiswolfsFlightradarCYD-OTA/1.0 (+https://github.com/Eiswolf-BG/eiswolfs-flightradar-CYD)"; + "https://git.rasmusbendtsen.dk/api/v1/repos/rasmus/flyradar/releases/latest"; + // Gitea API uses Authorization: token header instead of + // User-Agent. The token is set in Config::GITEA_API_TOKEN. + // Gitea serves downloads directly (no redirect), so + // setFollowRedirects is not needed. bool parseVersion(const char* s, int& major, int& minor, int& patch) { major = minor = patch = 0; @@ -56,7 +55,12 @@ CheckInfo checkForUpdate() { Serial.println("[OTA] Check failed: http.begin() returned false."); return info; } - http.addHeader("User-Agent", USER_AGENT); + http.addHeader("User-Agent", "EiswolfsFlightradarCYD-OTA/1.0"); + if (Config::GITEA_API_TOKEN[0]) { + String auth = "token "; + auth += Config::GITEA_API_TOKEN; + http.addHeader("Authorization", auth); + } int code = http.GET(); if (code != HTTP_CODE_OK) { @@ -121,21 +125,25 @@ bool performUpdate(const char* url, void (*onProgress)(uint8_t percent)) { Serial.printf("[OTA] Starting: url=%s freeHeap=%u RSSI=%ddBm\n", url, (unsigned)ESP.getFreeHeap(), WiFi.RSSI()); - WiFiClientSecure client; +WiFiClientSecure client; client.setInsecure(); client.setTimeout(15000); -// IMPORTANT: GitHub's "browser_download_url" for release assets is NOT - // a direct download link, but first returns an HTTP 301/302 redirect - // to a signed objects.githubusercontent.com URL. HTTPUpdate does NOT - // follow redirects by default (HTTPC_DISABLE_FOLLOW_REDIRECTS is the - // default) - without this line the download aborts with HTTP_UPDATE_FAILED - // because only the redirect response arrives instead of the .bin file. See - // e.g. espressif/arduino-esp32#3020. HTTPC_STRICT_FOLLOW_REDIRECTS - // suffices since we only use GET. - httpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); + // Gitea serves downloads directly (no redirect like GitHub's S3), + // but private repos still need the Authorization header. Use the + // HTTPClient overload of httpUpdate.update() so we can set it. + HTTPClient http; + if (!http.begin(client, url)) { + Serial.println("[OTA] Failed: http.begin() returned false for download URL."); + return false; + } + if (Config::GITEA_API_TOKEN[0]) { + String auth = "token "; + auth += Config::GITEA_API_TOKEN; + http.addHeader("Authorization", auth); + } -// We show a brief success message ourselves after successful installation, + // We show a brief success message ourselves after successful installation, // before the device reboots - see // menu_screen.cpp::runOtaUpdateScreen(). httpUpdate.rebootOnUpdate(false); @@ -156,7 +164,9 @@ bool performUpdate(const char* url, void (*onProgress)(uint8_t percent)) { } }); - t_httpUpdate_return result = httpUpdate.update(client, url); + t_httpUpdate_return result = httpUpdate.update(http); + + http.end(); if (result != HTTP_UPDATE_OK) { Serial.printf("[OTA] Failed: result=%d error=%d (%s) freeHeap=%u\n", (int)result, diff --git a/src/ota_update.h b/src/ota_update.h index b4a2303..42b6da2 100644 --- a/src/ota_update.h +++ b/src/ota_update.h @@ -2,7 +2,7 @@ #include // Firmware update over WiFi (Menu > System > "Check for update") - -// checks against the latest version in the GitHub repository (Releases API) and +// checks against the latest version in a private Gitea repository (Releases API) and // installs it on the device directly upon confirmation, without cable/ // web flasher. Blocking, synchronous HTTPS calls - only executed on // explicit button press (no background polling), analogous to @@ -23,7 +23,7 @@ namespace OtaUpdate { char downloadUrl[192] = {0}; }; -// Queries the GitHub Releases API for the latest release, compares +// Queries the Gitea Releases API for the latest release, compares // its version number (tag name, "v" prefix is ignored) against // Config::APP_VERSION and looks for the "firmware.bin" attachment in the release. // CheckResult::Error on any error along the way (no WiFi, timeout,