Skip to content

feat(webservices): add GitHub firmware update checking - #189

Draft
byamo wants to merge 9 commits into
matejdro:mainfrom
byamo:feat/github-firmware-updates
Draft

feat(webservices): add GitHub firmware update checking#189
byamo wants to merge 9 commits into
matejdro:mainfrom
byamo:feat/github-firmware-updates

Conversation

@byamo

@byamo byamo commented Jul 28, 2026

Copy link
Copy Markdown

This PR adds the ability to check for and download firmware updates directly from GitHub repositories (coredevices/PebbleOS).

Features:

  • GitHub API Integration: Fetch releases from GitHub repositories.
  • Filter PBZ files by watch hardware platform revision.
  • Filter releases by firmware version (only show newer versions than currently installed)
  • Users can still manually select PBZ files or download directly from GitHub.
  • Core Devices Only: GitHub auto-download is restricted to core devices (asterix, obelix, getafix)
  • Proper Error Handling: Handles API errors, missing assets, and connection issues.

Technical Details:

  • New API types: GithubRelease, GithubSource, GithubToken.
  • New data layer: GithubClientImpl with proper Kotlin Serialization mapping.
  • UI integration in firmware update screen with loading states.

Partially addresses #34

byamo added 7 commits July 28, 2026 21:05
Add data classes for GitHub API integration:
- GithubRelease: represents a GitHub release with assets
- GithubSource: represents a GitHub repository source
- GithubToken: represents GitHub authentication token

These types enable fetching firmware releases from GitHub
Add suspend functions for fetching GitHub releases and downloading assets:
- fetchGithubReleases(source: GithubSource, token: String?): Outcome<List<GithubRelease>>
- downloadGithubAsset(asset: GithubAsset, token: String?): Outcome<File>
Implement GithubClientImpl for fetching releases from GitHub API:
- Fetch and parse releases from GitHub repositories
- Map GitHub assets to domain model (GithubAsset)
- Handle browser_download_url mapping to download_url
- Filter out assets without download URLs
- Add proper error handling and logging
- Add fetchGithubReleases implementation calling GithubClient
- Add downloadGithubAsset implementation with context-aware cache directory
- Use Dispatchers.IO for background operations
- Add GithubPreferencesRepository for managing GitHub preferences
- Add GithubProviders for dependency injection setup
- Enable configuration of GitHub API settings
- Add checkGithubUpdates() function to fetch and filter releases
- Add downloadFromGithub() function to download firmware assets
- Filter releases by watch hardware platform revision (e.g., obelix_pvt)
- Filter releases by firmware version (show only newer versions)
- Add githubReleases and downloadProgress state flows
- Handle empty results (watch is up to date)
- Add Check GitHub for updates button
- Display GitHub releases with PBZ assets in cards
- Show release tag, name, and published date
- Add loading state with CircularProgressIndicator
- Add error handling for GitHub API failures
- Restrict GitHub auto-download to core devices (asterix, obelix, getafix)
- Fix locale observation in Composable functions
- Add string resources for GitHub-related messages
}
}

private var client: HttpClient? = null

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should share HttpClient with all other app parts (such as appstore). Http client is a pretty heavy thing and should only be created once and reused.

}

@ContributesTo(AppScope::class)
interface GithubPreferencesProviders {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DI should be in a separate file than the repository.

}

object GithubPreferencesSerializer : androidx.datastore.core.Serializer<GithubPreferences> {
private val json = Json {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Json is created multiple times throughout the app. This is a bit wasteful. Can we create it once via DI and then inject it everywhere?

}
}

object GithubPreferencesSerializer : androidx.datastore.core.Serializer<GithubPreferences> {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not use objects, use DI + Singleton instead.

byamo added 2 commits July 31, 2026 23:22
…ializer

- Use @ContributesBinding for GithubClientImpl instead of @ContributesTo providers
- Add GithubClient interface in API module for better DI practices
- Update WebservicesClientImpl to inject GithubClient interface instead of concrete class
- Remove GithubProviders interface (boilerplate)
- Replace @contextual with static InstantComponentSerializer for published_at field
- Move companion object to end of file
- Replace withContext(Dispatchers.IO) with withIO {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants