Browse / github.com/storytold/craft-libs / patch
Prepare v0.1.0 with release notes, versioning policy and pinned adoption
Prepare v0.1.0 with release notes, versioning policy and pinned adoption Consumers starting projects need a named dependency baseline they can keep while main evolves. Prepare the coordinated v0.1.0 Git release for craft-atomic, craft-settings, craft-quit, craft-print and craft-ui, with release notes, tag/commit pinning examples, lockfile guidance and an explicit 0.x compatibility policy. Add a workspace release gate on Linux, macOS and Windows (default/all-feature Clippy and tests), a Linux Rust 1.95 library check and UI/settings WASM checks. Windows queue tests are mandatory on the runner. The policy documents platform limits, immutable tags, deliberate upgrades
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- skylartaylor (imported from pull request #41, open)
- Base
f03ec27ab2c405969428512178f746183cd55ca0- Size
- +252 −2 in 4 files
- Review
- pending
- Shared
- 2026-10-28
- Id
86d05c43a9f6225ee287eee9
How it went
No other operator has reported using it yet.
Diff
raw · .github/workflows/workspace.yml CHANGELOG.md README.md docs/versioning.md
new file mode 100644@@ -0,0 +1,75 @@+name: Workspace++on:+ push:+ branches: [main]+ tags: ["v*"]+ pull_request:+ workflow_dispatch:++permissions:+ contents: read++jobs:+ native:+ name: Workspace (${{ matrix.os }})+ timeout-minutes: 30+ strategy:+ fail-fast: false+ matrix:+ os: [ubuntu-latest, windows-latest, macos-latest]+ runs-on: ${{ matrix.os }}+ steps:+ - uses: actions/checkout@v4+ - name: Install software Vulkan renderer+ if: runner.os == 'Linux'+ run: |+ sudo apt-get update+ sudo apt-get install -y mesa-vulkan-drivers libvulkan1+ echo 'WGPU_BACKEND=vulkan' >> "$GITHUB_ENV"+ - uses: dtolnay/rust-toolchain@stable+ with:+ components: rustfmt, clippy+ - uses: Swatinem/rust-cache@v2+ with:+ key: workspace+ - name: Prepare the Windows test driver+ if: runner.os == 'Windows'+ shell: powershell+ run: |+ $ErrorActionPreference = 'Stop'+ Start-Service Spooler+ Add-PrinterDriver -Name 'Generic / Text Only'+ - run: cargo fmt --check+ - run: cargo clippy --workspace --all-targets --locked -- -D warnings+ - run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings+ - run: cargo test --workspace --locked+ env:+ CRAFT_PRINT_REQUIRE_QUEUE: ${{ runner.os == 'Windows' && '1' || '0' }}+ - run: cargo test --workspace --all-features --locked+ env:+ CRAFT_PRINT_REQUIRE_QUEUE: ${{ runner.os == 'Windows' && '1' || '0' }}+ msrv:+ name: Rust 1.95 (Linux libraries)+ runs-on: ubuntu-latest+ timeout-minutes: 15+ steps:+ - uses: actions/checkout@v4+ - uses: dtolnay/rust-toolchain@1.95.0+ - uses: Swatinem/rust-cache@v2+ with:+ key: workspace-msrv+ - run: cargo check --workspace --lib --all-features --locked+ wasm:+ name: UI and settings WASM+ runs-on: ubuntu-latest+ timeout-minutes: 15+ steps:+ - uses: actions/checkout@v4+ - uses: dtolnay/rust-toolchain@stable+ with:+ targets: wasm32-unknown-unknown+ - uses: Swatinem/rust-cache@v2+ with:+ key: workspace-wasm+ - run: cargo check -p craft-ui -p craft-settings --all-features --locked --target wasm32-unknown-unknownnew file mode 100644@@ -0,0 +1,65 @@+# Changelog++All crates share the workspace version. See [the versioning policy](docs/versioning.md).++## v0.1.0 — 2026-10-12++First coordinated Git release of craft-libs. Applications can pin a named baseline instead of+following development commits. This is an initial 0.x release: compatibility is maintained+within `0.1.x`; changes requiring consumer migration use a new minor version.++### Included crates++- **craft-atomic:** same-directory staged file replacement, exclusive creation, streaming+ writes, transient rename retries and fault-injection support, extracted from PhotoCraft.+- **craft-settings:** app-owned TOML settings with platform/portable paths, atomic saves,+ backups, damaged-file recovery, schema migrations and preservation of unknown fields.+- **craft-quit:** native macOS termination, optional egui close handling and an optional+ application menu. Save decisions and prompts stay with the app.+- **craft-print:** CUPS and native Windows PDF submission, printer discovery, copies, duplex,+ colour and scaling options. Includes bounded PDF sheet handling and the pinned Windows+ completion fix. PDF generation stays with the app.+- **craft-ui:** egui icon buttons, tabs, splits, resize handles, toolbar overflow, transactional+ docking, theme helpers and print-settings controls. Commands, content, localization and+ application state stay with the consumer. Docking serialization is opt-in through `serde`.++### Requirements and adoption++- Rust **1.95+**, edition 2024. Public UI integrations use **egui 0.36**.+- Use `git = "https://github.com/storytold/craft-libs", tag = "v0.1.0"` for each required crate;+ use the same tag everywhere. The [README](README.md#use-a-released-version) has a complete+ manifest example and a commit-pin alternative. Commit application lockfiles.+- No automatic migration from an arbitrary earlier Git revision is implied. Compare the API+ you used with this release and test affected workflows before changing pins.+- For `craft-quit`, run the close hook last in `eframe::App::logic`, after the app's unsaved-work+ decision. Finish asynchronous saves before requesting close; termination does not execute+ code after `run_native`. See the crate's API documentation before adoption.+- This release is distributed through Git only. No crates.io packages are published by it.++### Platform coverage and known limits++The release gate checks the workspace on Linux, macOS and Windows with default and all features,+plus Linux minimum-compiler and UI/settings WASM checks. UI tests include offscreen visual+regressions. Windows print tests exercise a temporary paused spooler queue; those checks do+not establish physical printer fidelity or every application's native GUI behavior.++- `craft-ui` supports native and WASM use. Font coverage, bidirectional text and screen-reader+ behavior still depend on the application and upstream stack; see [#17](https://github.com/storytold/craft-libs/issues/17).+- `craft-settings` persistence is native-only. WASM exposes settings traits, document helpers+ and error types. Concurrent writers are best-effort, last-writer-wins; strict coordination+ needs an application-owned lock.+- `craft-atomic` does not preserve all filesystem metadata during replacement. Directory sync+ is best effort; tests do not prove physical power-loss durability. See its README's contract.+- `craft-quit`'s native behavior is macOS-specific; other platforms keep their normal close+ path. Earlier hardware testing of the close hook is recorded in+ [#3](https://github.com/storytold/craft-libs/issues/3); it does not qualify every consuming app.+- `craft-print` requires CUPS command-line tools on Linux/macOS or the native Windows spooler.+ Browser submission is unsupported. Windows accepts a bounded subset of print-ready PDFs;+ unsupported inputs and driver paper/scaling mismatches return errors. Printing is synchronous,+ so call it from a worker. Physical output needs hardware testing.+- Windows printing retains a pinned Git dependency on the maintained `winprint` fork. Its+ build dependencies require the license/advisory policy exceptions documented in+ [craft-print's README](crates/print/README.md). Registry publication is deferred.++Planned crates and open feature PRs are not part of this release. Existing commit pins remain+valid, and consumers do not need to update simply because `main` changes.@@ -15,12 +15,41 @@ A Cargo workspace (edition 2024, resolver 3). Each library is a crate under `cra (`license.workspace = true`, and so on) and `[lints] workspace = true`. Register each crate in `[workspace.dependencies]` in the root `Cargo.toml`. -Apps depend on a crate by git:+## Use a released version++The first coordinated release is **[v0.1.0](https://github.com/storytold/craft-libs/releases/tag/v0.1.0)**.+It gives consumers a fixed baseline while development continues on `main`. All five crates+share this version. They require Rust 1.95 or later; the UI integrations use egui 0.36.++Add only the crates you need, using the same tag for every craft-libs dependency: ```toml-craft-<name> = { git = "https://github.com/storytold/craft-libs", rev = "<commit>" }+[dependencies]+craft-ui = { git = "https://github.com/storytold/craft-libs", tag = "v0.1.0" }+craft-settings = { git = "https://github.com/storytold/craft-libs", tag = "v0.1.0" }+# Optional, for egui close handling and the macOS application menu:+craft-quit = { git = "https://github.com/storytold/craft-libs", tag = "v0.1.0", features = ["menu"] } ``` +`craft-atomic` and `craft-print` use the same dependency syntax. Enable `craft-ui`'s+`serde` feature if you need to serialize its docking layout. These are Git releases;+crates.io publication is deferred.++Release tags are never moved or reused. For a commit pin, resolve the tag with+`git ls-remote https://github.com/storytold/craft-libs 'refs/tags/v0.1.0^{}'` and replace+`tag = "v0.1.0"` with `rev = "<full commit SHA>"` on every craft-libs dependency.+Use either `tag` or `rev`, not both. An existing commit pin keeps working; switching to this+release may require adapting to changes since that commit.++Commit your application's `Cargo.lock` and build with `cargo build --locked` for reproducible+Rust dependency resolution. A Git pin fixes craft-libs source, not every transitive dependency.+A library's own lockfile does not constrain its downstream consumers. Upgrade deliberately:+read the release notes, update all craft-libs pins together, refresh the lockfile with+`cargo check`, and run your application's tests and affected workflows before committing.++See the [release notes](CHANGELOG.md) for included functionality and known limits, and the+[versioning policy](docs/versioning.md) for compatibility guarantees and release checks.+ ## Libraries - [`craft-atomic`](crates/atomic/README.md): Crash-safe atomic file writing and replacement with same-directory staging, directory fsync, Apple `F_FULLFSYNC` fallback, transient lock backoff, and fault injection for the Craft suite.new file mode 100644@@ -0,0 +1,81 @@+# Versioning and releases++craft-libs releases give applications a fixed dependency baseline. Consumers decide when to+upgrade; development on `main` is not a reason to refresh a working application's pins.++## One workspace, one release++All crates inherit `workspace.package.version` and ship together under an annotated `vX.Y.Z`+Git tag. A release contains the crates listed in that tag's README, not proposed crates in+open pull requests. A crate can keep the same implementation across several workspace releases.+Use the same tag or commit for every craft-libs dependency in a consumer's dependency graph;+mixing Git sources can create duplicate crate instances and incompatible Rust types.++Tags identify reviewed commits and are never moved, deleted or reused to fix a release.+Corrections get a new version. The release notes and policy are stored with the source so a+consumer can read the contract that applied to its version. GitHub Releases carry the same notes.+Publishing to crates.io will be a separate step; these tags do not imply registry availability.++## Compatibility while versions are 0.x++The initial release is `0.1.0`. APIs are still developing, but compatibility within a minor+release line is intentional:++- **Patch (`0.1.0` → `0.1.1`):** compatible fixes, documentation and additive APIs that preserve+ existing callers. Keep public signatures, feature defaults, supported targets, minimum Rust+ version and documented behavior compatible. Check that additions do not break exhaustive+ matches, struct literals, trait implementations or other existing source patterns.+- **Minor (`0.1.x` → `0.2.0`):** changes requiring consumer action. This includes removing or+ changing public APIs, incompatible persisted representations, feature/default changes,+ dropping a supported target, raising the minimum Rust version, or upgrading a dependency+ such as egui when its exposed types become incompatible. Explain the before/after and migration.+- **`1.0.0`:** a separate decision that the public contracts are ready for long-term stability.+ After that, breaking changes require a major release; compatible additions use minor releases.++Documented invalid input can be rejected more strictly in a patch to fix a defect or security+issue. Call out any observable change. Do not use “0.x” or “bug fix” to silently break a valid,+documented workflow. App-owned settings schemas and migration policy remain the app's+responsibility; library releases do not automatically migrate consumer data.++For public egui APIs in `0.1.x`, keep the egui 0.36 compatibility line. The minimum Rust version+is 1.95. Compatible transitive updates still need validation and release-note coverage when+observable. Cargo's version-range rules do not select newer Git tags: changing a release pin+is always an explicit manifest edit.++## Support and scope++The newest minor line receives routine fixes. Important fixes to older lines are considered+case by case; there is no promise of maintaining every 0.x line or an LTS schedule. Existing+tags remain available so consumers can upgrade on their own schedule. Release notes identify+known limitations; a tag is not a claim that every driver, OS version or consuming app was tested.++Platform boundaries are crate-specific. See each crate's API/README and the release notes.+In particular, native printing needs the OS spooler, settings persistence is native-only, and+browser UI compatibility does not imply native services work in a browser. Consumers must test+their own save/close flows, accessibility, rendering and printing where they use those services.++## Preparing a release++1. Choose a reviewed commit on `main`. Inspect open defects, changes since the previous tag,+ crate metadata and any changed platform/dependency contracts. Update the shared version+ and lockfile when needed; the first release already uses `0.1.0`.+2. Add a dated `CHANGELOG.md` entry with the included crates, changes, compatibility requirements,+ migration steps and known limits. Update the README's recommended pin. Keep fixes and+ unrelated pending features out of the release preparation unless they block the baseline.+3. Run formatting, workspace Clippy with warnings denied, and workspace tests, both default+ and all features. The `Workspace` workflow runs these on Linux, macOS and Windows, requires+ Windows spooler regression tests, checks the minimum compiler on Linux, and checks the+ documented UI/settings WASM surface. All release jobs must pass for the candidate source.+ Repository-local build commands must also follow the host's storage/allocation rules.+4. Review consumer impact and existing platform evidence. Exercise affected native workflows+ when behavior changes; unit tests and cross-compilation cannot establish GUI or physical+ printer acceptance. Record limitations instead of extending the support claim beyond evidence.+5. Merge the preparation PR and verify the checks for the actual release commit. Create an+ annotated tag on that exact commit (`git tag -a vX.Y.Z FULL_SHA -m "craft-libs vX.Y.Z"`),+ push only that tag, and create a GitHub Release using that version's changelog entry.+ Tag-triggered CI should also pass. Do not publish crates as part of this Git-only release.+6. Verify that the remote tag resolves to the intended commit, the release notes are visible,+ and a small external consumer resolves and checks with the documented pin. Preserve the+ source identity, check results and release URL. Never repair a published tag by moving it.++The workflow validates source; it does not automatically tag or publish on every push.