Skip to content

Run CI against stable Godot runtime #288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions .github/composite/godot-install/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,19 @@ runs:
# shell: bash

- name: "Download Godot artifact"
env:
ARTIFACT_NAME: ${{ inputs.artifact-name }}
# if: steps.cache-godot.outputs.cache-hit != 'true'
# If a specific Godot revision should be used, rather than latest, use this:
# curl https://nightly.link/Bromeon/godot4-nightly/actions/runs/4910907653/${{ inputs.artifact-name }}.zip \
run: |
curl https://nightly.link/Bromeon/godot4-nightly/workflows/compile-godot/master/${{ inputs.artifact-name }}.zip \
-Lo artifact.zip \
--retry 3
if [[ $ARTIFACT_NAME == *"stable"* ]]; then
url="https://nightly.link/Bromeon/godot4-nightly/workflows/compile-godot-stable/master/$ARTIFACT_NAME.zip"
else
url="https://nightly.link/Bromeon/godot4-nightly/workflows/compile-godot-nightly/master/$ARTIFACT_NAME.zip"
fi

curl "$url" -Lo artifact.zip --retry 3
unzip artifact.zip -d $RUNNER_DIR/godot_bin
shell: bash

Expand Down
77 changes: 46 additions & 31 deletions .github/workflows/full-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,47 +123,64 @@ jobs:
strategy:
fail-fast: false # cancel all jobs as soon as one fails?
matrix:
# Naming: {os}[-{runtimeVersion}]-{apiVersion}
# runtimeVersion = version of Godot binary; apiVersion = version of GDExtension API against which gdext is compiled.

# Order this way because macOS typically has the longest duration, followed by Windows, so it benefits total workflow execution time.
# Additionally, the 'linux (msrv *)' special case will then be listed next to the other 'linux' jobs.
# Note: Windows uses '--target x86_64-pc-windows-msvc' by default as Cargo argument.
include:
# macOS

- name: macos-stableRt-4.0.3
os: macos-12
artifact-name: macos-stable
godot-binary: godot.macos.editor.dev.x86_64
godot-prebuilt-patch: '4.0.3'

- name: macos-4.0.3
os: macos-12
artifact-name: macos
artifact-name: macos-nightly
godot-binary: godot.macos.editor.dev.x86_64
godot-prebuilt-patch: '4.0.3'

- name: macos-double
os: macos-12
artifact-name: macos-double-nightly
godot-binary: godot.macos.editor.dev.double.x86_64
rust-extra-args: --features godot/double-precision

- name: macos-nightly
os: macos-12
artifact-name: macos
artifact-name: macos-nightly
godot-binary: godot.macos.editor.dev.x86_64
rust-extra-args: --features godot/custom-godot
with-llvm: true
godot-prebuilt-patch: '4.1'

# Windows

- name: windows-stableRt-4.0.3
os: windows-latest
artifact-name: windows-stable
godot-binary: godot.windows.editor.dev.x86_64.exe
godot-prebuilt-patch: '4.0.3'

- name: windows-4.0.3
os: windows-latest
artifact-name: windows
artifact-name: windows-nightly
godot-binary: godot.windows.editor.dev.x86_64.exe
godot-prebuilt-patch: '4.0.3'

- name: windows-double
os: windows-latest
artifact-name: windows-double-nightly
godot-binary: godot.windows.editor.dev.double.x86_64.exe
rust-extra-args: --features godot/double-precision

- name: windows-nightly
os: windows-latest
artifact-name: windows
artifact-name: windows-nightly
godot-binary: godot.windows.editor.dev.x86_64.exe
rust-extra-args: --features godot/custom-godot
godot-prebuilt-patch: '4.1'
Expand All @@ -172,44 +189,50 @@ jobs:

# Don't use latest Ubuntu (22.04) as it breaks lots of ecosystem compatibility.
# If ever moving to ubuntu-latest, need to manually install libtinfo5 for LLVM.
- name: linux-stableRt-4.0.3
os: ubuntu-20.04
artifact-name: linux-stable
godot-binary: godot.linuxbsd.editor.dev.x86_64

- name: linux-4.0.3
os: ubuntu-20.04
artifact-name: linux
artifact-name: linux-nightly
godot-binary: godot.linuxbsd.editor.dev.x86_64
godot-check-header: false # disabled for now

- name: linux-4.0.2
os: ubuntu-20.04
artifact-name: linux
artifact-name: linux-nightly
godot-binary: godot.linuxbsd.editor.dev.x86_64
godot-prebuilt-patch: '4.0.2'

- name: linux-4.0.1
os: ubuntu-20.04
artifact-name: linux
artifact-name: linux-nightly
godot-binary: godot.linuxbsd.editor.dev.x86_64
godot-prebuilt-patch: '4.0.1'

- name: linux-4.0
os: ubuntu-20.04
artifact-name: linux
artifact-name: linux-nightly
godot-binary: godot.linuxbsd.editor.dev.x86_64
godot-prebuilt-patch: '4.0'

