{"id":16608440,"url":"https://github.com/oclero/qtupdater","last_synced_at":"2026-01-16T03:15:05.725Z","repository":{"id":38412541,"uuid":"425598667","full_name":"oclero/qtupdater","owner":"oclero","description":"Updater for Qt5, enabling application auto-updates.","archived":false,"fork":false,"pushed_at":"2026-01-11T23:45:01.000Z","size":159,"stargazers_count":16,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-01-12T03:19:24.791Z","etag":null,"topics":["cmake","cpp","cpp17","qt","qt5","updater"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oclero.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-07T19:38:27.000Z","updated_at":"2025-11-18T20:49:02.000Z","dependencies_parsed_at":"2025-02-14T14:45:09.159Z","dependency_job_id":null,"html_url":"https://github.com/oclero/qtupdater","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/oclero/qtupdater","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oclero%2Fqtupdater","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oclero%2Fqtupdater/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oclero%2Fqtupdater/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oclero%2Fqtupdater/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oclero","download_url":"https://codeload.github.com/oclero/qtupdater/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oclero%2Fqtupdater/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28477054,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T03:13:13.607Z","status":"ssl_error","status_checked_at":"2026-01-16T03:11:47.863Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmake","cpp","cpp17","qt","qt5","updater"],"created_at":"2024-10-12T01:26:14.236Z","updated_at":"2026-01-16T03:15:05.713Z","avatar_url":"https://github.com/oclero.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\t\u003cimg height=\"50\" src=\"logo.svg\"\u003e\n\u003c/div\u003e\n\n# QtUpdater\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green)](https://mit-license.org/)\n[![CMake version](https://img.shields.io/badge/CMake-3.21+-064F8C?logo=cmake)](https://www.qt.io)\n[![C++ version](https://img.shields.io/badge/C++-17-00599C?logo=++)](https://www.qt.io)\n[![Qt version](https://img.shields.io/badge/Qt-6.0+-41CD52?logo=qt)](https://www.qt.io)\n\nUpdater for Qt6 (auto-updates).\n\n---\n\n### Table of Contents\n\n- [Requirements](#requirements)\n- [Features](#features)\n- [Usage](#usage)\n- [Server Specifications](#server-specifications)\n- [Example](#example)\n- [Author](#author)\n- [License](#license)\n\n---\n\n## Requirements\n\n- Platform: Windows, MacOS, Linux (except for installer auto-start).\n- [CMake 3.21+](https://cmake.org/download/)\n- [Qt 6.0+](https://www.qt.io/download-qt-installer)\n\n## Features\n\nThis library contains:\n\n- A core: `oclero::qtupdater::Updater`.\n- A controller: `oclero::qtupdater::Controller`, that may be use with QtWidgets or QtQuick/QML.\n\nIt provides these features:\n\n- Get latest update information.\n- Get changelog.\n- Get installer.\n- Execute installer.\n- Temporarly stores the update data in the `temp` folder.\n- Verify checksum after downloading and before executing installer.\n\n## Usage\n\n1. Add the library as a dependency with CMake.\n\n   ```cmake\n   find_package(QtUpdater REQUIRED)\n   ```\n\n2. Link with the library in CMake.\n\n   ```cmake\n   target_link_libraries(your_project oclero::QtUpdater)\n   ```\n\n3. Include the only necessary header in your C++ file.\n\n   ```c++\n   #include \u003coclero/qtupdater/Updater.h\u003e\n   ```\n\n4. Use the `oclero::qtupdater::Updater` class to check for updates, download changelog and installer, and execute the installer. See the [Client Example](#client) section for more details.\n\n## Server Specifications\n\n### Protocol\n\nThe protocol is the following:\n\n1. The client sends a GET request to the endpoint URL of your choice. Example (with curl):\n\n   ```bash\n   curl http://server/endpoint\\?version\\=latest\n   ```\n\n2. The server answers by sending back an _appcast_: a JSON file containing the necessary information. The _appcast_ must look like the following:\n\n   ```json\n   {\n     \"version\": \"x.y.z\",\n     \"date\": \"dd/MM/YYYY\",\n     \"checksum\": \"418397de9ef332cd0e477ff5e8ca38d4\",\n     \"checksumType\": \"md5\",\n     \"installerUrl\": \"http://server/endpoint/package-name.exe\",\n     \"changelogUrl\": \"http://server/endpoint/changelog-name.md\"\n   }\n   ```\n\n3. The client downloads the changelog from `changelogUrl`, if any provided (facultative step).\n\n4. The client downloads the installer from `installerUrl`, if any provided.\n\n5. The client installs the installer:\n   - The client may start the installer and quit, if necessary.\n   - It may also move the downloaded file to some location.\n\n## Example\n\n### Client\n\nUsage is straightforward:\n\n```c++\nusing namespace oclero::qtupdater;\n\n// Create an updater.\nUpdater updater(\"https://server/endpoint\");\n\n// Subscribe to all necessary signals. See documentation for complete list.\nQObject::connect(\u0026updater, \u0026Updater::updateAvailabilityChanged,\n                 \u0026updater, [\u0026updater]() {\n  if (updater.updateAvailability() == UpdateAvailability::Available) {\n    // An update is available!\n    qDebug() \u003c\u003c \"Update available!\"\n      \u003c\u003c \" - You have: \"\n      \u003c\u003c qPrintable(updater.currentVersion())\n      \u003c\u003c \" - Latest is: \"\n      \u003c\u003c qPrintable(updater.latestVersion());\n\n  } else if (updater.updateAvailability() == UpdateAvailability::UpToDate) {\n    // You have the latest version.\n    qDebug() \u003c\u003c \"You have the latest version.\";\n\n  } else {\n    // An error occurred.\n    // Subscribe to checkForUpdateFailed() signal for more details.\n    qDebug() \u003c\u003c \"Error.\";\n  }\n});\n\n// Start checking.\nupdater.checkForUpdate();\n```\n\nIf you server does not provide a JSON in the expected format, you can use a custom parser:\n\n```c++\nupdater.setAppCastParser([](const QByteArray\u0026 data) -\u003e oclero::qtupdater::AppCast {\n  // Your custom parsing code here.\n});\n```\n\nWhen an update is available, you can download the changelog and installer:\n\n```c++\n// See signals changelogAvailableChanged() and installerAvailableChanged().\nupdater.downloadInstaller();\n```\n\nYou can then execute the installer:\n\n```c++\n// This will start the installer and quit the application if necessary.\nupdater.installUpdate();\n```\n\n### Server\n\nA _very basic_ development server written in Python is included as testing purposes during development. Don't use in production environment!\n\n- It does not implement any security mechanism, nor HTTPS.\n- It does not cache anything and reads files from disk on each request.\n\n#### Setup\n\n```bash\n# Start with default config.\ncd examples/dev_server\npip install -r requirements.txt\npython main.py\n\n# ... Or set your own config.\npython main.py --dir /some-directory --port 8000 --address 127.0.0.1\n```\n\n#### File Structure\n\nThis development server expects files in the following format:\n\n```txt\npublic/\n  v1.0.0.json      # Version metadata\n  v1.0.0.exe       # Windows installer (or .dmg for macOS)\n  v1.0.0.md        # Changelog\n  v1.1.0.json\n  v1.1.0.exe\n  v1.1.0.md\n  # etc.\n```\n\n#### API\n\n- `GET /?version=latest` - Get latest version JSON.\n- `GET /` - Same as above.\n- `GET /?version=1.0.0` - Get specific version JSON.\n- `GET /v1.0.0.exe` - Download installer.\n- `GET /v1.0.0.md` - Download changelog.\n\n## Author\n\n**Olivier Cléro** | [email](mailto:oclero@pm.me) | [website](https://www.olivierclero.com) | [github](https://www.github.com/oclero) | [gitlab](https://www.gitlab.com/oclero)\n\n## License\n\n**QtUpdater** is available under the MIT license. See the [LICENSE](LICENSE) file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foclero%2Fqtupdater","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foclero%2Fqtupdater","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foclero%2Fqtupdater/lists"}