diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 11951100..4c746adb 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -20,9 +20,6 @@ jobs: with: toolchain: stable - name: Build with Cargo - uses: actions-rs/cargo@v1 - with: - command: build - args: --release + run: cargo build --release --workspace - name: Run tests run: cargo test --verbose \ No newline at end of file diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml new file mode 100644 index 00000000..259ef819 --- /dev/null +++ b/.github/workflows/draft-release.yml @@ -0,0 +1,48 @@ +name: draft-release + +on: + push: + tags: '*' + +env: + CARGO_TERM_COLOR: always + +jobs: + release: + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + - os: windows-latest + target: x86_64-pc-windows-msvc + + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup npm + uses: actions/setup-node@v4 + - name: Setup rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: ${{ matrix.target }} + override: true + + - name: Build xtask + run: cargo build --package xtask --target ${{ matrix.target }} --release + - name: Prepare and pack the client + run: | + cargo xtask prep-lsp --target ${{ matrix.target }} --release + cargo xtask package --out-dir . --out-name "witcherscript-ide-${{ github.ref_name }}-${{ matrix.target }}" + + - name: Create draft release + uses: ncipollo/release-action@v1 + with: + artifacts: "*.vsix" + draft: true + allowUpdates: true + generateReleaseNotes: true \ No newline at end of file diff --git a/xtask/README.md b/xtask/README.md index 2c98dd73..708d7ee4 100644 --- a/xtask/README.md +++ b/xtask/README.md @@ -2,4 +2,6 @@ This crate provides automation scripts for the repo. They are OS-agnostic as they don't directly use any specific shell. All you need is the `cargo xtask` command. +Beware, these tasks are used in github workflows, so make sure any breaking changes are also reflected in `.github/workflows`. + More about xtask workflow [here](https://github.com/matklad/cargo-xtask). \ No newline at end of file diff --git a/xtask/src/cli.rs b/xtask/src/cli.rs index 6b22e6a5..f6d71791 100644 --- a/xtask/src/cli.rs +++ b/xtask/src/cli.rs @@ -11,12 +11,24 @@ pub struct Cli { #[derive(Subcommand)] pub enum Commands { - /// Copy debug build of the LSP server to the VSCode client - CopyLsp, - /// Copy release build of the LSP server to the VSCode client - CopyLspRelease, + // Build and copy LSP server into VSCode's extension directory + PrepLsp { + /// Should LSP be built with optimised release profile + #[arg(long)] + release: bool, + /// Compilation target triple + #[arg(long)] + target: Option + }, /// Build and package VSCode extension into a .vsix file - Package, + Package { + /// Output directory for the .vsix file; default is the current working directory + #[arg(long)] + out_dir: Option, + /// Name of the output file without the extension + #[arg(long)] + out_name: Option + }, /// Build, package and install the VSCode extension Install } diff --git a/xtask/src/commands/copy_lsp.rs b/xtask/src/commands/copy_lsp.rs deleted file mode 100644 index a28d32c6..00000000 --- a/xtask/src/commands/copy_lsp.rs +++ /dev/null @@ -1,17 +0,0 @@ -use xshell::{Shell, cmd}; - - -const SRC: &str = "./target/debug/witcherscript-lsp.exe"; -const DST: &str = "./editors/vscode/server/bin"; - -pub fn copy_lsp() -> anyhow::Result<()> { - let sh = Shell::new()?; - - println!("Building the LSP..."); - cmd!(sh, "cargo build --package witcherscript-lsp").run()?; - - sh.copy_file(SRC, DST)?; - println!("Copied debug LSP into {}", DST); - - Ok(()) -} \ No newline at end of file diff --git a/xtask/src/commands/copy_lsp_release.rs b/xtask/src/commands/copy_lsp_release.rs deleted file mode 100644 index c0c81b24..00000000 --- a/xtask/src/commands/copy_lsp_release.rs +++ /dev/null @@ -1,17 +0,0 @@ -use xshell::{Shell, cmd}; - - -const SRC: &str = "./target/release/witcherscript-lsp.exe"; -const DST: &str = "./editors/vscode/server/bin"; - -pub fn copy_lsp_release() -> anyhow::Result<()> { - let sh = Shell::new()?; - - println!("Building the LSP..."); - cmd!(sh, "cargo build --package witcherscript-lsp --release").run()?; - - sh.copy_file(SRC, DST)?; - println!("Copied release LSP into {}", DST); - - Ok(()) -} \ No newline at end of file diff --git a/xtask/src/commands/install.rs b/xtask/src/commands/install.rs index 10652182..926c8611 100644 --- a/xtask/src/commands/install.rs +++ b/xtask/src/commands/install.rs @@ -2,34 +2,26 @@ use anyhow::{Context, bail}; use xshell::{Shell, cmd}; -const LSP_SRC: &str = "./target/release/witcherscript-lsp.exe"; -const LSP_DST: &str = "./editors/vscode/server/bin"; const EXT_DIR: &str = "./editors/vscode"; const VSIX_NAME: &str = "witcherscript-ide.vsix"; pub fn install() -> anyhow::Result<()> { let sh = Shell::new()?; - println!("Building LSP release..."); - cmd!(sh, "cargo build --package witcherscript-lsp --release").run()?; - - sh.copy_file(LSP_SRC, LSP_DST)?; - println!("Copied LSP into {}", LSP_DST); - sh.change_dir(EXT_DIR); if cfg!(unix) { cmd!(sh, "npm --version").run().with_context(|| "npm is required")?; - cmd!(sh, "vsce --version").run().with_context(|| "vsce is required: npm install -g vsce")?; cmd!(sh, "code --version").run().with_context(|| "Visual Studio Code is required")?; + cmd!(sh, "npm ci").run()?; cmd!(sh, "npm run package").run()?; } else { cmd!(sh, "cmd.exe /c npm --version").run().with_context(|| "npm is required")?; - cmd!(sh, "cmd.exe /c vsce --version").run().with_context(|| "vsce is required: npm install -g vsce")?; cmd!(sh, "cmd.exe /c code --version").run().with_context(|| "Visual Studio Code is required")?; + cmd!(sh, "cmd.exe /c npm ci").run()?; cmd!(sh, "cmd.exe /c npm run package").run()?; } @@ -44,6 +36,10 @@ pub fn install() -> anyhow::Result<()> { if !installed_extensions.contains("witcherscript-ide") { bail!("Could not install the Visual Studio Code extension."); } + + // Remove the vsix file + // If you want to keep it use xtask package instead + sh.remove_path(VSIX_NAME)?; Ok(()) } \ No newline at end of file diff --git a/xtask/src/commands/mod.rs b/xtask/src/commands/mod.rs index 4357673e..4db08a16 100644 --- a/xtask/src/commands/mod.rs +++ b/xtask/src/commands/mod.rs @@ -1,9 +1,7 @@ -mod copy_lsp; -mod copy_lsp_release; +mod prep_lsp; mod package; mod install; -pub use copy_lsp::copy_lsp; -pub use copy_lsp_release::copy_lsp_release; +pub use prep_lsp::prep_lsp; pub use package::package; pub use install::install; \ No newline at end of file diff --git a/xtask/src/commands/package.rs b/xtask/src/commands/package.rs index eb03c7e7..6c35615b 100644 --- a/xtask/src/commands/package.rs +++ b/xtask/src/commands/package.rs @@ -1,39 +1,47 @@ +use std::path::PathBuf; use anyhow::Context; use xshell::{Shell, cmd}; -const LSP_SRC: &str = "./target/release/witcherscript-lsp.exe"; -const LSP_DST: &str = "./editors/vscode/server/bin"; const EXT_DIR: &str = "./editors/vscode"; const VSIX_NAME: &str = "witcherscript-ide.vsix"; -pub fn package() -> anyhow::Result<()> { +pub fn package(out_dir: Option, out_name: Option) -> anyhow::Result<()> { let sh = Shell::new()?; - println!("Building LSP release..."); - cmd!(sh, "cargo build --package witcherscript-lsp --release").run()?; - - sh.copy_file(LSP_SRC, LSP_DST)?; - println!("Copied LSP into {}", LSP_DST); - + // normalize the output path so it stays valid when we change cwd + let out_dir = if let Some(out_dir) = out_dir { + // can't just use Option::map because of error propagation here + Some(PathBuf::from(&out_dir).canonicalize()?) + } else { + None + }; sh.change_dir(EXT_DIR); if cfg!(unix) { cmd!(sh, "npm --version").run().with_context(|| "npm is required")?; - cmd!(sh, "vsce --version").run().with_context(|| "vsce is required: npm install -g vsce")?; + cmd!(sh, "npm ci").run()?; cmd!(sh, "npm run package").run()?; } else { cmd!(sh, "cmd.exe /c npm --version").run().with_context(|| "npm is required")?; - cmd!(sh, "cmd.exe /c vsce --version").run().with_context(|| "vsce is required: npm install -g vsce")?; + cmd!(sh, "cmd.exe /c npm ci").run()?; cmd!(sh, "cmd.exe /c npm run package").run()?; } - let version = env!("CARGO_PKG_VERSION"); - sh.copy_file(VSIX_NAME, format!("witcherscript-ide-{version}.vsix"))?; + let vsix_file = format!("{}.vsix", out_name.unwrap_or("witcherscript-ide".to_string())); + let vsix_dst = if let Some(output_dir) = out_dir { + output_dir.join(vsix_file) + } else { + PathBuf::from(&vsix_file).canonicalize()? + }; + + sh.copy_file(VSIX_NAME, vsix_dst.as_os_str())?; + println!("Copied vsix package into {}", vsix_dst.display()); + // remove the original vsix file sh.remove_path(VSIX_NAME)?; Ok(()) diff --git a/xtask/src/commands/prep_lsp.rs b/xtask/src/commands/prep_lsp.rs new file mode 100644 index 00000000..3001cc71 --- /dev/null +++ b/xtask/src/commands/prep_lsp.rs @@ -0,0 +1,42 @@ +use std::path::PathBuf; +use xshell::{Shell, cmd}; + + +const LSP_DST: &str = "./editors/vscode/server/bin"; + +pub fn prep_lsp(release: bool, target: Option) -> anyhow::Result<()> { + let sh = Shell::new()?; + + let mut build = cmd!(sh, "cargo build --package witcherscript-lsp"); + + let mut lsp_src = PathBuf::from("./target"); + if let Some(target) = target { + build = build.arg("--target").arg(&target); + lsp_src.push(target); + } + + if release { + build = build.arg("--release"); + lsp_src.push("release"); + } else { + lsp_src.push("debug"); + } + + lsp_src.push("witcherscript-lsp"); + + if cfg!(windows) { + lsp_src.set_extension("exe"); + } + + println!("Building the LSP..."); + build.run()?; + + + // make sure destination folder exists + sh.create_dir(LSP_DST)?; + + sh.copy_file(lsp_src, LSP_DST)?; + println!("Copied LSP into {}", LSP_DST); + + Ok(()) +} \ No newline at end of file diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 600056a7..83554a89 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -9,9 +9,8 @@ fn main() -> anyhow::Result<()> { let cli = Cli::parse(); match cli.command { - cli::Commands::CopyLsp => commands::copy_lsp(), - cli::Commands::CopyLspRelease => commands::copy_lsp_release(), - cli::Commands::Package => commands::package(), + cli::Commands::PrepLsp { release, target } => commands::prep_lsp(release, target), + cli::Commands::Package { out_dir, out_name } => commands::package(out_dir, out_name), cli::Commands::Install => commands::install() } } \ No newline at end of file