- name: linux-double
os: ubuntu-20.04
artifact-name: linux-double-nightly
godot-binary: godot.linuxbsd.editor.dev.double.x86_64
rust-extra-args: --features godot/double-precision

- name: linux-features
os: ubuntu-20.04
artifact-name: linux
artifact-name: linux-nightly
godot-binary: godot.linuxbsd.editor.dev.x86_64
rust-extra-args: --features godot/threads,godot/serde

- name: linux-nightly
os: ubuntu-20.04
artifact-name: linux
artifact-name: linux-nightly
godot-binary: godot.linuxbsd.editor.dev.x86_64
rust-extra-args: --features godot/custom-godot
godot-prebuilt-patch: '4.1'
Expand All @@ -220,35 +243,27 @@ jobs:
# The gcc version can possibly be removed later, as it is slower and needs a larger artifact than the clang one.

# --disallow-focus: fail if #[itest(focus)] is encountered, to prevent running only a few tests for full CI
- name: linux-memcheck-gcc-4.0.3
os: ubuntu-20.04
artifact-name: linux-memcheck-gcc
godot-binary: godot.linuxbsd.editor.dev.x86_64.san
godot-args: -- --disallow-focus
rust-toolchain: nightly
rust-env-rustflags: -Zrandomize-layout

- name: linux-memcheck-clang-4.0.3
- name: linux-memcheck-stableRt-4.0.3
os: ubuntu-20.04
artifact-name: linux-memcheck-clang
artifact-name: linux-memcheck-clang-stable
godot-binary: godot.linuxbsd.editor.dev.x86_64.llvm.san
godot-args: -- --disallow-focus
rust-toolchain: nightly
rust-env-rustflags: -Zrandomize-layout

- name: linux-memcheck-gcc-nightly
os: ubuntu-20.04
artifact-name: linux-memcheck-gcc
godot-binary: godot.linuxbsd.editor.dev.x86_64.san
godot-args: -- --disallow-focus
rust-toolchain: nightly
rust-env-rustflags: -Zrandomize-layout
rust-extra-args: --features godot/custom-godot
godot-prebuilt-patch: '4.1'
# FIXME(#298): memory leaks detected when running 4.0.3 API with 4.1+ binary
# - name: linux-memcheck-4.0.3
# os: ubuntu-20.04
# artifact-name: linux-memcheck-clang-nightly
# godot-binary: godot.linuxbsd.editor.dev.x86_64.llvm.san
# godot-args: -- --disallow-focus
# rust-toolchain: nightly
# rust-env-rustflags: -Zrandomize-layout

