diff --git a/.github/workflows/bevy_mod_scripting.yml b/.github/workflows/bevy_mod_scripting.yml index 6b502d51b1..2cc2180e25 100644 --- a/.github/workflows/bevy_mod_scripting.yml +++ b/.github/workflows/bevy_mod_scripting.yml @@ -13,6 +13,11 @@ on: name: Check and Lint - bevy_mod_scripting + +env: + REGISTRY: ghcr.io + IMAGE_NAME: bevy-mod-scripting + concurrency: # Use github.run_id on main branch # Use github.event.pull_request.number on pull requests, so it's unique per pull request @@ -23,20 +28,29 @@ concurrency: jobs: generate-job-matrix: runs-on: ubuntu-latest + # container: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest outputs: matrix: ${{ steps.generate-matrix.outputs.matrix }} steps: + - name: Checkout + uses: actions/checkout@v4 - name: Generate matrix id: generate-matrix run: | - echo "matrix=$(cargo xtask ci-matrix)" >> $GITHUB_OUTPUT + cargo xtask ci-matrix > matrix.json + cat matrix.json + echo "Convert to single line JSON" + jq -c . matrix.json > matrix-one-line.json + echo "matrix=$(cat matrix-one-line.json)" >> $GITHUB_OUTPUT check: permissions: pull-requests: write name: Check - ${{ matrix.run_args.name }} runs-on: ${{ matrix.run_args.os }} - needs: generate-job-matrix + # container: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + needs: + - generate-job-matrix strategy: matrix: run_args: ${{fromJson(needs.generate-job-matrix.outputs.matrix)}} @@ -54,7 +68,9 @@ jobs: override: true - name: Rust Cache uses: Swatinem/rust-cache@v2.7.3 - - uses: actions-rs/cargo@v1 - with: - command: ${{ matrix.run_args.command }} - args: ci-check \ No newline at end of file + - name: Setup + run: | + cargo xtask init + - name: Check + run: | + ${{ matrix.run_args.command }} \ No newline at end of file diff --git a/.github/workflows/build-ci-image.yml b/.github/workflows/build-ci-image.yml new file mode 100644 index 0000000000..dc2a40dd5a --- /dev/null +++ b/.github/workflows/build-ci-image.yml @@ -0,0 +1,42 @@ +on: + workflow_dispatch: + + +env: + REGISTRY: ghcr.io + IMAGE_NAME: bevy-mod-scripting + +jobs: + build-runner-image: + permissions: + contents: read + packages: write + runs-on: ubuntu-latest + name: Build multi-platform Docker image + outputs: + image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.tags }} + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/build-push-action@v5 + with: + context: . + file: ./crates/xtask/Dockerfile + platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Cargo.toml b/Cargo.toml index aabd435120..08c7f331e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,10 @@ path = "src/lib.rs" features = ["lua54"] [features] -default = ["core_functions", "bevy_bindings", "unsafe_lua_modules"] +default = ["core_functions", "bevy_bindings"] ## lua -lua = ["bevy_mod_scripting_lua"] +lua = ["bevy_mod_scripting_lua", "unsafe_lua_modules"] # one of these must be selected lua51 = ["bevy_mod_scripting_lua/lua51", "lua"] lua52 = ["bevy_mod_scripting_lua/lua52", "lua"] diff --git a/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs index f97bd6df1d..7666f6779d 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/bindings/script_value.rs @@ -41,7 +41,10 @@ impl FromLua for LuaScriptValue { Value::Nil => ScriptValue::Unit, Value::Boolean(b) => ScriptValue::Bool(b), // Value::LightUserData(light_user_data) => todo!(), + #[cfg(not(feature = "luau"))] Value::Integer(i) => ScriptValue::Integer(i), + #[cfg(feature = "luau")] + Value::Integer(i) => ScriptValue::Integer(i as i64), Value::Number(n) => ScriptValue::Float(n), Value::String(s) => ScriptValue::String(s.to_str()?.to_owned().into()), Value::Table(table) => { @@ -86,7 +89,10 @@ impl IntoLua for LuaScriptValue { Ok(match self.0 { ScriptValue::Unit => Value::Nil, ScriptValue::Bool(b) => Value::Boolean(b), + #[cfg(not(feature = "luau"))] ScriptValue::Integer(i) => Value::Integer(i), + #[cfg(feature = "luau")] + ScriptValue::Integer(i) => Value::Integer(i as i32), ScriptValue::Float(f) => Value::Number(f), ScriptValue::String(s) => Value::String(lua.create_string(s.as_ref())?), ScriptValue::Reference(r) => LuaReflectReference::from(r).into_lua(lua)?, diff --git a/crates/xtask/Dockerfile b/crates/xtask/Dockerfile new file mode 100644 index 0000000000..11ef450f06 --- /dev/null +++ b/crates/xtask/Dockerfile @@ -0,0 +1,19 @@ +FROM rust:latest AS base +RUN cargo install sccache --version ^0.7 +RUN cargo install cargo-chef --version ^0.1 +ENV RUSTC_WRAPPER=sccache SCCACHE_DIR=/sccache + +FROM base AS planner +WORKDIR /app +COPY . . +RUN --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ + cargo chef prepare --recipe-path recipe.json + +FROM base as builder +WORKDIR /app +COPY --from=planner /app/recipe.json recipe.json +RUN --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ + cargo chef cook --release --recipe-path recipe.json +COPY . . +RUN --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ + cargo xtask init \ No newline at end of file diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index b41406404e..868ac1b9f7 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -107,6 +107,12 @@ impl IntoFeatureGroup for Feature { #[derive(Debug, Clone, PartialEq, Eq)] struct Features(HashSet); +impl Default for Features { + fn default() -> Self { + Features::new(vec![Feature::Lua54]) + } +} + impl Features { fn new>(features: I) -> Self { Self(features.into_iter().collect()) @@ -161,9 +167,6 @@ impl Features { impl std::fmt::Display for Features { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if &Self::all_features() == self { - return write!(f, "all"); - } for (i, feature) in self.0.iter().sorted().enumerate() { if i > 0 { write!(f, ",")?; @@ -207,6 +210,16 @@ impl App { fn into_command(self) -> Command { let mut cmd = Command::new("cargo"); cmd.arg("xtask"); + + if self.global_args.features != Features::default() { + cmd.arg("--features") + .arg(self.global_args.features.to_string()); + } + + if let Some(profile) = self.global_args.profile { + cmd.arg("--profile").arg(profile); + } + match self.subcmd { Xtasks::Macros { macro_name } => { cmd.arg("macros").arg(macro_name.as_ref()); @@ -281,7 +294,16 @@ impl App { pub(crate) fn into_ci_row(self, os: String) -> CiMatrixRow { CiMatrixRow { command: self.clone().into_command_string().into_string().unwrap(), - name: format!("{} - {}", self.subcmd.as_ref(), self.global_args.features), + name: format!( + "{}({}) - {}", + self.subcmd.as_ref(), + os, + if self.global_args.features == Features::all_features() { + "all features".to_owned() + } else { + self.global_args.features.to_string() + } + ), os, } } @@ -289,7 +311,7 @@ impl App { #[derive(Debug, Parser, Clone)] struct GlobalArgs { - #[clap(long, short, global = true, value_parser=clap::value_parser!(Features), value_name=Features::to_placeholder(), default_value="lua54",required = false)] + #[clap(long, short, global = true, value_parser=clap::value_parser!(Features), value_name=Features::to_placeholder(), default_value=Features::default().to_string(),required = false)] features: Features, #[clap( @@ -355,7 +377,6 @@ enum Xtasks { Check { #[clap( long, - short, default_value = "false", help = "Run in the expected format for rust-analyzer's override check command" )] @@ -363,7 +384,6 @@ enum Xtasks { #[clap( long, - short, default_value = "all", value_parser=clap::value_parser!(CheckKind), value_name=CheckKind::to_placeholder(), @@ -375,25 +395,25 @@ enum Xtasks { Docs { /// Open in browser /// This will open the generated docs in the default browser - #[clap(long, short)] + #[clap(long)] open: bool, /// Skip building rust docs - #[clap(long, short)] + #[clap(long)] no_rust_docs: bool, }, /// Build the main workspace, and then run all tests Test { /// Run tests containing the given name only - #[clap(long, short)] + #[clap(long)] name: Option, /// Run tests in the given package only - #[clap(long, short)] + #[clap(long)] package: Option, /// Run tests without coverage - #[clap(long, short)] + #[clap(long)] no_coverage: bool, }, /// Perform a full check as it would be done in CI, except not parallelised @@ -454,22 +474,25 @@ impl Xtasks { // we don't need to verify all feature flags on all platforms, this is mostly a "does it compile" check // for finding out missing compile time logic or bad imports multi_os_steps - .retain(|e| !e.command.contains("build") && !e.command.contains("docs")); + .retain(|e| !e.command.contains(" build") && !e.command.contains(" docs")); let mut macos_matrix = multi_os_steps.clone(); let mut windows_matrix = multi_os_steps.clone(); for row in macos_matrix.iter_mut() { row.os = "macos-latest".to_owned(); + row.name = row.name.replace("ubuntu-latest", "macos-latest"); } for row in windows_matrix.iter_mut() { row.os = "windows-latest".to_owned(); + row.name = row.name.replace("ubuntu-latest", "windows-latest"); } matrix.extend(macos_matrix); matrix.extend(windows_matrix); + matrix.sort_by_key(|e| e.name.to_owned()); let json = serde_json::to_string_pretty(&matrix)?; return Ok(json); } diff --git a/release-plz.toml b/release-plz.toml index a13e3450b6..4de4baff86 100644 --- a/release-plz.toml +++ b/release-plz.toml @@ -3,6 +3,16 @@ dependencies_update = false publish_timeout = "30m" git_release_enable = false git_tag_enable = false +commit_parsers = [ + { message = "^feat", group = "added" }, + { message = "^changed", group = "changed" }, + { message = "^deprecated", group = "deprecated" }, + { message = "^fix", group = "fixed" }, + { message = "^security", group = "security" }, + { message = "^.*", group = "other" }, + # dont include chore changes in changelog + { message = "^chore.*", skip = true }, +] [[package]] name = "bevy_mod_scripting"