Skip to content
Closed
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
107 changes: 84 additions & 23 deletions .github/workflows/push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,124 @@ on:
branches:
- main
pull_request:
workflow_dispatch:

env:
# For setup-rust, see https://github.com/moonrepo/setup-rust/issues/22
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
install-and-build-shaders:
test-os:
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
rust-gpu-version: [latest]
runs-on: ${{ matrix.os }}
env:
RUST_LOG: debug
steps:
- uses: actions/checkout@v4
- uses: cargo-bins/cargo-binstall@main
- run: cargo binstall cargo-nextest
- run: cargo fetch --locked
- name: shader-crate-template cargo fetch --locked
run: |
cd ./crates/shader-crate-template
cargo fetch --locked
- run: cargo nextest run
- name: Run a full build
run: cargo xtask test-build

test-rust-gpu-releases:
strategy:
fail-fast: false
matrix:
glam-version: [latest]
include:
# As well as testing on each OS, we also want to test to make sure we're still supporting
# older versions of `rust-gpu`. However, we can assume that these tests are already okay
# across platforms, so we only need to test on Linux, the chepeast in terms of minutes.
#
# `0.7.0` currently fails building `spirv-builder-cli` with:
# """
# package `is_terminal_polyfill v1.70.1` cannot be built because it requires rustc
# package `is_terminal_polyfill v1.70.1` cannot be built because it requires rustc
# 1.70.0 or newer, while the currently active rustc version is 1.69.0-nightly
# """
# It's probably easily fixable. But also `0.7.0` was released in April 2023, so there's
# unlikely many users of it?
- os: ubuntu-latest
rust-gpu-version: 0.8.0
- os: ubuntu-latest
rust-gpu-version: 0.9.0
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
- rust-gpu-version: 0.8.0
- rust-gpu-version: 0.9.0

# target spec introduction
# last version before
# * fails: compiler too old, `serde` using `#[diagnostic]`
# - rust-gpu-version: cc752312c3de6813a41189e46476d5c1be5e0bbe
# glam-version: 0.30.7
# first version requiring target specs
# * fails: target spec mismatch!
# * resolution: Since this is just a few commits, I'd be fine ignoring it.
# - rust-gpu-version: 02cefd101014f66b79dffb20a2c2b5b7c9038401
# glam-version: 0.30.7
# target specs change again just a few commits later
# * fails: compiler too old, `proc-macro2` using `Literal::byte_character`.
# * resolution: want to support, can't be bothered to hack in old proc-macro2 versions
# - rust-gpu-version: bbb61f58b3d24f3f64745050eb214b90bf6dcce9
# glam-version: 0.30.7

# testing rustc 1.5 months later
- rust-gpu-version: eea8998df9dc2fd8e7a65c5b5b7ae20c238a665a
glam-version: 0.30.7

# just after target specs v2 refactor
# before
- rust-gpu-version: a547c6e45266d613d9fec673e869d7a96181e47b
glam-version: 0.30.7
# after
- rust-gpu-version: 2326b87fe1542eeb898065e36ac949307b55386d
glam-version: 0.30.7

# glam semver breakage due to vector type refactor
# before, glam fixed to 0.30.7 in this commit
- rust-gpu-version: f79c4181a5dc2d37303947b113f190930c6c1ce6
# after, glam >0.30.8
- rust-gpu-version: e767f24f2565baf1a71bbaf84d453d181cab2417
runs-on: ubuntu-latest
env:
RUST_LOG: debug
steps:
- uses: actions/checkout@v4
- name: Fetch root dependencies
run: cargo fetch --locked
- name: Fetch shader-crate-template dependencies
run: |
cd ./crates/shader-crate-template
cargo fetch --locked
- run: cargo test
- name: Run a full build
run: cargo xtask test-build --rust-gpu-version ${{ matrix.rust-gpu-version }}
lints:
run: cargo xtask test-build --rust-gpu-version ${{ matrix.rust-gpu-version }} --glam-version ${{ matrix.glam-version }}

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cargo-bins/cargo-binstall@main
- name: Install cargo-shear
run: cargo binstall cargo-shear
- run: cargo binstall cargo-shear
- run: cargo fetch --locked
- run: cargo clippy -- --deny warnings
- run: cargo fmt --check
- run: cargo shear

# This allows us to have a single job we can branch protect on, rather than needing
# to update the branch protection rules when the test matrix changes
test_success:
runs-on: ubuntu-24.04
needs: [test-os, test-rust-gpu-releases, lint]
# Hack for buggy GitHub Actions behavior with skipped checks: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks
if: ${{ always() }}
steps:
# Another hack is to actually check the status of the dependencies or else it'll fall through
- run: |
echo "Checking statuses..."
[[ "${{ needs.test-os.result }}" == "success" ]] || exit 1
[[ "${{ needs.test-rust-gpu-releases.result }}" == "success" ]] || exit 1
[[ "${{ needs.lint.result }}" == "success" ]] || exit 1

defaults:
run:
shell: bash
5 changes: 5 additions & 0 deletions crates/cargo-gpu/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ edition = "2021"
[dependencies.spirv-builder]
package = "rustc_codegen_spirv"
{version_spec}

