Add initial CI job for Windows target (#8088)

Kirill Bulatov created

Clippy is disabled for now, due to many warnings in both `gpui` and
other code, see
https://github.com/zed-industries/zed/actions/runs/7980269779/job/21789529800
for more details.

Also, due to `#!/usr/bin/env bash` shebang in the `script/clippy`, it
starts in Windows CI with `shell: C:\Program Files\Git\bin\bash.EXE
-euxo pipefail {0}`

https://github.com/zed-industries/zed/actions/runs/7980269779/job/21789529800#step:4:3
It seems more appropriate to use PowerShell instead.

See `todo!("windows")` for all stubbed places currently.

Release Notes:

- N/A

Change summary

.github/workflows/ci.yml                  | 30 +++++++++++++++++++++++++
crates/fs/src/fs.rs                       |  2 
crates/gpui/src/platform.rs               |  4 +++
crates/gpui/src/platform/test/platform.rs |  3 ++
crates/install_cli/src/install_cli.rs     | 14 +++++++----
crates/terminal/src/terminal.rs           |  4 +-
crates/zed/src/languages/csharp.rs        | 14 +++++++----
crates/zed/src/languages/elixir.rs        | 14 +++++++----
crates/zed/src/languages/lua.rs           | 14 +++++++----
crates/zed/src/languages/rust.rs          | 14 +++++++----
crates/zed/src/languages/toml.rs          | 14 +++++++----
crates/zed/src/languages/zig.rs           | 14 +++++++----
12 files changed, 103 insertions(+), 38 deletions(-)

Detailed changes

.github/workflows/ci.yml 🔗

@@ -126,6 +126,36 @@ jobs:
 
       - name: Build Zed
         run: cargo build -p zed
+
+  # todo!(windows): Actually run the tests
+  windows_tests:
+    name: (Windows) Run Clippy and tests
+    runs-on: windows-latest
+    steps:
+      - name: Checkout repo
+        uses: actions/checkout@v4
+        with:
+          clean: false
+          submodules: "recursive"
+
+      - name: Restore from cache
+        uses: actions/cache@v4
+        with:
+          path: |
+            ~/.cargo/bin/
+            ~/.cargo/registry/index/
+            ~/.cargo/registry/cache/
+            ~/.cargo/git/db/
+            target/
+          key: ${{ runner.os }}-cargo-${{ hashFiles('**/rust-toolchain.toml') }}-${{ hashFiles('**/Cargo.lock') }}
+      # todo!(windows): Actually run clippy
+      #- name: cargo clippy
+      #  shell: bash -euxo pipefail {0}
+      #  run: script/clippy
+
+      - name: Build Zed
+        run: cargo build -p zed
+
   bundle:
     name: Bundle macOS app
     runs-on:

crates/fs/src/fs.rs 🔗

@@ -245,7 +245,7 @@ impl Fs for RealFs {
         #[cfg(unix)]
         let inode = metadata.ino();
 
-        // todo!(windows)
+        // todo!("windows")
         #[cfg(windows)]
         let inode = 0;
 

crates/gpui/src/platform.rs 🔗

@@ -61,6 +61,10 @@ pub(crate) fn current_platform() -> Rc<dyn Platform> {
 pub(crate) fn current_platform() -> Rc<dyn Platform> {
     Rc::new(LinuxPlatform::new())
 }
+#[cfg(target_os = "windows")]
+pub(crate) fn current_platform() -> Rc<dyn Platform> {
+    todo!("windows")
+}
 
 pub(crate) trait Platform: 'static {
     fn background_executor(&self) -> BackgroundExecutor;

crates/gpui/src/platform/test/platform.rs 🔗

@@ -125,6 +125,9 @@ impl Platform for TestPlatform {
 
         #[cfg(target_os = "macos")]
         return Arc::new(crate::platform::mac::MacTextSystem::new());
+
+        #[cfg(target_os = "windows")]
+        todo!("windows")
     }
 
     fn run(&self, _on_finish_launching: Box<dyn FnOnce()>) {

crates/install_cli/src/install_cli.rs 🔗

@@ -18,12 +18,16 @@ pub async fn install_cli(cx: &AsyncAppContext) -> Result<()> {
     // If the symlink is not there or is outdated, first try replacing it
     // without escalating.
     smol::fs::remove_file(link_path).await.log_err();
-    if smol::fs::unix::symlink(&cli_path, link_path)
-        .await
-        .log_err()
-        .is_some()
+    // todo!("windows")
+    #[cfg(not(windows))]
     {
-        return Ok(());
+        if smol::fs::unix::symlink(&cli_path, link_path)
+            .await
+            .log_err()
+            .is_some()
+        {
+            return Ok(());
+        }
     }
 
     // The symlink could not be created, so use osascript with admin privileges

crates/terminal/src/terminal.rs 🔗

@@ -396,7 +396,7 @@ impl TerminalBuilder {
         #[cfg(unix)]
         let (fd, shell_pid) = (pty.file().as_raw_fd(), pty.child().id());
 
-        // todo!(windows)
+        // todo!("windows")
         #[cfg(windows)]
         let (fd, shell_pid) = (-1, 0);
 
@@ -664,7 +664,7 @@ impl Terminal {
     fn update_process_info(&mut self) -> bool {
         #[cfg(unix)]
         let mut pid = unsafe { libc::tcgetpgrp(self.shell_fd as i32) };
-        // todo!(windows)
+        // todo!("windows")
         #[cfg(windows)]
         let mut pid = -1;
         if pid < 0 {

crates/zed/src/languages/csharp.rs 🔗

@@ -81,11 +81,15 @@ impl super::LspAdapter for OmniSharpAdapter {
             archive.unpack(container_dir).await?;
         }
 
-        fs::set_permissions(
-            &binary_path,
-            <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-        )
-        .await?;
+        // todo!("windows")
+        #[cfg(not(windows))]
+        {
+            fs::set_permissions(
+                &binary_path,
+                <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
+            )
+            .await?;
+        }
         Ok(LanguageServerBinary {
             path: binary_path,
             arguments: server_binary_arguments(),

crates/zed/src/languages/elixir.rs 🔗

@@ -356,11 +356,15 @@ impl LspAdapter for NextLspAdapter {
             }
             futures::io::copy(response.body_mut(), &mut file).await?;
 
-            fs::set_permissions(
-                &binary_path,
-                <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-            )
-            .await?;
+            // todo!("windows")
+            #[cfg(not(windows))]
+            {
+                fs::set_permissions(
+                    &binary_path,
+                    <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
+                )
+                .await?;
+            }
         }
 
         Ok(LanguageServerBinary {

crates/zed/src/languages/lua.rs 🔗

@@ -83,11 +83,15 @@ impl super::LspAdapter for LuaLspAdapter {
             archive.unpack(container_dir).await?;
         }
 
-        fs::set_permissions(
-            &binary_path,
-            <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-        )
-        .await?;
+        // todo!("windows")
+        #[cfg(not(windows))]
+        {
+            fs::set_permissions(
+                &binary_path,
+                <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
+            )
+            .await?;
+        }
         Ok(LanguageServerBinary {
             path: binary_path,
             arguments: Vec::new(),

crates/zed/src/languages/rust.rs 🔗

@@ -74,11 +74,15 @@ impl LspAdapter for RustLspAdapter {
             let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
             let mut file = File::create(&destination_path).await?;
             futures::io::copy(decompressed_bytes, &mut file).await?;
-            fs::set_permissions(
-                &destination_path,
-                <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-            )
-            .await?;
+            // todo!("windows")
+            #[cfg(not(windows))]
+            {
+                fs::set_permissions(
+                    &destination_path,
+                    <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
+                )
+                .await?;
+            }
 
             remove_matching(&container_dir, |entry| entry != destination_path).await;
         }

crates/zed/src/languages/toml.rs 🔗

@@ -72,11 +72,15 @@ impl LspAdapter for TaploLspAdapter {
 
             futures::io::copy(decompressed_bytes, &mut file).await?;
 
-            fs::set_permissions(
-                &binary_path,
-                <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-            )
-            .await?;
+            // todo!("windows")
+            #[cfg(not(windows))]
+            {
+                fs::set_permissions(
+                    &binary_path,
+                    <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
+                )
+                .await?;
+            }
         }
 
         Ok(LanguageServerBinary {

crates/zed/src/languages/zig.rs 🔗

@@ -64,11 +64,15 @@ impl LspAdapter for ZlsAdapter {
             archive.unpack(container_dir).await?;
         }
 
-        fs::set_permissions(
-            &binary_path,
-            <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-        )
-        .await?;
+        // todo!("windows")
+        #[cfg(not(windows))]
+        {
+            fs::set_permissions(
+                &binary_path,
+                <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
+            )
+            .await?;
+        }
         Ok(LanguageServerBinary {
             path: binary_path,
             arguments: vec![],