- name: linux-memcheck-clang-nightly
- name: linux-memcheck-nightly
os: ubuntu-20.04
artifact-name: linux-memcheck-clang
artifact-name: linux-memcheck-clang-nightly
godot-binary: godot.linuxbsd.editor.dev.x86_64.llvm.san
godot-args: -- --disallow-focus
rust-toolchain: nightly
Expand All @@ -263,7 +278,7 @@ jobs:
- name: "Run Godot integration test"
uses: ./.github/composite/godot-itest
with:
artifact-name: godot-${{ matrix.artifact-name || matrix.name }}
artifact-name: godot-${{ matrix.artifact-name }}
godot-binary: ${{ matrix.godot-binary }}
godot-args: ${{ matrix.godot-args }}
godot-prebuilt-patch: ${{ matrix.godot-prebuilt-patch }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/minimal-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
- name: "Run Godot integration test"
uses: ./.github/composite/godot-itest
with:
artifact-name: godot-linux
artifact-name: godot-linux-nightly
godot-binary: godot.linuxbsd.editor.dev.x86_64


Expand Down
6 changes: 3 additions & 3 deletions godot-bindings/src/godot_exe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

//! Commands related to Godot executable

use crate::custom::godot_version::GodotVersion;
use crate::godot_version::parse_godot_version;
use crate::header_gen::generate_rust_binding;
use crate::watch::StopWatch;
use crate::GodotVersion;

use regex::Regex;
use std::fs;
Expand Down Expand Up @@ -99,7 +99,7 @@ fn update_version_file(version: &str) {
}
*/

fn read_godot_version(godot_bin: &Path) -> GodotVersion {
pub(crate) fn read_godot_version(godot_bin: &Path) -> GodotVersion {
let output = Command::new(godot_bin)
.arg("--version")
.output()
Expand Down Expand Up @@ -259,7 +259,7 @@ fn polyfill_legacy_header(c: &mut String) {
);
}

fn locate_godot_binary() -> PathBuf {
pub(crate) fn locate_godot_binary() -> PathBuf {
if let Ok(string) = std::env::var("GODOT4_BIN") {
println!("Found GODOT4_BIN with path to executable: '{string}'");
println!("cargo:rerun-if-env-changed=GODOT4_BIN");
Expand Down
19 changes: 1 addition & 18 deletions godot-bindings/src/godot_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,11 @@

//#![allow(unused_variables, dead_code)]

use crate::GodotVersion;
use regex::{Captures, Regex};
use std::error::Error;
use std::str::FromStr;

#[derive(Debug, Eq, PartialEq)]
pub struct GodotVersion {
/// the original string (trimmed, stripped of text around)
pub full_string: String,

pub major: u8,
pub minor: u8,

/// 0 if none
pub patch: u8,

/// alpha|beta|dev|stable
pub status: String,

/// Git revision 'custom_build.{rev}' or '{official}.rev', if available
pub custom_rev: Option<String>,
}

pub fn parse_godot_version(version_str: &str) -> Result<GodotVersion, Box<dyn Error>> {
// Format of the string emitted by `godot --version`:
// https://github.com/godot-rust/gdext/issues/118#issuecomment-1465748123
Expand Down
59 changes: 59 additions & 0 deletions godot-bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ compile_error!(
"At least one of `custom-godot` or `prebuilt-godot` must be specified (none given)."
);

// This is outside of `godot_version` to allow us to use it even when we don't have the `custom-godot`
// feature enabled.
#[derive(Debug, Eq, PartialEq)]
pub struct GodotVersion {
/// the original string (trimmed, stripped of text around)
pub full_string: String,

pub major: u8,
pub minor: u8,

/// 0 if none
pub patch: u8,

/// alpha|beta|dev|stable
pub status: String,

/// Git revision 'custom_build.{rev}' or '{official}.rev', if available
pub custom_rev: Option<String>,
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
// Regenerate all files

Expand All @@ -41,6 +61,10 @@ mod custom {
pub fn write_gdextension_headers_from_c(h_path: &Path, rs_path: &Path, watch: &mut StopWatch) {
godot_exe::write_gdextension_headers(h_path, rs_path, true, watch);
}

pub(crate) fn get_godot_version() -> GodotVersion {
godot_exe::read_godot_version(&godot_exe::locate_godot_binary())
}
}

#[cfg(feature = "custom-godot")]
Expand Down Expand Up @@ -70,6 +94,23 @@ mod prebuilt {
.unwrap_or_else(|e| panic!("failed to write gdextension_interface.rs: {e}"));
watch.record("write_header_rs");
}

pub(crate) fn get_godot_version() -> GodotVersion {
let version: Vec<&str> = godot4_prebuilt::GODOT_VERSION
.split('.')
.collect::<Vec<_>>();
GodotVersion {
full_string: godot4_prebuilt::GODOT_VERSION.into(),
major: version[0].parse().unwrap(),
minor: version[1].parse().unwrap(),
patch: version
.get(2)
.and_then(|patch| patch.parse().ok())
.unwrap_or(0),
status: "stable".into(),
custom_rev: None,
}
}
}

#[cfg(not(feature = "custom-godot"))]
Expand All @@ -85,3 +126,21 @@ pub fn clear_dir(dir: &Path, watch: &mut StopWatch) {
}
std::fs::create_dir_all(dir).unwrap_or_else(|e| panic!("failed to create dir: {e}"));
}

pub fn emit_godot_version_cfg() {
let GodotVersion {
major,
minor,
patch,
..
} = get_godot_version();

println!(r#"cargo:rustc-cfg=gdextension_api="{major}.{minor}""#);

// Godot drops the patch version if it is 0.
if patch != 0 {
println!(r#"cargo:rustc-cfg=gdextension_exact_api="{major}.{minor}.{patch}""#);
} else {
println!(r#"cargo:rustc-cfg=gdextension_exact_api="{major}.{minor}""#);
}
}
9 changes: 9 additions & 0 deletions godot-codegen/src/central_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,15 @@ fn make_build_config(header: &Header) -> TokenStream {
String::from_utf8_lossy(c_str.to_bytes()).to_string()
}
}

/// Version of the Godot engine which loaded gdext via GDExtension binding, as
/// `(major, minor, patch)` triple.
pub fn godot_runtime_version_triple() -> (u8, u8, u8) {
let version = unsafe {
crate::runtime_metadata().godot_version
};
(version.major as u8, version.minor as u8, version.patch as u8)
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions godot-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ godot = { path = "../godot" }
serde_json = "1.0"

[build-dependencies]
godot-bindings = { path = "../godot-bindings" }
godot-codegen = { path = "../godot-codegen" }
2 changes: 2 additions & 0 deletions godot-core/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ fn main() {

godot_codegen::generate_core_files(gen_path);
println!("cargo:rerun-if-changed=build.rs");

godot_bindings::emit_godot_version_cfg();
}
2 changes: 1 addition & 1 deletion godot-core/src/builtin/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ impl<T: VariantMetadata> FromVariant for Array<T> {
}

let array = unsafe {
Self::from_sys_init(|self_ptr| {
sys::from_sys_init_or_init_default::<Self>(|self_ptr| {
let array_from_variant = sys::builtin_fn!(array_from_variant);
array_from_variant(self_ptr, variant.var_sys());
})
Expand Down
Loading