Secret Scan / scan (push) Successful in 24s
Build App (Preview) / compute-version (pull_request) Successful in 6s
Secret Scan / scan (pull_request) Successful in 6s
Build App (Preview) / create-release (pull_request) Successful in 1s
Build App (Preview) / build-macos (pull_request) Successful in 2m39s
Build App (Preview) / build-windows (pull_request) Successful in 4m44s
Build App (Preview) / build-linux (pull_request) Successful in 6m17s
Build App (Preview) / prune-previews (pull_request) Successful in 1s
Final review pass gave this a clean bill of health overall but named
three small things:
- get_app_version() and check_for_updates() each read
option_env!("TRIPLE_C_BUILD_SUFFIX") independently with slightly
different idioms — if one were ever edited alone, the About panel and
the update check could silently disagree about whether this is a
preview build. Extracted preview_build_suffix() as the single place
that reads and classifies it.
- pick_update's doc comment described the unparseable-tag case as a
`-preview.<sha>` suffix; the actual tag build-app-preview.yml creates is
`preview-<sha>` (no version, no dot) — already correct in the
neighboring GitHubRelease::prerelease comment, just not here.
- That same prerelease comment claimed defence against a preview release
leaking through backfill-releases.yml, but a preview's tag already fails
semver parsing on its own — this field's actual job is the case parsing
can't catch: a normally-tagged release someone flags prerelease on
Gitea (a hotfix candidate, an RC) that a backfill would otherwise mirror
as-is.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FGjXq6fqtAFHdbhk4f3PfZ
67 lines
2.5 KiB
Rust
67 lines
2.5 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
/// Info returned to the frontend about an available update.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct UpdateInfo {
|
|
pub version: String,
|
|
pub tag_name: String,
|
|
pub release_url: String,
|
|
pub body: String,
|
|
pub assets: Vec<ReleaseAsset>,
|
|
pub published_at: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ReleaseAsset {
|
|
pub name: String,
|
|
pub browser_download_url: String,
|
|
pub size: u64,
|
|
}
|
|
|
|
/// GitHub API release response (internal).
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
pub struct GitHubRelease {
|
|
pub tag_name: String,
|
|
pub html_url: String,
|
|
pub body: String,
|
|
pub assets: Vec<GitHubAsset>,
|
|
pub published_at: String,
|
|
/// Whether GitHub itself has this release marked as a prerelease.
|
|
/// `#[serde(default)]` rather than required: every response GitHub sends
|
|
/// carries this, but nothing here should refuse to parse the rest of a
|
|
/// release over one missing field. Defaults to `false` (offered) rather
|
|
/// than `true` (excluded) — a missing field only happens if GitHub's API
|
|
/// shape changes, and "API changed, therefore updates silently stop
|
|
/// working forever" is the worse failure of the two.
|
|
///
|
|
/// `build-app.yml`'s own mirror never publishes a prerelease, but
|
|
/// `.gitea/workflows/backfill-releases.yml` forwards every Gitea release
|
|
/// unfiltered, `prerelease` included. A preview release's `preview-<sha>`
|
|
/// tag already fails semver parsing on its own, so this field is not what
|
|
/// stops *that* case — it is what stops the case tag-parsing can't catch:
|
|
/// a normally-tagged release (`v0.4.13`) that someone marks as a
|
|
/// prerelease on Gitea (a hotfix candidate, an RC) and a backfill then
|
|
/// mirrors as-is. Real defence for that case, not a no-op.
|
|
#[serde(default)]
|
|
pub prerelease: bool,
|
|
}
|
|
|
|
/// GitHub API asset response (internal).
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
pub struct GitHubAsset {
|
|
pub name: String,
|
|
pub browser_download_url: String,
|
|
pub size: u64,
|
|
}
|
|
|
|
/// Info returned to the frontend about an available container image update.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ImageUpdateInfo {
|
|
/// The remote digest (e.g. sha256:abc...)
|
|
pub remote_digest: String,
|
|
/// The local digest, if available
|
|
pub local_digest: Option<String>,
|
|
/// When the remote image was last updated (if known)
|
|
pub remote_updated_at: Option<String>,
|
|
}
|