Update check works under either repository owner (#1747)
Release pages and assets are accepted under bherbruck or tangency-labs (exact owner/repo, github.com only); the API request stays on the old name.
This commit is contained in:
1 parent
201e055259
commit
7f9074d65c
2 files changed
+41
-4
No files matched your search
@@ -29,8 +29,16 @@ pub const REPO: &str = "bherbruck/solidcraft";
|
|||||||
pub const LATEST_API: &str = "https://api.github.com/repos/bherbruck/solidcraft/releases/latest";
|
pub const LATEST_API: &str = "https://api.github.com/repos/bherbruck/solidcraft/releases/latest";
|
||||||
/// Where Download goes when no package fits this installation.
|
/// Where Download goes when no package fits this installation.
|
||||||
pub const RELEASES_PAGE: &str = "https://github.com/bherbruck/solidcraft/releases/latest";
|
pub const RELEASES_PAGE: &str = "https://github.com/bherbruck/solidcraft/releases/latest";
|
||||||
/// Release pages and assets must be on GitHub, under this repository.
|
/// Release pages and assets must be on GitHub, under this repository. The repository is moving
|
||||||
const RELEASE_PREFIX: &str = "https://github.com/bherbruck/solidcraft/releases/";
|
/// to the `tangency-labs` organisation, so releases may name either owner (the API request stays
|
||||||
|
/// on the old name, which GitHub redirects after a transfer).
|
||||||
|
const RELEASE_PREFIXES: [&str; 2] = ["https://github.com/bherbruck/solidcraft/releases/", "https://github.com/tangency-labs/solidcraft/releases/"];
|
||||||
|
|
||||||
|
/// A release page or asset URL: github.com, one of the two owners, exactly `solidcraft`, then
|
||||||
|
/// `/releases/` (the trailing slash rules out look-alike names such as `solidcraft-evil`).
|
||||||
|
fn is_release_url(url: &str) -> bool {
|
||||||
|
RELEASE_PREFIXES.iter().any(|p| url.starts_with(p))
|
||||||
|
}
|
||||||
|
|
||||||
/// While the app stays open, automatic checks run once a day (every start checks too).
|
/// While the app stays open, automatic checks run once a day (every start checks too).
|
||||||
pub const CHECK_INTERVAL_S: f64 = 24.0 * 3600.0;
|
pub const CHECK_INTERVAL_S: f64 = 24.0 * 3600.0;
|
||||||
@@ -358,7 +366,7 @@ impl Release {
|
|||||||
notes.truncate(cut);
|
notes.truncate(cut);
|
||||||
notes.push_str("\n\n…");
|
notes.push_str("\n\n…");
|
||||||
}
|
}
|
||||||
let page = Some(s("html_url")).filter(|u| u.starts_with(RELEASE_PREFIX)).unwrap_or_else(|| RELEASES_PAGE.to_string());
|
let page = Some(s("html_url")).filter(|u| is_release_url(u)).unwrap_or_else(|| RELEASES_PAGE.to_string());
|
||||||
let assets = v
|
let assets = v
|
||||||
.get("assets")
|
.get("assets")
|
||||||
.and_then(Value::as_array)
|
.and_then(Value::as_array)
|
||||||
@@ -368,7 +376,7 @@ impl Release {
|
|||||||
.filter_map(|a| {
|
.filter_map(|a| {
|
||||||
let name = a.get("name")?.as_str()?.to_string();
|
let name = a.get("name")?.as_str()?.to_string();
|
||||||
let url = a.get("browser_download_url")?.as_str()?.to_string();
|
let url = a.get("browser_download_url")?.as_str()?.to_string();
|
||||||
url.starts_with(RELEASE_PREFIX).then(|| Asset { name, url, size: a.get("size").and_then(Value::as_u64).unwrap_or(0) })
|
is_release_url(&url).then(|| Asset { name, url, size: a.get("size").and_then(Value::as_u64).unwrap_or(0) })
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Ok(Release {
|
Ok(Release {
|
||||||
|
|||||||
@@ -441,3 +441,32 @@ fn release_notes_read_as_markdown() {
|
|||||||
}
|
}
|
||||||
assert_eq!(inline("**[x](y)**"), vec![Span::Strong("x".into())]);
|
assert_eq!(inline("**[x](y)**"), vec![Span::Strong("x".into())]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn releases_under_either_owner_are_accepted() {
|
||||||
|
let parse = |owner: &str| {
|
||||||
|
let base = format!("https://github.com/{owner}/releases");
|
||||||
|
Release::parse(
|
||||||
|
json!({"tag_name": "v1.0.0", "html_url": format!("{base}/tag/v1.0.0"), "assets": [
|
||||||
|
{"name": "solidcraft-windows-x64.msi", "browser_download_url": format!("{base}/download/v1.0.0/solidcraft-windows-x64.msi")},
|
||||||
|
]})
|
||||||
|
.to_string()
|
||||||
|
.as_bytes(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
for owner in ["bherbruck/solidcraft", "tangency-labs/solidcraft"] {
|
||||||
|
let r = parse(owner);
|
||||||
|
assert_eq!(r.page, format!("https://github.com/{owner}/releases/tag/v1.0.0"));
|
||||||
|
assert_eq!(r.assets.len(), 1, "{owner}");
|
||||||
|
}
|
||||||
|
// Any other owner, repository, host or scheme is dropped.
|
||||||
|
for owner in ["evil/solidcraft", "tangency-labs/solidcraft-evil", "tangency-labs.evil/solidcraft", "bherbruck/other"] {
|
||||||
|
let r = parse(owner);
|
||||||
|
assert_eq!(r.page, RELEASES_PAGE, "{owner}");
|
||||||
|
assert!(r.assets.is_empty(), "{owner}");
|
||||||
|
}
|
||||||
|
assert!(!is_release_url("http://github.com/tangency-labs/solidcraft/releases/x"));
|
||||||
|
assert!(!is_release_url("https://github.com.evil.example/tangency-labs/solidcraft/releases/x"));
|
||||||
|
assert!(!is_release_url("https://github.com/tangency-labs/solidcraft/issues/1"));
|
||||||
|
}
|
||||||
Reference in new issue
Block a user