[dependencies]
elsa = {{ version = "=1.11.2", features = ["indexmap"] }}
indexmap = "1.7.0"
indexmap2 = {{ package = "indexmap", version = "=2.11.4" }}
"#
);
std::fs::write(checkout.join("Cargo.toml"), cargo_toml)
Expand Down
116 changes: 92 additions & 24 deletions crates/xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use anyhow::Context as _;
use clap::Parser as _;
use std::borrow::Cow;

/// Path to the shader crate
const SHADER_CRATE_PATH: &str = "crates/shader-crate-template";
Expand All @@ -20,6 +21,9 @@ enum Cli {
/// Build using the specified version of `spirv-std`.
#[clap(long)]
rust_gpu_version: Option<String>,
/// The version of glam to use
#[clap(long)]
glam_version: Option<String>,
},
}

Expand Down Expand Up @@ -128,40 +132,104 @@ impl ShaderCrateTemplateCargoTomlWriter {
Ok(())
}

/// Replace the `spirv-std` dependency version
fn replace_spirv_std_version(&mut self, version: String) -> anyhow::Result<()> {
let dependencies = self.get_cargo_dependencies_table();
let spirv_std = dependencies.get_mut("spirv-std").unwrap();
*spirv_std = toml::Value::String(version);
self.write_shader_crate_cargo_toml_changes()?;
/// Add or replace a dependency in the shader-crate-template
fn set_dependency(
&mut self,
package: String,
version: DependencyVersion,
) -> anyhow::Result<()> {
if let Some(version) = version.to_toml() {
let dependencies = self.get_cargo_dependencies_table();
dependencies.insert(package, version);
self.write_shader_crate_cargo_toml_changes()?;
}
Ok(())
}

/// Replace the `spirv-std` dependency version
fn set_spirv_std_version(&mut self, version: &str) -> anyhow::Result<()> {
self.set_dependency(
"spirv-std".into(),
DependencyVersion::parse(
version.into(),
"https://github.com/Rust-GPU/rust-gpu".into(),
),
)
}

/// Replace the `glam` dependency version
fn set_dependency_glam(&mut self, version: &str) -> anyhow::Result<()> {
self.set_dependency(
"glam".into(),
DependencyVersion::parse(
version.into(),
"https://github.com/bitshifter/glam-rs".into(),
),
)
}
}

/// The version of a dependency
pub enum DependencyVersion<'a> {
/// Don't change anything, don't replace the dependency nor add it when it's not there.
Latest,
/// A version dependency for crates.io
Crates(Cow<'a, str>),
/// A git dependency on a specific rev
Git {
/// git repo
git: Cow<'a, str>,
/// git commit revision
rev: Cow<'a, str>,
},
}

impl<'a> DependencyVersion<'a> {
/// Try to parse a version from a string
pub fn parse(version: Cow<'a, str>, git: Cow<'a, str>) -> Self {
if version == "latest" {
Self::Latest
} else if version.contains('.') {
Self::Crates(version)
} else {
Self::Git { git, rev: version }
}
}

/// Convert this version to a toml value, may fail if we want the latest version
pub fn to_toml(&self) -> Option<toml::Value> {
match self {
Self::Latest => None,
Self::Crates(version) => Some(toml::Value::String(version.to_string())),
Self::Git { git, rev } => Some(toml::Value::Table(toml::Table::from_iter([
("git".to_owned(), toml::Value::String(git.to_string())),
("rev".to_owned(), toml::Value::String(rev.to_string())),
]))),
}
}
}

/// Run the xtask.
fn main() {
fn main() -> anyhow::Result<()> {
env_logger::builder().init();

let cli = Cli::parse();

match cli {
match &cli {
Cli::TestBuild {
rust_gpu_version: maybe_rust_gpu_version,
glam_version,
} => {
log::info!("installing cargo gpu");
cmd(["cargo", "install", "--path", "crates/cargo-gpu"]).unwrap();
cmd(["cargo", "install", "--path", "crates/cargo-gpu"])?;

log::info!("setup project");
let dir = tempfile::TempDir::with_prefix("test-shader-output").unwrap();
let mut overwriter = ShaderCrateTemplateCargoTomlWriter::new();
overwriter.replace_output_dir(dir.path()).unwrap();

if let Some(rust_gpu_version) = maybe_rust_gpu_version {
if rust_gpu_version != "latest" {
overwriter
.replace_spirv_std_version(rust_gpu_version)
.unwrap();
}
let dir = tempfile::TempDir::with_prefix("test-shader-output")?;
overwriter.replace_output_dir(dir.path())?;
if let Some(rust_gpu_version) = maybe_rust_gpu_version.as_ref() {
overwriter.set_spirv_std_version(&rust_gpu_version)?;
}
if let Some(glam_version) = glam_version.as_ref() {
overwriter.set_dependency_glam(&glam_version)?;
}

log::info!("building with auto-install");
Expand All @@ -174,12 +242,12 @@ fn main() {
"--auto-install-rust-toolchain",
"--rebuild-codegen",
"--force-overwrite-lockfiles-v4-to-v3",
])
.unwrap();
])?;

cmd(["ls", "-lah", dir.path().to_str().unwrap()]).unwrap();
cmd(["ls", "-lah", dir.path().to_str().unwrap()])?;
//NOTE: manifest.json is the default value here, which should be valid
cmd(["cat", dir.path().join("manifest.json").to_str().unwrap()]).unwrap();
cmd(["cat", dir.path().join("manifest.json").to_str().unwrap()])?;
}
}
Ok(())
}
Loading