From 2ab42600c9fb5f2c19494f32a3fd4e6d15b812ff Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2026 19:53:30 +1200 Subject: [PATCH 1/7] feat: add simple typst bindings as proof of concept --- Cargo.lock | 52 +++++++++++++ Cargo.toml | 4 +- bindings/typst/Cargo.toml | 31 ++++++++ bindings/typst/LICENSE | 1 + bindings/typst/README.md | 41 ++++++++++ bindings/typst/examples/cnvx.wasm | Bin 0 -> 173353 bytes bindings/typst/examples/power.pdf | Bin 0 -> 16844 bytes bindings/typst/examples/power.typ | 35 +++++++++ bindings/typst/justfile | 3 + bindings/typst/src/lib.rs | 123 ++++++++++++++++++++++++++++++ 10 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 bindings/typst/Cargo.toml create mode 120000 bindings/typst/LICENSE create mode 100644 bindings/typst/README.md create mode 100755 bindings/typst/examples/cnvx.wasm create mode 100644 bindings/typst/examples/power.pdf create mode 100644 bindings/typst/examples/power.typ create mode 100644 bindings/typst/justfile create mode 100644 bindings/typst/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a92bc17..228f4e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -274,6 +274,18 @@ dependencies = [ "test-case", ] +[[package]] +name = "cnvx-typst" +version = "0.0.1" +dependencies = [ + "cnvx-graph", + "cnvx-lp", + "cnvx-math", + "serde", + "serde_json", + "wasm-minimal-protocol", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -1456,6 +1468,19 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1836,6 +1861,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "venial" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61584a325b16f97b5b25fcc852eb9550843a251057a5e3e5992d2376f3df4bb2" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -1929,6 +1964,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-minimal-protocol" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae17f1dd65ee737caf73ea45f517c09578ab60970c28e5e96b7900fe2e245633" +dependencies = [ + "proc-macro2", + "quote", + "venial", +] + [[package]] name = "web-sys" version = "0.3.85" @@ -2348,3 +2394,9 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index b43ee8f..de768ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ cnvx-graph = { workspace = true, optional = true } workspace = true [workspace] -members = ["crates/*", "tests"] +members = ["crates/*", "tests", "bindings/*"] default-members = ["crates/cnvx-cli"] resolver = "2" @@ -39,7 +39,7 @@ keywords = ["optimization", "linear-programming", "convex"] readme = "README.md" [workspace.dependencies] -cnvx = { path = "crates/cnvx", version = "0.0.1" } +cnvx = { path = ".", version = "0.0.1" } cnvx-cli = { path = "crates/cnvx-cli", version = "0.0.1" } cnvx-core = { path = "crates/cnvx-core", version = "0.0.1" } cnvx-lp = { path = "crates/cnvx-lp", version = "0.0.1" } diff --git a/bindings/typst/Cargo.toml b/bindings/typst/Cargo.toml new file mode 100644 index 0000000..eec3a66 --- /dev/null +++ b/bindings/typst/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "cnvx-typst" +version = "0.0.1" +edition = { workspace = true } +description = "Typst WebAssembly bindings for the cnvx optimization library" +authors = { workspace = true } +repository = { workspace = true } +license = { workspace = true } +keywords = { workspace = true } +readme = { workspace = true } +publish = false + +[lib] +name = "cnvx" +crate-type = ["cdylib"] +path = "src/lib.rs" +doc = false + +[dependencies] +cnvx-lp = { workspace = true } +cnvx-math = { workspace = true } +cnvx-graph = { workspace = true } +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0.150" +wasm-minimal-protocol = "0.2.0" + +[profile.release] +opt-level = "z" # minimise WASM binary size +lto = true +codegen-units = 1 +strip = true diff --git a/bindings/typst/LICENSE b/bindings/typst/LICENSE new file mode 120000 index 0000000..30cff74 --- /dev/null +++ b/bindings/typst/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/bindings/typst/README.md b/bindings/typst/README.md new file mode 100644 index 0000000..387ca70 --- /dev/null +++ b/bindings/typst/README.md @@ -0,0 +1,41 @@ +# cnvx-typst + +**cnvx-typst** provides Typst bindings for the [cnvx](https://github.com/chriso345/cnvx) optimization library. + +> [!WARNING] +> Typst bindings are currently in early development and may not yet cover all features of the Rust library. The API is subject to change as development progresses. + +--- + +## Installation + +Requires [Rust](https://rustup.rs) and optionally [just](https://github.com/casey/just/). + +`cnvx` is currently only available via source installation. Clone the repository and run the following commands to build the WebAssembly plugin from this directory: + +With `just`: + +```bash +just build +``` + +Without `just`: + +```bash +cargo build --release --target wasm32-unknown-unknown + +# To run the examples: +cp ../../target/wasm32-unknown-unknown/release/cnvx_typst.wasm examples/cnvx.wasm +``` + +You will also need the WASM target installed: + +```bash +rustup target add wasm32-unknown-unknown +``` + +--- + +## License + +Licensed under the MIT License. See the [LICENSE](LICENSE) file for more details. diff --git a/bindings/typst/examples/cnvx.wasm b/bindings/typst/examples/cnvx.wasm new file mode 100755 index 0000000000000000000000000000000000000000..6ada7b6d9e4d1deb6ccd43bd84e4e33591aa8e42 GIT binary patch literal 173353 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
gevUy91|mcejc;ykjkcb92ezSndF( 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 HNQA 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 literal 0 HcmV?d00001 diff --git a/bindings/typst/examples/power.typ b/bindings/typst/examples/power.typ new file mode 100644 index 0000000..f739ce6 --- /dev/null +++ b/bindings/typst/examples/power.typ @@ -0,0 +1,35 @@ +#let cnvx = plugin("cnvx.wasm") + +#let solve-lp(request) = { + let bytes = cnvx.solve_lp(bytes(json.encode(request))) + json(bytes) +} + +// Define the power grid problem +#let result = solve-lp(( + vars: ( + (name: "Gas", lb: 0.0, ub: 200.0), + (name: "Coal", lb: 0.0, ub: 180.0), + (name: "Wind", lb: 0.0, ub: 120.0), + ), + constraints: ( + (expr: (Gas: 1.0, Coal: 1.0, Wind: 1.0), op: "eq", rhs: 300.0), + (expr: (Gas: 1.0, Coal: -0.5), op: "leq", rhs: 0.0), + (expr: (Gas: 1.0, Coal: 1.0), op: "geq", rhs: 150.0), + ), + objective: ( + sense: "minimize", + expr: (Gas: 50.0, Coal: 80.0), + ), +)) + += Power Grid Dispatch + +#table( + columns: 2, + [*Variable*], [*Value*], + [Gas], [#result.values.Gas MW], + [Coal], [#result.values.Coal MW], + [Wind], [#result.values.Wind MW], + [*Total cost*], [*\$#result.objective*], +) diff --git a/bindings/typst/justfile b/bindings/typst/justfile new file mode 100644 index 0000000..ef8c2e5 --- /dev/null +++ b/bindings/typst/justfile @@ -0,0 +1,3 @@ +build: + cargo build --release --target wasm32-unknown-unknown + cp ../../target/wasm32-unknown-unknown/release/cnvx.wasm examples/cnvx.wasm diff --git a/bindings/typst/src/lib.rs b/bindings/typst/src/lib.rs new file mode 100644 index 0000000..84edfdb --- /dev/null +++ b/bindings/typst/src/lib.rs @@ -0,0 +1,123 @@ +use cnvx_lp::*; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use wasm_minimal_protocol::*; + +initiate_protocol!(); + +// Request types + +#[derive(Deserialize)] +struct VarDef { + name: String, + lb: Option, + ub: Option, +} + +#[derive(Deserialize)] +struct ConstraintDef { + expr: HashMap, + op: String, + rhs: f64, +} + +#[derive(Deserialize)] +struct ObjectiveDef { + sense: String, + expr: HashMap, +} + +#[derive(Deserialize)] +struct SolveRequest { + vars: Vec, + constraints: Vec, + objective: ObjectiveDef, +} + +// Response types + +#[derive(Serialize)] +struct SolveResponse { + status: String, + objective: Option, + values: HashMap, + error: Option, +} + +impl SolveResponse { + fn error(msg: impl Into) -> Self { + Self { + status: "error".into(), + objective: None, + values: HashMap::new(), + error: Some(msg.into()), + } + } +} + +// Plugin entry point +#[wasm_func] +pub fn solve_lp(input: &[u8]) -> Result, Box> { + let req = serde_json::from_slice::(input)?; + let response = run_solve(req); + Ok(serde_json::to_vec(&response)?) +} + +fn run_solve(req: SolveRequest) -> SolveResponse { + let mut model = LpModel::new(); + let mut name_to_var: HashMap = HashMap::new(); + + for def in &req.vars { + let b = model.add_var(); + let id = b.var; + drop(b); + let var = &mut model.vars[id.0]; + var.name = Some(def.name.clone()); + var.lb = def.lb; + var.ub = def.ub; + name_to_var.insert(def.name.clone(), id); + } + + for def in &req.constraints { + let expr = build_expr(&def.expr, &name_to_var); + let constraint = match def.op.as_str() { + "eq" => expr.eq(def.rhs), + "leq" => expr.leq(def.rhs), + "geq" => expr.geq(def.rhs), + op => return SolveResponse::error(format!("unknown op: {op}")), + }; + model += constraint; + } + + let obj_expr = build_expr(&req.objective.expr, &name_to_var); + let objective = match req.objective.sense.as_str() { + "minimize" => Objective::minimize(obj_expr).name("objective"), + "maximize" => Objective::maximize(obj_expr).name("objective"), + s => return SolveResponse::error(format!("unknown sense: {s}")), + }; + model.add_objective(objective); + + match LpSolver::new().solve(&model) { + Ok(sol) => SolveResponse { + status: "optimal".into(), + objective: sol.objective_value, + values: name_to_var + .iter() + .map(|(name, id)| (name.clone(), sol.value(*id))) + .collect(), + error: None, + }, + Err(e) => SolveResponse { + status: "error".into(), + objective: None, + values: HashMap::new(), + error: Some(e.to_string()), + }, + } +} + +fn build_expr(terms: &HashMap, vars: &HashMap) -> LinExpr { + terms.iter().fold(LinExpr::constant(0.0), |acc, (name, &coeff)| { + if let Some(&id) = vars.get(name) { acc + LinExpr::new(id, coeff) } else { acc } + }) +} From 1e40584578d71a1b47ac454214cfdcb6a845da2a Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2026 20:00:52 +1200 Subject: [PATCH 2/7] ci: remove slow tests for now, only run tests if content changes --- .github/workflows/ci.yml | 32 ++++++++++++++++++++++++++++++-- tests/src/netlib.rs | 8 ++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73fb1d5..b9f4b89 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,27 @@ env: CARGO_TERM_COLOR: always jobs: + changes: + name: Detect Changes + runs-on: ubuntu-latest + outputs: + crates: ${{ steps.filter.outputs.crates }} + integration: ${{ steps.filter.outputs.integration }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + crates: + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + integration: + - 'crates/**' + - 'tests/**' + - 'Cargo.toml' + - 'Cargo.lock' required: name: Required Checks runs-on: ubuntu-latest @@ -34,7 +55,7 @@ jobs: echo "Upstream results: $results" - if echo "$results" | grep -qE '(failure|cancelled|skipped)'; then + if echo "$results" | grep -qE '(failure|cancelled)'; then result="failed" else result="success" @@ -78,7 +99,10 @@ jobs: test: name: Test - Crate runs-on: ubuntu-latest - needs: find-crates + needs: + - changes + - find-crates + if: needs.changes.outputs.crates == 'true' strategy: matrix: crate: ${{ fromJSON(needs.find-crates.outputs.crates) }} @@ -91,8 +115,12 @@ jobs: name: Integration Test - Crate runs-on: ubuntu-latest needs: + - changes - build - test + if: | + needs.changes.outputs.integration == 'true' && + needs.test.result != 'failure' steps: - name: Checkout uses: actions/checkout@v4 diff --git a/tests/src/netlib.rs b/tests/src/netlib.rs index 12c6912..feb108e 100644 --- a/tests/src/netlib.rs +++ b/tests/src/netlib.rs @@ -144,12 +144,12 @@ fn run_cnvx(mps: &Path) -> Result { } #[test_case("afiro", Some(-4.6475314286E+02))] -#[test_case("adlittle", Some(2.2549496316E+05))] -#[test_case("sc50b", Some(-7.0000000000E+01))] +// #[test_case("adlittle", Some(2.2549496316E+05))] #[test_case("sc50a", Some(-6.4575077059E+01))] -#[test_case("sc105", Some(-5.2202061212E+01))] +#[test_case("sc50b", Some(-7.0000000000E+01))] +// #[test_case("sc105", Some(-5.2202061212E+01))] // #[test_case("share1b", Some(-7.6589318579E+04))] -#[test_case("share2b", Some(-4.1573224074E+02))] +// #[test_case("share2b", Some(-4.1573224074E+02))] fn netlib_test(name: &str, expected: Option) { let lp = ensure_lp_file(name, expected); run_emps(&lp); From 720964e3ae8667fc79f9748e311349de933d59dc Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2026 20:03:26 +1200 Subject: [PATCH 3/7] fix: clippy errors --- bindings/typst/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/bindings/typst/src/lib.rs b/bindings/typst/src/lib.rs index 84edfdb..8cd13da 100644 --- a/bindings/typst/src/lib.rs +++ b/bindings/typst/src/lib.rs @@ -70,7 +70,6 @@ fn run_solve(req: SolveRequest) -> SolveResponse { for def in &req.vars { let b = model.add_var(); let id = b.var; - drop(b); let var = &mut model.vars[id.0]; var.name = Some(def.name.clone()); var.lb = def.lb; From b42a3eeeffa17b0c51afbc5259686c10f400a36c Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2026 20:07:47 +1200 Subject: [PATCH 4/7] ci: update ci for crate filter --- .github/workflows/ci.yml | 44 +++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9f4b89..3a88997 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,11 +15,28 @@ env: CARGO_TERM_COLOR: always jobs: + find-crates: + name: Discover Crates + runs-on: ubuntu-latest + outputs: + crates: ${{ steps.list-crates.outputs.crates }} + filters: ${{ steps.list-crates.outputs.filters }} + steps: + - uses: actions/checkout@v4 + - id: list-crates + run: | + crates=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | jq -R -s -c 'split("\n")[:-1]') + echo "crates=$crates" >> $GITHUB_OUTPUT + filters=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | jq -R -s -c ' + split("\n")[:-1] | map({ key: ., value: ["crates/" + . + "/**", "Cargo.toml", "Cargo.lock"] }) | from_entries + ') + echo "filters=$filters" >> $GITHUB_OUTPUT changes: name: Detect Changes runs-on: ubuntu-latest + needs: find-crates outputs: - crates: ${{ steps.filter.outputs.crates }} + crates: ${{ steps.filter.outputs.changes }} integration: ${{ steps.filter.outputs.integration }} steps: - uses: actions/checkout@v4 @@ -27,10 +44,7 @@ jobs: id: filter with: filters: | - crates: - - 'crates/**' - - 'Cargo.toml' - - 'Cargo.lock' + ${{ fromJSON(needs.find-crates.outputs.filters) }} integration: - 'crates/**' - 'tests/**' @@ -52,18 +66,14 @@ jobs: if: always() run: | results=$(tr -d '\n' <<< '${{ toJSON(needs.*.result) }}') - echo "Upstream results: $results" - if echo "$results" | grep -qE '(failure|cancelled)'; then result="failed" else result="success" fi - echo "result=$result" >> $GITHUB_OUTPUT echo "results=$results" >> $GITHUB_OUTPUT - - if: steps.status.outputs.result != 'success' name: Fail if any upstream failed run: | @@ -102,10 +112,10 @@ jobs: needs: - changes - find-crates - if: needs.changes.outputs.crates == 'true' + if: needs.changes.outputs.crates != '[]' strategy: matrix: - crate: ${{ fromJSON(needs.find-crates.outputs.crates) }} + crate: ${{ fromJSON(needs.changes.outputs.crates) }} steps: - uses: actions/checkout@v4 - name: Run ${{ matrix.crate }} tests @@ -129,15 +139,3 @@ jobs: # or something within the solver. - name: Run integration tests run: timeout 240s cargo netlib -- --nocapture - - find-crates: - name: Discover Crates - runs-on: ubuntu-latest - outputs: - crates: ${{ steps.list-crates.outputs.crates }} - steps: - - uses: actions/checkout@v4 - - id: list-crates - run: | - crates=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | jq -R -s -c 'split("\n")[:-1]') - echo "crates=$crates" >> $GITHUB_OUTPUT From d6c2e07b751ec3193f0dd811947d3d11ec3dde6f Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2026 20:10:36 +1200 Subject: [PATCH 5/7] ci: fix ci --- .github/workflows/ci.yml | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a88997..382a397 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,10 +27,22 @@ jobs: run: | crates=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | jq -R -s -c 'split("\n")[:-1]') echo "crates=$crates" >> $GITHUB_OUTPUT - filters=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | jq -R -s -c ' - split("\n")[:-1] | map({ key: ., value: ["crates/" + . + "/**", "Cargo.toml", "Cargo.lock"] }) | from_entries - ') - echo "filters=$filters" >> $GITHUB_OUTPUT + filters=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | while read -r crate; do + echo "${crate}:" + echo " - 'crates/${crate}/**'" + echo " - 'Cargo.toml'" + echo " - 'Cargo.lock'" + done) + filters="${filters} + integration: + - 'crates/**' + - 'tests/**' + - 'Cargo.toml' + - 'Cargo.lock'" + echo "filters<> $GITHUB_OUTPUT + echo "$filters" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + changes: name: Detect Changes runs-on: ubuntu-latest @@ -43,13 +55,8 @@ jobs: - uses: dorny/paths-filter@v3 id: filter with: - filters: | - ${{ fromJSON(needs.find-crates.outputs.filters) }} - integration: - - 'crates/**' - - 'tests/**' - - 'Cargo.toml' - - 'Cargo.lock' + filters: ${{ needs.find-crates.outputs.filters }} + required: name: Required Checks runs-on: ubuntu-latest From 79fc3767cc9e25f84e7b11af677009e17177f813 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2026 20:16:39 +1200 Subject: [PATCH 6/7] ci: fix ci --- .github/workflows/ci.yml | 83 +++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 382a397..1657c5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,72 +1,84 @@ name: CI / Build & Test - -on: +'on': push: - branches: [master] + branches: + - master pull_request: - branches: [master] + branches: + - master workflow_dispatch: {} - concurrency: - group: ${{ github.workflow }}-${{ github.ref_name != 'master' && github.ref || github.run_id }} + group: >- + ${{ github.workflow }}-${{ github.ref_name != 'master' && github.ref || + github.run_id }} cancel-in-progress: true - env: CARGO_TERM_COLOR: always - jobs: find-crates: name: Discover Crates runs-on: ubuntu-latest outputs: - crates: ${{ steps.list-crates.outputs.crates }} - filters: ${{ steps.list-crates.outputs.filters }} + crates: '${{ steps.list-crates.outputs.crates }}' + filters: '${{ steps.list-crates.outputs.filters }}' steps: - uses: actions/checkout@v4 - id: list-crates - run: | - crates=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | jq -R -s -c 'split("\n")[:-1]') + run: > + crates=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} + \; | jq -R -s -c 'split("\n")[:-1]') + echo "crates=$crates" >> $GITHUB_OUTPUT - filters=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | while read -r crate; do + + filters=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename + {} \; | while read -r crate; do echo "${crate}:" echo " - 'crates/${crate}/**'" echo " - 'Cargo.toml'" echo " - 'Cargo.lock'" done) + filters="${filters} + integration: - 'crates/**' - 'tests/**' - 'Cargo.toml' - 'Cargo.lock'" echo "filters<> $GITHUB_OUTPUT + echo "$filters" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT changes: name: Detect Changes runs-on: ubuntu-latest needs: find-crates outputs: - crates: ${{ steps.filter.outputs.changes }} - integration: ${{ steps.filter.outputs.integration }} + crates: '${{ steps.build-outputs.outputs.crates }}' + testing: '${{ steps.filter.outputs.integration }}' steps: - uses: actions/checkout@v4 - uses: dorny/paths-filter@v3 id: filter with: - filters: ${{ needs.find-crates.outputs.filters }} + list-files: none + filters: '${{ needs.find-crates.outputs.filters }}' + - id: build-outputs + run: > + crates=$(echo '${{ steps.filter.outputs.changes }}' | jq -c '[.[] | + select(. != "integration")]') + echo "crates=$crates" >> $GITHUB_OUTPUT required: name: Required Checks runs-on: ubuntu-latest - if: always() # Always run to determine status of upstream jobs + if: always() needs: - build - integration-test - lint - test - steps: - id: status name: Determine status @@ -83,51 +95,47 @@ jobs: echo "results=$results" >> $GITHUB_OUTPUT - if: steps.status.outputs.result != 'success' name: Fail if any upstream failed - run: | - echo "One or more upstream jobs failed: ${{ steps.status.outputs.results }}" - exit 1 + run: > + echo "One or more upstream jobs failed: ${{ + steps.status.outputs.results }}" + exit 1 build: name: Build - Workspace runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - - name: Build run: cargo build --workspace --all-targets - lint: - name: Lint, Format and Docs - Workspace + name: 'Lint, Format and Docs - Workspace' runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - - name: Run Clippy run: cargo clippy --workspace --all-targets -- -D warnings - - name: Check Formatting run: cargo fmt --all -- --check - - name: Check Docs - run: RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --document-private-items - + run: >- + RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps + --document-private-items test: name: Test - Crate runs-on: ubuntu-latest needs: - changes - find-crates - if: needs.changes.outputs.crates != '[]' + if: 'needs.changes.outputs.crates != ''[]''' strategy: matrix: - crate: ${{ fromJSON(needs.changes.outputs.crates) }} + crate: '${{ fromJSON(needs.changes.outputs.crates) }}' steps: - uses: actions/checkout@v4 - - name: Run ${{ matrix.crate }} tests - run: cargo test -p ${{ matrix.crate }} - + - name: 'Run ${{ matrix.crate }} tests' + run: 'cargo test -p ${{ matrix.crate }}' integration-test: name: Integration Test - Crate runs-on: ubuntu-latest @@ -136,13 +144,10 @@ jobs: - build - test if: | - needs.changes.outputs.integration == 'true' && + needs.changes.outputs.testing == 'true' && needs.test.result != 'failure' steps: - name: Checkout uses: actions/checkout@v4 - - # FIXME: This timeout should be replaced with either something in the test itself - # or something within the solver. - name: Run integration tests run: timeout 240s cargo netlib -- --nocapture From 60e327e2d93e3b84e3098628c3d4786806865159 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2026 20:20:55 +1200 Subject: [PATCH 7/7] ci: update actions to new version --- .github/workflows/ci.yml | 14 +++++++------- .github/workflows/conventional-commit.yml | 2 +- .github/workflows/release.yml | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1657c5a..ce6d0e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: crates: '${{ steps.list-crates.outputs.crates }}' filters: '${{ steps.list-crates.outputs.filters }}' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - id: list-crates run: > crates=$(find crates -maxdepth 1 -mindepth 1 -type d -exec basename {} @@ -58,8 +58,8 @@ jobs: crates: '${{ steps.build-outputs.outputs.crates }}' testing: '${{ steps.filter.outputs.integration }}' steps: - - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v3 + - uses: actions/checkout@v6 + - uses: dorny/paths-filter@v4 id: filter with: list-files: none @@ -105,7 +105,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Build run: cargo build --workspace --all-targets lint: @@ -113,7 +113,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Run Clippy run: cargo clippy --workspace --all-targets -- -D warnings - name: Check Formatting @@ -133,7 +133,7 @@ jobs: matrix: crate: '${{ fromJSON(needs.changes.outputs.crates) }}' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: 'Run ${{ matrix.crate }} tests' run: 'cargo test -p ${{ matrix.crate }}' integration-test: @@ -148,6 +148,6 @@ jobs: needs.test.result != 'failure' steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Run integration tests run: timeout 240s cargo netlib -- --nocapture diff --git a/.github/workflows/conventional-commit.yml b/.github/workflows/conventional-commit.yml index 43253d0..95e7076 100644 --- a/.github/workflows/conventional-commit.yml +++ b/.github/workflows/conventional-commit.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Validate PR title id: check_title diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4d38161..6a6ae37 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable @@ -80,7 +80,7 @@ jobs: -Force - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: ${{ matrix.archive_name }} path: dist/${{ matrix.archive_name }} @@ -98,7 +98,7 @@ jobs: steps: - name: Download artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v6 with: path: dist @@ -117,7 +117,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust uses: dtolnay/rust-toolchain@stable