From e1eda7977c43f6958dc707b0fcb9582b5be87d90 Mon Sep 17 00:00:00 2001 From: Reactor Scram Date: Wed, 24 Apr 2024 11:42:12 -0500 Subject: [PATCH] refactor: Make published artifact names consistent and use permalinks (#4746) ```[tasklist] - [x] Update website - [x] Update blog entry with old link - [ ] ~~Replace Github URL in GUI Client updater with our own links~~ - [ ] Wait for CI to go green ``` Refs #4531 This proposes a unified scheme for deb and MSI packages, and moves Windows to that scheme. This breaks compatibility. Existing Clients won't recognize the new asset names once this is merged, so they won't show the "Firezone 1.0.0 is available" pop-up. --------- Co-authored-by: Jamil Bou Kheir --- .github/workflows/_build_artifacts.yml | 15 +- .github/workflows/_tauri.yml | 14 +- .../src-tauri/src/client/debug_commands.rs | 5 +- rust/gui-client/src-tauri/src/client/gui.rs | 41 ++- .../src-tauri/src/client/updates.rs | 326 +++++++----------- scripts/Makefile | 8 +- scripts/build/tauri-rename-windows.sh | 14 +- scripts/build/tauri-upload-windows.sh | 6 +- scripts/gateway-systemd-install.sh | 18 +- website/next.config.mjs | 4 + website/redirects.js | 142 ++++++++ .../src/app/blog/mar-2024-update/readme.mdx | 3 +- .../kb/user-guides/linux-client/readme.mdx | 6 +- .../kb/user-guides/windows-client/readme.mdx | 2 +- 14 files changed, 344 insertions(+), 260 deletions(-) create mode 100644 website/redirects.js diff --git a/.github/workflows/_build_artifacts.yml b/.github/workflows/_build_artifacts.yml index 71a267c5e..59523aaef 100644 --- a/.github/workflows/_build_artifacts.yml +++ b/.github/workflows/_build_artifacts.yml @@ -149,23 +149,23 @@ jobs: arch: - target: x86_64-unknown-linux-musl - shortname: x64 + shortname: x86_64 platform: linux/amd64 - target: aarch64-unknown-linux-musl # E.g. AWS Graviton - shortname: arm64 + shortname: aarch64 platform: linux/arm64 - target: armv7-unknown-linux-musleabihf # E.g. Raspberry Pi platform: linux/arm/v7 - shortname: arm + shortname: armv7 name: - package: firezone-linux-client - artifact: linux-client + artifact: firezone-client-headless-linux image_name: client - package: firezone-relay - artifact: relay + artifact: firezone-relay image_name: relay - package: firezone-gateway - artifact: gateway + artifact: firezone-gateway image_name: gateway - package: snownet-tests artifact: snownet-tests @@ -174,7 +174,8 @@ jobs: artifact: http-test-server image_name: http-test-server env: - BINARY_DEST_PATH: ${{ matrix.name.artifact }}-${{ matrix.arch.shortname }} + # mark:automatic-version + BINARY_DEST_PATH: ${{ matrix.name.artifact }}_1.0.0_${{ matrix.arch.shortname }} outputs: client_image: ${{ steps.image-name.outputs.client_image }} relay_image: ${{ steps.image-name.outputs.relay_image }} diff --git a/.github/workflows/_tauri.yml b/.github/workflows/_tauri.yml index 336c388f0..b45019a9d 100644 --- a/.github/workflows/_tauri.yml +++ b/.github/workflows/_tauri.yml @@ -36,12 +36,12 @@ jobs: syms-artifact: rust/gui-client/firezone-linux-gui-client-amd64.dwp pkg-artifact: rust/gui-client/firezone-linux-gui-client_amd64.deb - runs-on: windows-2019 - binary-dest-path: firezone-windows-client + binary-dest-path: firezone-client-gui-windows rename-script: ../../scripts/build/tauri-rename-windows.sh upload-script: ../../scripts/build/tauri-upload-windows.sh - exe-artifact: rust/gui-client/firezone-windows-client-x64.exe - syms-artifact: rust/gui-client/firezone-windows-client-x64.pdb - pkg-artifact: rust/gui-client/firezone-windows-client-x64.msi + exe-artifact: rust/gui-client/firezone-client-gui-windows-x86_64.exe + syms-artifact: rust/gui-client/firezone-client-gui-windows-x86_64.pdb + pkg-artifact: rust/gui-client/firezone-client-gui-windows-x86_64.msi env: BINARY_DEST_PATH: ${{ matrix.binary-dest-path }} AZURE_KEY_VAULT_URI: ${{ secrets.AZURE_KEY_VAULT_URI }} @@ -83,21 +83,21 @@ jobs: - name: Upload exe uses: actions/upload-artifact@v4 with: - name: ${{ matrix.binary-dest-path }}-exe + name: ${{ matrix.binary-dest-path }}-x86_64-exe path: | ${{ matrix.exe-artifact }} if-no-files-found: error - name: Upload debug symbols uses: actions/upload-artifact@v4 with: - name: ${{ matrix.binary-dest-path }}-syms + name: ${{ matrix.binary-dest-path }}-x86_64-syms path: | ${{ matrix.syms-artifact }} if-no-files-found: error - name: Upload package uses: actions/upload-artifact@v4 with: - name: ${{ matrix.binary-dest-path }}-pkg + name: ${{ matrix.binary-dest-path }}-x86_64-pkg path: | ${{ matrix.pkg-artifact }} if-no-files-found: error diff --git a/rust/gui-client/src-tauri/src/client/debug_commands.rs b/rust/gui-client/src-tauri/src/client/debug_commands.rs index 4e26b4a72..856194426 100644 --- a/rust/gui-client/src-tauri/src/client/debug_commands.rs +++ b/rust/gui-client/src-tauri/src/client/debug_commands.rs @@ -29,8 +29,9 @@ fn check_for_updates() -> Result<()> { client::logging::debug_command_setup()?; let rt = tokio::runtime::Runtime::new().unwrap(); - let release = rt.block_on(client::updates::check()); - tracing::info!("{:?}", release.as_ref().map(serde_json::to_string)); + let release = rt.block_on(client::updates::check())?; + tracing::info!("{:#?}", serde_json::to_string(&release)); + tracing::info!("{:?}", release.download_url()); Ok(()) } diff --git a/rust/gui-client/src-tauri/src/client/gui.rs b/rust/gui-client/src-tauri/src/client/gui.rs index 5d7343547..5bc99dd65 100644 --- a/rust/gui-client/src-tauri/src/client/gui.rs +++ b/rust/gui-client/src-tauri/src/client/gui.rs @@ -17,6 +17,7 @@ use system_tray_menu::Event as TrayMenuEvent; use tauri::{Manager, SystemTray, SystemTrayEvent}; use tokio::sync::{mpsc, oneshot, Notify}; use tunnel_wrapper::CallbackHandler; +use url::Url; use ControllerRequest as Req; @@ -403,16 +404,22 @@ async fn check_for_updates(ctlr_tx: CtlrTx, always_show_update_notification: boo let release = client::updates::check() .await .context("Error in client::updates::check")?; + let Some(download_url) = release.download_url() else { + tracing::warn!("No installer for this OS/arch online"); + return Ok(()); + }; let our_version = client::updates::current_version()?; - let github_version = &release.tag_name; if always_show_update_notification || (our_version < release.tag_name) { - tracing::info!(?our_version, ?github_version, "Github has a new release"); + tracing::info!(?our_version, ?release.tag_name, "There is a new release"); // We don't necessarily need to route through the Controller here, but if we // want a persistent "Click here to download the new MSI" button, this would allow that. ctlr_tx - .send(ControllerRequest::UpdateAvailable(release)) + .send(ControllerRequest::UpdateAvailable { + download_url: download_url.clone(), + version_to_download: release.tag_name, + }) .await .context("Error while sending UpdateAvailable to Controller")?; return Ok(()); @@ -420,8 +427,8 @@ async fn check_for_updates(ctlr_tx: CtlrTx, always_show_update_notification: boo tracing::info!( ?our_version, - ?github_version, - "Our release is newer than, or the same as Github's latest" + ?release.tag_name, + "Our release is newer than, or the same as, the latest" ); Ok(()) } @@ -474,8 +481,11 @@ pub(crate) enum ControllerRequest { SignIn, SystemTrayMenu(TrayMenuEvent), TunnelReady, - UpdateAvailable(client::updates::Release), - UpdateNotificationClicked(client::updates::Release), + UpdateAvailable { + download_url: Url, + version_to_download: semver::Version, + }, + UpdateNotificationClicked(Url), } struct Controller { @@ -655,8 +665,11 @@ impl Controller { self.tunnel_ready = true; self.refresh_system_tray_menu()?; } - Req::UpdateAvailable(release) => { - let title = format!("Firezone {} available for download", release.tag_name); + Req::UpdateAvailable { + download_url, + version_to_download, + } => { + let title = format!("Firezone {} available for download", version_to_download); // We don't need to route through the controller here either, we could // use the `open` crate directly instead of Tauri's wrapper @@ -665,16 +678,12 @@ impl Controller { &title, "Click here to download the new version.", self.ctlr_tx.clone(), - Req::UpdateNotificationClicked(release), + Req::UpdateNotificationClicked(download_url), )?; } - Req::UpdateNotificationClicked(release) => { + Req::UpdateNotificationClicked(download_url) => { tracing::info!("UpdateNotificationClicked in run_controller!"); - tauri::api::shell::open( - &self.app.shell_scope(), - release.browser_download_url, - None, - )?; + tauri::api::shell::open(&self.app.shell_scope(), download_url, None)?; } } Ok(()) diff --git a/rust/gui-client/src-tauri/src/client/updates.rs b/rust/gui-client/src-tauri/src/client/updates.rs index 44ff2a295..e14e71073 100644 --- a/rust/gui-client/src-tauri/src/client/updates.rs +++ b/rust/gui-client/src-tauri/src/client/updates.rs @@ -1,58 +1,61 @@ //! Module to check the Github repo for new releases use crate::client::about::get_cargo_version; -use std::{fmt, str::FromStr}; +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use std::str::FromStr; use url::Url; /// GUI-friendly release struct -#[derive(serde::Serialize)] +/// +/// Serialize is derived for debugging +#[derive(Deserialize, Serialize)] pub(crate) struct Release { - /// URL that will instantly try to download the MSI to disk + /// All assets in a given release + assets: Vec, + /// Git tag name / Cargo version name /// - /// e.g. - pub browser_download_url: Url, - /// Git tag name - /// - /// e.g. 1.0.0-pre.8 + /// e.g. 1.0.1 pub tag_name: semver::Version, } -impl Release { - /// Parses the release JSON, finds the MSI asset, and returns info about the latest MSI - fn from_str(s: &str) -> Result { - let ReleaseDetails { assets, tag_name } = serde_json::from_str(s)?; - let asset = assets - .into_iter() - .find(|asset| asset.name == ASSET_NAME) - .ok_or(Error::NoSuchAsset)?; - - Ok(Release { - browser_download_url: asset.browser_download_url, - tag_name, - }) - } +#[derive(Deserialize, Serialize)] +struct Asset { + browser_download_url: Url, + /// Name of the asset, e.g. `firezone-client-gui-windows-x86_64.msi` + name: String, } -impl fmt::Debug for Release { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Release") - .field( - "browser_download_url", - &self.browser_download_url.to_string(), - ) - .field("tag_name", &self.tag_name.to_string()) - .finish() +impl Release { + /// Download URL for current OS and arch + pub fn download_url(&self) -> Option<&Url> { + self.download_url_for(std::env::consts::ARCH, std::env::consts::OS) + } + + /// Download URL for the first asset that matches the given arch, OS, and package type + fn download_url_for(&self, arch: &str, os: &str) -> Option<&Url> { + let package = match os { + "linux" => "deb", + "macos" => "dmg", // Unused in practice + "windows" => "msi", + _ => panic!("Don't know what package this OS uses"), + }; + + let prefix = format!("firezone-client-gui-{os}_"); + let suffix = format!("_{arch}.{package}"); + + let mut iter = self + .assets + .iter() + .filter(|x| x.name.starts_with(&prefix) && x.name.ends_with(&suffix)); + iter.next().map(|asset| &asset.browser_download_url) } } #[derive(Debug, thiserror::Error)] pub(crate) enum Error { - #[error("Non-OK HTTP status")] - HttpStatus(reqwest::StatusCode), #[error(transparent)] JsonParse(#[from] serde_json::Error), - #[error("No such asset `{ASSET_NAME}` in the latest release")] - NoSuchAsset, #[error("Our own semver in the exe is invalid, this should be impossible")] OurVersionIsInvalid(semver::Error), #[error(transparent)] @@ -65,30 +68,14 @@ const LATEST_RELEASE_API_URL: &str = /// const GITHUB_API_VERSION: &str = "2022-11-28"; -/// The name of the Windows MSI / Linux deb asset. -/// -/// These ultimately come from `cd.yml`, `git grep WCPYPXZF` -#[cfg(target_os = "linux")] -const ASSET_NAME: &str = "firezone-linux-gui-client_amd64.deb"; - -/// Unused - The Tauri client is not supported for macOS -#[cfg(target_os = "macos")] -const ASSET_NAME: &str = "firezone-mac-unused-client_aarch64.dmg"; - -#[cfg(target_os = "windows")] -const ASSET_NAME: &str = "firezone-windows-client-x64.msi"; - /// Returns the latest release, even if ours is already newer -pub(crate) async fn check() -> Result { +pub(crate) async fn check() -> Result { let client = reqwest::Client::builder().build()?; + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; // - // This would change for aarch64 support - let user_agent = format!( - // TODO: remove 'windows' - "Firezone Client/{:?} (Windows; Win64; x64)", - current_version() - ); + let user_agent = format!("Firezone Client/{:?} ({os}; {arch})", current_version()); // Reqwest follows up to 10 redirects by default // https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.redirect @@ -101,11 +88,11 @@ pub(crate) async fn check() -> Result { .await?; let status = response.status(); if status != reqwest::StatusCode::OK { - return Err(Error::HttpStatus(status)); + anyhow::bail!("HTTP status: {status}"); } let response = response.text().await?; - Release::from_str(&response) + Ok(serde_json::from_str(&response)?) } // TODO: DRY with about.rs @@ -113,156 +100,109 @@ pub(crate) fn current_version() -> Result { semver::Version::from_str(&get_cargo_version()).map_err(Error::OurVersionIsInvalid) } -/// Deserializable struct that matches Github's JSON -#[derive(serde::Deserialize)] -struct ReleaseDetails { - assets: Vec, - tag_name: semver::Version, -} - -#[derive(serde::Deserialize)] -struct Asset { - browser_download_url: Url, - /// Name of the asset, e.g. `firezone-windows-client-x64.msi` - name: String, -} - #[cfg(test)] mod tests { use std::str::FromStr; - /// A cut-down example of the real JSON from Github's API - /// - /// The real one is about 32 KB, most of which is details about the assets, - /// so it'll get bigger over time if new assets are added. - /// - /// The GraphQL API couldn't be used because it needs a token. - const RELEASES_LATEST_JSON: &str = r#" - { - "url": "https://api.github.com/repos/firezone/firezone/releases/138228264", - "assets_url": "https://api.github.com/repos/firezone/firezone/releases/138228264/assets", - "upload_url": "https://uploads.github.com/repos/firezone/firezone/releases/138228264/assets{?name,label}", - "html_url": "https://github.com/firezone/firezone/releases/tag/1.0.0-pre.8", - "id": 138228264, - "author": { - "login": "github-actions[bot]", - "id": 41898282, - "node_id": "MDM6Qm90NDE4OTgyODI=", - "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/github-actions%5Bbot%5D", - "html_url": "https://github.com/apps/github-actions", - "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", - "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", - "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", - "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", - "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", - "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", - "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", - "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", - "type": "Bot", - "site_admin": false - }, - "node_id": "RE_kwDOD12Hpc4IPTIo", - "tag_name": "1.0.0-pre.8", - "target_commitish": "refs/heads/main", - "name": "1.0.0-pre.8", - "draft": false, - "prerelease": false, - "created_at": "2024-01-24T00:23:23Z", - "published_at": "2024-01-24T04:34:44Z", - "assets": [ - { - "url": "https://api.github.com/repos/firezone/firezone/releases/assets/147443613", - "id": 147443613, - "node_id": "RA_kwDOD12Hpc4Iyc-c", - "name": "firezone-linux-gui-client_amd64.deb", - "label": "", - "uploader": { - "login": "github-actions[bot]", - "id": 41898282, - "node_id": "MDM6Qm90NDE4OTgyODI=", - "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/github-actions%5Bbot%5D", - "html_url": "https://github.com/apps/github-actions", - "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", - "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", - "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", - "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", - "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", - "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", - "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", - "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", - "type": "Bot", - "site_admin": false - }, - "content_type": "application/octet-stream", - "state": "uploaded", - "size": 8376320, - "download_count": 10, - "created_at": "2024-01-24T04:33:53Z", - "updated_at": "2024-01-24T04:33:53Z", - "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.8/firezone-linux-gui-client_amd64.deb" - }, - { - "url": "https://api.github.com/repos/firezone/firezone/releases/assets/147443612", - "id": 147443612, - "node_id": "RA_kwDOD12Hpc4Iyc-c", - "name": "firezone-windows-client-x64.msi", - "label": "", - "uploader": { - "login": "github-actions[bot]", - "id": 41898282, - "node_id": "MDM6Qm90NDE4OTgyODI=", - "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/github-actions%5Bbot%5D", - "html_url": "https://github.com/apps/github-actions", - "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", - "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", - "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", - "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", - "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", - "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", - "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", - "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", - "type": "Bot", - "site_admin": false - }, - "content_type": "application/octet-stream", - "state": "uploaded", - "size": 8376320, - "download_count": 10, - "created_at": "2024-01-24T04:33:53Z", - "updated_at": "2024-01-24T04:33:53Z", - "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.8/firezone-windows-client-x64.msi" - } - ] - }"#; - #[test] - fn test() { - let asset_name = super::ASSET_NAME; - let release = super::Release::from_str(RELEASES_LATEST_JSON).unwrap(); - let expected_url = format!( - "https://github.com/firezone/firezone/releases/download/1.0.0-pre.8/{asset_name}" + fn new_format() { + let s = r#" + { + "tag_name": "1.0.0-pre.14", + "assets": [ + { + "name": "firezone-client-gui-linux_1.0.0-pre.14_aarch64.deb", + "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-gui-linux_1.0.0-pre.14_aarch64.deb" + }, + { + "name": "firezone-client-gui-linux_1.0.0-pre.14_x86_64.deb", + "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-gui-linux_1.0.0-pre.14_x86_64.deb" + }, + { + "name": "firezone-client-gui-windows_1.0.0-pre.14_aarch64.msi", + "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-gui-windows_1.0.0-pre.14_aarch64.msi" + }, + { + "name": "firezone-client-gui-windows_1.0.0-pre.14_x86_64.msi", + "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-gui-windows_1.0.0-pre.14_x86_64.msi" + }, + + { + "name": "firezone-client-headless-linux_1.0.0-pre.14_aarch64.deb", + "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-headless-linux_1.0.0-pre.14_aarch64.deb" + }, + { + "name": "firezone-client-headless-linux_1.0.0-pre.14_x86_64.deb", + "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-headless-linux_1.0.0-pre.14_x86_64.deb" + }, + { + "name": "firezone-client-headless-windows_1.0.0-pre.14_aarch64.msi", + "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-headless-windows_1.0.0-pre.14_aarch64.msi" + }, + { + "name": "firezone-client-headless-windows_1.0.0-pre.14_x86_64.msi", + "browser_download_url": "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-headless-windows_1.0.0-pre.14_x86_64.msi" + } + ] + }"#; + + let release: super::Release = serde_json::from_str(s).unwrap(); + let expected_url = "https://github.com/firezone/firezone/releases/download/1.0.0-pre.14/firezone-client-gui-windows_1.0.0-pre.14_x86_64.msi"; + assert_eq!( + release + .download_url_for("x86_64", "windows") + .unwrap() + .to_string(), + expected_url ); - assert_eq!(release.browser_download_url.to_string(), expected_url); - assert_eq!(release.tag_name.to_string(), "1.0.0-pre.8"); + assert_eq!(release.tag_name.to_string(), "1.0.0-pre.14"); assert!( semver::Version::from_str("1.0.0").unwrap() - > semver::Version::from_str("1.0.0-pre.8").unwrap() + > semver::Version::from_str("1.0.0-pre.14").unwrap() ); assert!( - semver::Version::from_str("1.0.0-pre.8").unwrap() + semver::Version::from_str("1.0.0-pre.14").unwrap() > semver::Version::from_str("0.7.0").unwrap() ); assert!(super::current_version().is_ok()); } + + #[test] + fn pick_asset() { + let asset_names = [ + "firezone-client-gui-linux_1.0.0-pre.14_aarch64.deb", + "firezone-client-gui-linux_1.0.0-pre.14_x86_64.deb", + "firezone-client-gui-windows_1.0.0-pre.14_aarch64.msi", + "firezone-client-gui-windows_1.0.0-pre.14_x86_64.msi", + "firezone-client-headless-linux_1.0.0-pre.14_aarch64.deb", + "firezone-client-headless-linux_1.0.0-pre.14_x86_64.deb", + "firezone-client-headless-windows_1.0.0-pre.14_aarch64.msi", + "firezone-client-headless-windows_1.0.0-pre.14_x86_64.msi", + "firezone-gateway-linux_1.0.0-pre.14_aarch64.deb", + "firezone-gateway-linux_1.0.0-pre.14_x86_64.deb", + "firezone-gateway-windows_1.0.0-pre.14_aarch64.msi", + "firezone-gateway-windows_1.0.0-pre.14_x86_64.msi", + ]; + + let product = "client-gui"; + let arch = "x86_64"; + let os = "windows"; + let package = "msi"; + + let prefix = format!("firezone-{product}-{os}_"); + let suffix = format!("_{arch}.{package}"); + + let mut iter = asset_names + .into_iter() + .filter(|x| x.starts_with(&prefix) && x.ends_with(&suffix)); + let asset_name = iter.next().unwrap(); + assert!(iter.next().is_none()); + + assert_eq!( + asset_name, + "firezone-client-gui-windows_1.0.0-pre.14_x86_64.msi" + ); + } } diff --git a/scripts/Makefile b/scripts/Makefile index 81d603e88..abdd208f0 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -22,10 +22,10 @@ android-version: @find kotlin/ -name "*.gradle.kts" -exec sed $(SEDARG) -e '/mark:automatic-version/{n;s/versionName =.*/versionName = "$(android-version)"/;}' {} \; cargo-version: - @find rust/ -name "Cargo.toml" -exec sed $(SEDARG) -e '/mark:automatic-version/{n;s/[0-9]*\.[0-9]*\.[0-9]*/$(rust-version)/;}' {} \; - # TODO: This can fail on some platforms. You may need to specify the package - # to avoid hitting the wrong codepaths for your platform. - @cd rust && cargo check + @# The website hosts permalinks to our published packages and binaries + @find website/ -name "redirects.js" -exec sed $(SEDARG) -e '/mark:automatic-version/{n;s/[0-9]*\.[0-9]*\.[0-9]*/$(cargo-version)/g;}' {} \; + @find rust/ -name "Cargo.toml" -exec sed $(SEDARG) -e '/mark:automatic-version/{n;s/[0-9]*\.[0-9]*\.[0-9]*/$(cargo-version)/;}' {} \; + @cd rust && cargo update --workspace ci-version: @find .github/ -name "*.yml" -exec sed $(SEDARG) -e '/mark:automatic-version/{n;s/[0-9]*\.[0-9]*\.[0-9]*/$(ci-version)/;}' {} \; diff --git a/scripts/build/tauri-rename-windows.sh b/scripts/build/tauri-rename-windows.sh index 7f0e64c5c..3a7efae61 100755 --- a/scripts/build/tauri-rename-windows.sh +++ b/scripts/build/tauri-rename-windows.sh @@ -1,19 +1,19 @@ #!/usr/bin/env bash -set -euo pipefail +set -euox pipefail # For debugging ls ../target/release ../target/release/bundle/msi # Used for release artifact # In release mode the name comes from tauri.conf.json -cp ../target/release/Firezone.exe "$BINARY_DEST_PATH-x64.exe" -cp ../target/release/bundle/msi/*.msi "$BINARY_DEST_PATH-x64.msi" -cp ../target/release/firezone_gui_client.pdb "$BINARY_DEST_PATH-x64.pdb" +cp ../target/release/Firezone.exe "$BINARY_DEST_PATH-x86_64.exe" +cp ../target/release/bundle/msi/*.msi "$BINARY_DEST_PATH-x86_64.msi" +cp ../target/release/firezone_gui_client.pdb "$BINARY_DEST_PATH-x86_64.pdb" function make_hash() { sha256sum "$1"> "$1.sha256sum.txt" } -make_hash "$BINARY_DEST_PATH-x64.exe" -make_hash "$BINARY_DEST_PATH-x64.msi" -make_hash "$BINARY_DEST_PATH-x64.pdb" +make_hash "$BINARY_DEST_PATH-x86_64.exe" +make_hash "$BINARY_DEST_PATH-x86_64.msi" +make_hash "$BINARY_DEST_PATH-x86_64.pdb" diff --git a/scripts/build/tauri-upload-windows.sh b/scripts/build/tauri-upload-windows.sh index a797f078e..f433e7761 100755 --- a/scripts/build/tauri-upload-windows.sh +++ b/scripts/build/tauri-upload-windows.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash -set -euo pipefail +set -euox pipefail # This artifact name is tied to the update checker in `gui-client/src-tauri/src/client/updates.rs` # So we can't put the version number in it until we stop using Github for update checks. gh release upload "$TAG_NAME" \ - "$BINARY_DEST_PATH"-x64.msi \ - "$BINARY_DEST_PATH"-x64.msi.sha256sum.txt \ + "$BINARY_DEST_PATH"_"$TAG_NAME"_x86_64.msi \ + "$BINARY_DEST_PATH"_"$TAG_NAME"_x86_64.msi.sha256sum.txt \ --clobber \ --repo "$REPOSITORY" diff --git a/scripts/gateway-systemd-install.sh b/scripts/gateway-systemd-install.sh index c44f1c670..ed9816c83 100755 --- a/scripts/gateway-systemd-install.sh +++ b/scripts/gateway-systemd-install.sh @@ -57,21 +57,9 @@ set -ue if [ ! -e /usr/local/bin/firezone-gateway ]; then echo "/usr/local/bin/firezone-gateway not found. Downloading latest version..." arch=\$(uname -m) - case \$arch in - aarch64) - bin="gateway-arm64" - ;; - armv7l) - bin="gateway-arm" - ;; - x86_64) - bin="gateway-x64" - ;; - *) - echo "Unsupported architecture" - exit 1 - esac - curl -Ls https://github.com/firezone/firezone/releases/latest/download/\$bin -o /usr/local/bin/firezone-gateway + + # See https://www.github.com/firezone/firezone/releases for available binaries + curl -fsSL https://www.firezone.dev/dl/firezone-gateway/latest/\$arch -o /usr/local/bin/firezone-gateway else echo "/usr/local/bin/firezone-gateway found. Skipping download." fi diff --git a/website/next.config.mjs b/website/next.config.mjs index 7b18db623..bfc920bcc 100644 --- a/website/next.config.mjs +++ b/website/next.config.mjs @@ -4,6 +4,7 @@ import remarkGfm from "remark-gfm"; import remarkParse from "remark-parse"; import rehypeStringify from "rehype-stringify"; import rehypeHighlight from "rehype-highlight"; +import redirects from "./redirects.js"; // Add IDs to headings import rehypeSlug from "rehype-slug"; @@ -34,6 +35,9 @@ const nextConfig = { experimental: { typedRoutes: true, }, + async redirects() { + return redirects; + }, // Proxy GitHub requests to avoid CORS issues async rewrites() { return [ diff --git a/website/redirects.js b/website/redirects.js new file mode 100644 index 000000000..9af03801c --- /dev/null +++ b/website/redirects.js @@ -0,0 +1,142 @@ +// Add all server-side redirects here. Will be loaded by next.config.mjs. + +module.exports = [ + /* + * + * Windows Client + * + */ + // latest + { + source: "/dl/firezone-client-gui-windows/latest/x86_64", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-client-gui-windows_1.0.0_x86_64.msi", + permanent: false, + }, + // versioned + { + source: "/dl/firezone-client-gui-windows/:version/x86_64", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-client-gui-windows_:version_x86_64.msi", + permanent: false, + }, + /* + * + * Linux Client + * + */ + // latest + { + source: "/dl/firezone-client-gui-linux/latest/x86_64", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-client-gui-linux_1.0.0_x86_64.deb", + permanent: false, + }, + { + source: "/dl/firezone-client-gui-linux/latest/aarch64", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-client-gui-linux_1.0.0_aarch64.deb", + permanent: false, + }, + { + source: "/dl/firezone-client-headless-linux/latest/x86_64", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-client-headless-linux_1.0.0_x86_64", + permanent: false, + }, + { + source: "/dl/firezone-client-headless-linux/latest/aarch64", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-client-headless-linux_1.0.0_aarch64", + permanent: false, + }, + { + source: "/dl/firezone-client-headless-linux/latest/armv7", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-client-headless-linux_1.0.0_armv7", + permanent: false, + }, + // versioned + { + source: "/dl/firezone-client-gui-linux/:version/x86_64", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-client-gui-linux_:version_x86_64.deb", + permanent: false, + }, + { + source: "/dl/firezone-client-gui-linux/:version/aarch64", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-client-gui-linux_:version_aarch64.deb", + permanent: false, + }, + { + source: "/dl/firezone-client-headless-linux/:version/x86_64", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-client-headless-linux_:version_x86_64", + permanent: false, + }, + { + source: "/dl/firezone-client-headless-linux/:version/aarch64", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-client-headless-linux_:version_aarch64", + permanent: false, + }, + { + source: "/dl/firezone-client-headless-linux/:version/armv7", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-client-headless-linux_:version_armv7", + permanent: false, + }, + /* + * + * Gateway + * + */ + // latest + { + source: "/dl/firezone-gateway/latest/x86_64", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-gateway_1.0.0_x86_64", + permanent: false, + }, + { + source: "/dl/firezone-gateway/latest/aarch64", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-gateway_1.0.0_aarch64", + permanent: false, + }, + { + source: "/dl/firezone-gateway/latest/armv7", + destination: + // mark:automatic-version + "https://www.github.com/firezone/firezone/releases/download/1.0.0/firezone-gateway_1.0.0_armv7", + permanent: false, + }, + // versioned + { + source: "/dl/firezone-gateway/:version/x86_64", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-gateway_:version_x86_64", + permanent: false, + }, + { + source: "/dl/firezone-gateway/:version/aarch64", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-gateway_:version_aarch64", + permanent: false, + }, + { + source: "/dl/firezone-gateway/:version/armv7", + destination: + "https://www.github.com/firezone/firezone/releases/download/:version/firezone-gateway_:version_armv7", + permanent: false, + }, +]; diff --git a/website/src/app/blog/mar-2024-update/readme.mdx b/website/src/app/blog/mar-2024-update/readme.mdx index 04eaf901f..d51146678 100644 --- a/website/src/app/blog/mar-2024-update/readme.mdx +++ b/website/src/app/blog/mar-2024-update/readme.mdx @@ -39,8 +39,7 @@ The Firezone Windows client is now available for beta testing! You'll need Windows 10 or higher and an x86-64 CPU to run the client. [See the docs](/kb/user-guides/windows-client) for more information and download -links, or use -[this direct link](https://github.com/firezone/firezone/releases/latest/download/firezone-windows-client-x64.msi) +links, or use [this direct link](/dl/firezone-client-gui-windows/latest/x86_64) to get started right away. **Note**: Be sure to click **Allow** when prompted by the User Account Control diff --git a/website/src/app/kb/user-guides/linux-client/readme.mdx b/website/src/app/kb/user-guides/linux-client/readme.mdx index cf990299d..d655c915f 100644 --- a/website/src/app/kb/user-guides/linux-client/readme.mdx +++ b/website/src/app/kb/user-guides/linux-client/readme.mdx @@ -21,9 +21,9 @@ The Linux Client is currently in beta and can be downloaded from our [main repository's releases page](https://github.com/firezone/firezone/releases). Alternatively, download the latest Client binary using one of the links below: -- [Download the Linux Client for `x86-64`](https://github.com/firezone/firezone/releases/latest/download/linux-client-x64) -- [Download the Linux Client for `ARMv7l`](https://github.com/firezone/firezone/releases/latest/download/linux-client-arm) -- [Download the Linux Client for `ARM64`](https://github.com/firezone/firezone/releases/latest/download/linux-client-arm64) +- [Download the Linux Client for `x86-64`](/dl/firezone-client-headless-linux/latest/x86_64) +- [Download the Linux Client for `ARMv7l`](/dl/firezone-client-headless-linux/latest/armv7) +- [Download the Linux Client for `ARM64`](/dl/firezone-client-headless/linux/latest/aarch64) ## Usage diff --git a/website/src/app/kb/user-guides/windows-client/readme.mdx b/website/src/app/kb/user-guides/windows-client/readme.mdx index 086825098..c42b8df29 100644 --- a/website/src/app/kb/user-guides/windows-client/readme.mdx +++ b/website/src/app/kb/user-guides/windows-client/readme.mdx @@ -13,7 +13,7 @@ architecture. The Windows Client is currently in beta and can be downloaded from the following link: -- [Download the MSI installer package](https://github.com/firezone/firezone/releases/latest/download/firezone-windows-client-x64.msi) +- [Download the MSI installer package](/dl/firezone-client-gui-windows/latest/x86_64) ## Usage