From 763816d27cc73f4e5fd40f9056c38b6a80379880 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Wed, 11 Nov 2026 12:11:59 -0500 Subject: [PATCH 1/5] ci: run Harden-Runner on every job (#3786) Adds step-security/harden-runner (audit, pinned to v2.22.4 like craft-common-actions) as the first step of each job that did not have it, so every workflow in the org's public repos reports its egress to StepSecurity. Audit, not block: block-mode allow lists come from each job's observed traffic. --- .github/workflows/packaging-lint.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/packaging-lint.yml b/.github/workflows/packaging-lint.yml index 2d1213a4e..758ecac06 100644 --- a/.github/workflows/packaging-lint.yml +++ b/.github/workflows/packaging-lint.yml @@ -27,6 +27,10 @@ jobs: name: Windows installation policy (no app build) runs-on: windows-latest steps: + - name: Harden runner + uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4 + with: + egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false From e258db5f194993166f1a9a4750f05301de5852fd Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Wed, 11 Nov 2026 12:44:25 -0500 Subject: [PATCH 2/5] Updates: take craft-update from craft-libs main at 6e03f65bf --- Cargo.lock | 16 +++++++++------- Cargo.toml | 4 ++-- apps/gridcraft/Cargo.toml | 2 +- crates/ui-egui/Cargo.toml | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a07b445d8..3986edf0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -910,12 +910,12 @@ dependencies = [ [[package]] name = "craft-fonts-build" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=1b34eba41e62138fc2438d2734523b302840b45d#1b34eba41e62138fc2438d2734523b302840b45d" +source = "git+https://github.com/storytold/craft-libs?rev=6e03f65bf45181db77ba6229716e6624db9eb25b#6e03f65bf45181db77ba6229716e6624db9eb25b" [[package]] name = "craft-i18n" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=1b34eba41e62138fc2438d2734523b302840b45d#1b34eba41e62138fc2438d2734523b302840b45d" +source = "git+https://github.com/storytold/craft-libs?rev=6e03f65bf45181db77ba6229716e6624db9eb25b#6e03f65bf45181db77ba6229716e6624db9eb25b" dependencies = [ "fixed_decimal", "icu_decimal", @@ -938,7 +938,7 @@ dependencies = [ [[package]] name = "craft-print" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=1b34eba41e62138fc2438d2734523b302840b45d#1b34eba41e62138fc2438d2734523b302840b45d" +source = "git+https://github.com/storytold/craft-libs?rev=6e03f65bf45181db77ba6229716e6624db9eb25b#6e03f65bf45181db77ba6229716e6624db9eb25b" dependencies = [ "craft-winprint-gdi", "log", @@ -952,7 +952,7 @@ dependencies = [ [[package]] name = "craft-ui" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=1b34eba41e62138fc2438d2734523b302840b45d#1b34eba41e62138fc2438d2734523b302840b45d" +source = "git+https://github.com/storytold/craft-libs?rev=6e03f65bf45181db77ba6229716e6624db9eb25b#6e03f65bf45181db77ba6229716e6624db9eb25b" dependencies = [ "craft-fonts-build", "craft-i18n", @@ -972,7 +972,7 @@ dependencies = [ [[package]] name = "craft-update" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=1b34eba41e62138fc2438d2734523b302840b45d#1b34eba41e62138fc2438d2734523b302840b45d" +source = "git+https://github.com/storytold/craft-libs?rev=6e03f65bf45181db77ba6229716e6624db9eb25b#6e03f65bf45181db77ba6229716e6624db9eb25b" dependencies = [ "chrono", "dunce", @@ -982,6 +982,7 @@ dependencies = [ "image", "log", "plist", + "rustix 1.1.5", "semver", "serde", "serde_json", @@ -1018,7 +1019,7 @@ dependencies = [ [[package]] name = "craft-window" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=1b34eba41e62138fc2438d2734523b302840b45d#1b34eba41e62138fc2438d2734523b302840b45d" +source = "git+https://github.com/storytold/craft-libs?rev=6e03f65bf45181db77ba6229716e6624db9eb25b#6e03f65bf45181db77ba6229716e6624db9eb25b" dependencies = [ "egui", "objc2 0.6.5", @@ -6519,7 +6520,7 @@ dependencies = [ [[package]] name = "winprint" version = "0.2.1" -source = "git+https://github.com/storytold/winprint.rs?rev=51934db382f225454cf152a8657eb03789be63c4#51934db382f225454cf152a8657eb03789be63c4" +source = "git+https://github.com/storytold/winprint.rs?rev=bc06a7c48b768eb27a828c7986f6d2868b245ee0#bc06a7c48b768eb27a828c7986f6d2868b245ee0" dependencies = [ "flate2", "fmt-derive", @@ -6534,6 +6535,7 @@ dependencies = [ "windows", "windows-core", "windows-implement", + "windows-numerics", "xml", ] diff --git a/Cargo.toml b/Cargo.toml index 2e460354f..e0038ca6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ gridcraft-math = { path = "crates/math" } # Every craft-libs crate (craft-update and craft-window here, craft-ui in ui-egui, craft-print in # the app) comes from one craft-libs revision. # craft-update: app-specific pretend versions apply to startup and manual checks. -craft-update = { git = "https://github.com/storytold/craft-libs", rev = "1b34eba41e62138fc2438d2734523b302840b45d", version = "=0.1.0", features = ["egui"] } +craft-update = { git = "https://github.com/storytold/craft-libs", rev = "6e03f65bf45181db77ba6229716e6624db9eb25b", version = "=0.1.0", features = ["egui"] } # foundation thiserror = "2" @@ -72,7 +72,7 @@ skrifa = { version = "0.44", default-features = false, features = ["std"] } epaint_default_fonts = "0.37" # One native window per workbook: the window list, Window menu titles and the immediate-viewport # driver. Same craft-libs revision as craft-update above. -craft-window = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "1b34eba41e62138fc2438d2734523b302840b45d", default-features = false, features = ["egui"] } +craft-window = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "6e03f65bf45181db77ba6229716e6624db9eb25b", default-features = false, features = ["egui"] } [workspace.lints.rust] unsafe_code = "forbid" diff --git a/apps/gridcraft/Cargo.toml b/apps/gridcraft/Cargo.toml index 9365f3e15..8704a6e39 100644 --- a/apps/gridcraft/Cargo.toml +++ b/apps/gridcraft/Cargo.toml @@ -35,7 +35,7 @@ winit = { version = "0.30", default-features = false, features = ["x11", "waylan [target.'cfg(not(target_arch = "wasm32"))'.dependencies] # Same craft-libs revision as the workspace's craft-update and craft-window (see the root # Cargo.toml). -craft-print = { git = "https://github.com/storytold/craft-libs", rev = "1b34eba41e62138fc2438d2734523b302840b45d" } +craft-print = { git = "https://github.com/storytold/craft-libs", rev = "6e03f65bf45181db77ba6229716e6624db9eb25b" } craft-update = { workspace = true } rfd = { workspace = true } arboard = { workspace = true, features = ["image-data"] } diff --git a/crates/ui-egui/Cargo.toml b/crates/ui-egui/Cargo.toml index 3ecbbbbf9..1a1c2a9ab 100644 --- a/crates/ui-egui/Cargo.toml +++ b/crates/ui-egui/Cargo.toml @@ -11,7 +11,7 @@ workspace = true [dependencies] # The shared capture slot (`craft_ui::capture`) comes from the one craft-libs revision every # craft-libs dependency uses (see the root Cargo.toml). -craft-ui = { git = "https://github.com/storytold/craft-libs", rev = "1b34eba41e62138fc2438d2734523b302840b45d" } +craft-ui = { git = "https://github.com/storytold/craft-libs", rev = "6e03f65bf45181db77ba6229716e6624db9eb25b" } gridcraft-engine = { workspace = true } gridcraft-chart = { workspace = true } # `monochrome_emoji_fonts` restores the Noto Emoji and emoji-icon faces that 0.37 moved behind From 7f6a79fd98a3ac4b6bbc9b96d9f123732461d2b1 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Wed, 11 Nov 2026 14:24:13 -0500 Subject: [PATCH 3/5] Fix Flatpak permissions for update checks and self-updates (#3803) * fix(flatpak): allow release checks and self-update helpers * test: keep Flatpak permission parsing within strict Clippy rules --- crates/ui-egui/tests/flatpak_updates.rs | 27 +++++++++++++++++++ .../ai.storyteller.gridcraft.bundle.yml | 2 ++ .../flatpak/ai.storyteller.gridcraft.yml | 2 ++ 3 files changed, 31 insertions(+) create mode 100644 crates/ui-egui/tests/flatpak_updates.rs diff --git a/crates/ui-egui/tests/flatpak_updates.rs b/crates/ui-egui/tests/flatpak_updates.rs new file mode 100644 index 000000000..072176361 --- /dev/null +++ b/crates/ui-egui/tests/flatpak_updates.rs @@ -0,0 +1,27 @@ +//! Release and source Flatpaks must allow release checks and host update helpers. +fn finish_args(manifest: &str) -> Vec<&str> { + manifest + .split("finish-args:") + .nth(1) + .unwrap_or_default() + .lines() + .take_while(|line| line.is_empty() || line.starts_with(' ') || line.starts_with('#')) + .filter_map(|line| line.trim().strip_prefix("- ")) + .map(|arg| arg.trim_matches(['\'', '"'])) + .collect() +} + +#[test] +fn flatpak_update_permissions() { + let manifests = [ + include_str!("../../../packaging/linux/flatpak/ai.storyteller.gridcraft.bundle.yml"), + include_str!("../../../packaging/linux/flatpak/ai.storyteller.gridcraft.yml"), + ]; + let args = manifests.map(finish_args); + assert_eq!(args[0], args[1], "source and release permissions must agree"); + for permissions in args { + for required in ["--share=network", "--talk-name=org.freedesktop.Flatpak"] { + assert!(permissions.contains(&required), "missing update permission: {required}"); + } + } +} diff --git a/packaging/linux/flatpak/ai.storyteller.gridcraft.bundle.yml b/packaging/linux/flatpak/ai.storyteller.gridcraft.bundle.yml index 5926f32f7..ee452af4f 100644 --- a/packaging/linux/flatpak/ai.storyteller.gridcraft.bundle.yml +++ b/packaging/linux/flatpak/ai.storyteller.gridcraft.bundle.yml @@ -17,6 +17,8 @@ runtime-version: '25.08' sdk: org.freedesktop.Sdk command: gridcraft finish-args: + # The shared updater inspects and updates this installation via flatpak-spawn --host. + - --talk-name=org.freedesktop.Flatpak - --filesystem=xdg-data/ArtCraft/versions:ro # Display: Wayland first; X11 only when no Wayland compositor is running. - --socket=wayland diff --git a/packaging/linux/flatpak/ai.storyteller.gridcraft.yml b/packaging/linux/flatpak/ai.storyteller.gridcraft.yml index e493d4855..b3164fbe0 100644 --- a/packaging/linux/flatpak/ai.storyteller.gridcraft.yml +++ b/packaging/linux/flatpak/ai.storyteller.gridcraft.yml @@ -18,6 +18,8 @@ sdk-extensions: - org.freedesktop.Sdk.Extension.rust-stable command: gridcraft finish-args: + # The shared updater inspects and updates this installation via flatpak-spawn --host. + - --talk-name=org.freedesktop.Flatpak - --filesystem=xdg-data/ArtCraft/versions:ro # Display: Wayland first; X11 only when no Wayland compositor is running. - --socket=wayland From 0c5b1e85e6d85072a2430f12e46f168adabcbc8b Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Wed, 11 Nov 2026 14:33:16 -0500 Subject: [PATCH 4/5] sonar: stop counting the locale table as duplicated code (#3805) --- sonar-project.properties | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sonar-project.properties b/sonar-project.properties index 7bd2234b9..95ca0669d 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,2 +1,6 @@ sonar.projectKey=storytold_gridcraft sonar.organization=storytold + +# The region table is one record per locale with the same field names and many shared values +# (month names, formats); that repetition is data, not copy-pasted logic. +sonar.cpd.exclusions=crates/core/src/region.rs From 5cf52c5fbb10d343316af3cc533c99b1d7ad1bf9 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Wed, 11 Nov 2026 14:55:53 -0500 Subject: [PATCH 5/5] chore: bump version to 0.19.1 for the Flatpak update fix (#3809) --- Cargo.lock | 36 ++++++++++++++++++------------------ Cargo.toml | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3986edf0f..92451aa83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2023,7 +2023,7 @@ dependencies = [ [[package]] name = "gridcraft" -version = "0.19.0" +version = "0.19.1" dependencies = [ "arboard", "chrono", @@ -2051,7 +2051,7 @@ dependencies = [ [[package]] name = "gridcraft-calc" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-core", "gridcraft-formula", @@ -2063,7 +2063,7 @@ dependencies = [ [[package]] name = "gridcraft-chart" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-calc", "gridcraft-core", @@ -2074,7 +2074,7 @@ dependencies = [ [[package]] name = "gridcraft-cli" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-engine", "gridcraft-mcp", @@ -2087,7 +2087,7 @@ dependencies = [ [[package]] name = "gridcraft-core" -version = "0.19.0" +version = "0.19.1" dependencies = [ "chrono", "js-sys", @@ -2098,7 +2098,7 @@ dependencies = [ [[package]] name = "gridcraft-engine" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-calc", "gridcraft-chart", @@ -2121,7 +2121,7 @@ dependencies = [ [[package]] name = "gridcraft-formula" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-core", "serde", @@ -2130,7 +2130,7 @@ dependencies = [ [[package]] name = "gridcraft-functions" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-core", "regex", @@ -2138,7 +2138,7 @@ dependencies = [ [[package]] name = "gridcraft-math" -version = "0.19.0" +version = "0.19.1" dependencies = [ "ratex-font", "ratex-layout", @@ -2148,7 +2148,7 @@ dependencies = [ [[package]] name = "gridcraft-mcp" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-engine", "log", @@ -2157,7 +2157,7 @@ dependencies = [ [[package]] name = "gridcraft-model" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-core", "gridcraft-formula", @@ -2170,18 +2170,18 @@ dependencies = [ [[package]] name = "gridcraft-numfmt" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-core", ] [[package]] name = "gridcraft-pdf" -version = "0.19.0" +version = "0.19.1" [[package]] name = "gridcraft-sandbox" -version = "0.19.0" +version = "0.19.1" dependencies = [ "landlock", "libc", @@ -2192,7 +2192,7 @@ dependencies = [ [[package]] name = "gridcraft-ui-egui" -version = "0.19.0" +version = "0.19.1" dependencies = [ "craft-ui", "craft-update", @@ -2219,7 +2219,7 @@ dependencies = [ [[package]] name = "gridcraft-web" -version = "0.19.0" +version = "0.19.1" dependencies = [ "craft-web-api", "craft-web-host", @@ -2238,7 +2238,7 @@ dependencies = [ [[package]] name = "gridcraft-xlsx" -version = "0.19.0" +version = "0.19.1" dependencies = [ "aes", "gridcraft-core", @@ -6710,7 +6710,7 @@ checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" [[package]] name = "xtask" -version = "0.19.0" +version = "0.19.1" dependencies = [ "gridcraft-engine", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index e0038ca6d..f244db53f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = ["crates/*", "apps/*", "xtask"] default-members = ["crates/*", "apps/gridcraft", "apps/gridcraft-cli", "xtask"] [workspace.package] -version = "0.19.0" +version = "0.19.1" edition = "2024" license = "MIT OR Apache-2.0" rust-version = "1.95"