Skip to content

Commit f9e1f45

Browse files
authored
Merge pull request #89 from RAprogramm/codex/release-and-publish-masterror-with-derive-re-export
Release masterror 0.10.5 with derive re-export
2 parents d5495a4 + 016de9f commit f9e1f45

File tree

7 files changed

+82
-66
lines changed

7 files changed

+82
-66
lines changed

.github/workflows/release.yml

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ jobs:
1717
steps:
1818
- uses: actions/checkout@v4
1919

20-
# Install a minimal Rust toolchain so that `cargo metadata` is available.
2120
- name: Install Rust (stable, minimal)
2221
uses: dtolnay/rust-toolchain@v1
2322
with:
@@ -50,7 +49,6 @@ jobs:
5049
echo "rust-version is not set for crate: ${CRATE_NAME}"
5150
exit 1
5251
fi
53-
# Normalize X.Y to X.Y.0
5452
if [[ "$RV" =~ ^[0-9]+\.[0-9]+$ ]]; then
5553
RV="${RV}.0"
5654
fi
@@ -84,8 +82,49 @@ jobs:
8482
with:
8583
toolchain: ${{ steps.msrv.outputs.msrv }}
8684

87-
- name: Publish to crates.io
85+
- name: Maybe publish masterror-derive
8886
env:
8987
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
90-
run: cargo +${{ steps.msrv.outputs.msrv }} publish --locked --token "$CARGO_REGISTRY_TOKEN"
88+
shell: bash
89+
run: |
90+
set -euo pipefail
91+
if cargo metadata --no-deps --format-version=1 \
92+
| jq -e '.packages[] | select(.name=="masterror-derive" and .source==null)' >/dev/null; then
93+
echo "Publishing masterror-derive..."
94+
n=0
95+
until [ $n -ge 5 ]
96+
do
97+
if cargo +${{ steps.msrv.outputs.msrv }} publish -p masterror-derive --locked --token "$CARGO_REGISTRY_TOKEN"; then
98+
echo "masterror-derive published."
99+
break
100+
fi
101+
n=$((n+1))
102+
echo "Retry $n/5 for masterror-derive..."
103+
sleep $((5*n))
104+
done
105+
else
106+
echo "No local masterror-derive found; skipping."
107+
fi
108+
109+
- name: Wait for crates.io index sync
110+
run: sleep 15
91111

112+
- name: Publish masterror
113+
env:
114+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
115+
shell: bash
116+
run: |
117+
set -euo pipefail
118+
n=0
119+
until [ $n -ge 5 ]
120+
do
121+
if cargo +${{ steps.msrv.outputs.msrv }} publish -p masterror --locked --token "$CARGO_REGISTRY_TOKEN"; then
122+
echo "masterror published."
123+
exit 0
124+
fi
125+
n=$((n+1))
126+
echo "Retry $n/5 for masterror..."
127+
sleep $((10*n))
128+
done
129+
echo "Failed to publish masterror after retries."
130+
exit 1

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file.
33

44
## [Unreleased]
55

6+
## [0.10.5] - 2025-09-20
7+
8+
### Added
9+
- Re-exported `masterror-derive` macros from `masterror` so consumers only depend on a single crate while deriving application errors.
10+
11+
### Changed
12+
- Published `masterror-derive` as a standalone crate (`0.6.1`) and configured the release workflow to publish it before `masterror` with retries and tag/MSRV validation.
13+
614
### Documentation
715
- Described `#[provide]` telemetry providers and `#[app_error]` conversions with
816
end-to-end examples in the derive guide ([README](README.md#structured-telemetry-providers-and-apperror-mappings),

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "masterror"
3-
version = "0.10.4"
3+
version = "0.10.5"
44
rust-version = "1.90"
55
edition = "2024"
66
license = "MIT OR Apache-2.0"
@@ -71,11 +71,11 @@ turnkey = []
7171
openapi = ["dep:utoipa"]
7272

7373
[workspace.dependencies]
74-
masterror-derive = { version = "0.6.0" }
74+
masterror-derive = { version = "0.6.1" }
7575
masterror-template = { version = "0.3.1" }
7676

7777
[dependencies]
78-
masterror-derive = { workspace = true }
78+
masterror-derive = { version = "0.6" }
7979
masterror-template = { workspace = true }
8080
tracing = "0.1"
8181

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ Stable categories, conservative HTTP mapping, no `unsafe`.
2929

3030
~~~toml
3131
[dependencies]
32-
masterror = { version = "0.10.4", default-features = false }
32+
masterror = { version = "0.10.5", default-features = false }
3333
# or with features:
34-
# masterror = { version = "0.10.4", features = [
34+
# masterror = { version = "0.10.5", features = [
3535
# "axum", "actix", "openapi", "serde_json",
3636
# "sqlx", "sqlx-migrate", "reqwest", "redis",
3737
# "validator", "config", "tokio", "multipart",
@@ -66,10 +66,10 @@ masterror = { version = "0.10.4", default-features = false }
6666
~~~toml
6767
[dependencies]
6868
# lean core
69-
masterror = { version = "0.10.4", default-features = false }
69+
masterror = { version = "0.10.5", default-features = false }
7070

7171
# with Axum/Actix + JSON + integrations
72-
# masterror = { version = "0.10.4", features = [
72+
# masterror = { version = "0.10.5", features = [
7373
# "axum", "actix", "openapi", "serde_json",
7474
# "sqlx", "sqlx-migrate", "reqwest", "redis",
7575
# "validator", "config", "tokio", "multipart",
@@ -623,13 +623,13 @@ assert_eq!(resp.status, 401);
623623
Minimal core:
624624

625625
~~~toml
626-
masterror = { version = "0.10.4", default-features = false }
626+
masterror = { version = "0.10.5", default-features = false }
627627
~~~
628628

629629
API (Axum + JSON + deps):
630630

631631
~~~toml
632-
masterror = { version = "0.10.4", features = [
632+
masterror = { version = "0.10.5", features = [
633633
"axum", "serde_json", "openapi",
634634
"sqlx", "reqwest", "redis", "validator", "config", "tokio"
635635
] }
@@ -638,7 +638,7 @@ masterror = { version = "0.10.4", features = [
638638
API (Actix + JSON + deps):
639639

640640
~~~toml
641-
masterror = { version = "0.10.4", features = [
641+
masterror = { version = "0.10.5", features = [
642642
"actix", "serde_json", "openapi",
643643
"sqlx", "reqwest", "redis", "validator", "config", "tokio"
644644
] }
@@ -709,4 +709,3 @@ MSRV = 1.90 (may raise in minor, never in patch).
709709
Apache-2.0 OR MIT, at your option.
710710

711711
</details>
712-

masterror-derive/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
[package]
22
name = "masterror-derive"
33
rust-version = "1.90"
4-
version = "0.6.0"
4+
version = "0.6.1"
55
edition = "2024"
66
license = "MIT OR Apache-2.0"
77
repository = "https://github.com/RAprogramm/masterror"
88
readme = "README.md"
99
description = "Derive macros for masterror"
10-
publish = false
1110

1211
[lib]
1312
proc-macro = true

src/lib.rs

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -206,60 +206,31 @@ pub mod prelude;
206206
pub use app_error::{AppError, AppResult};
207207
pub use code::AppCode;
208208
pub use kind::AppErrorKind;
209-
/// Native derive macro for error enums and structs.
209+
/// Re-export derive macros so users only depend on [`masterror`].
210210
///
211-
/// Supports `#[from]` conversions, transparent wrappers, and precise
212-
/// diagnostics for `#[error("...")]` templates with field-aware validation.
211+
/// # Examples
213212
///
214213
/// ```
215-
/// use std::error::Error as StdError;
216-
///
217-
/// use masterror::Error;
214+
/// use masterror::{AppCode, AppError, AppErrorKind, Error};
218215
///
219216
/// #[derive(Debug, Error)]
220-
/// #[error("{code}: {message}")]
221-
/// struct MiniError {
222-
/// code: u16,
223-
/// message: &'static str
217+
/// #[error("missing flag: {name}")]
218+
/// #[app_error(kind = AppErrorKind::BadRequest, code = AppCode::BadRequest, message)]
219+
/// struct MissingFlag {
220+
/// name: &'static str
224221
/// }
225222
///
226-
/// #[derive(Debug, Error)]
227-
/// #[error("wrapper -> {0}")]
228-
/// struct MiniWrapper(
229-
/// #[from]
230-
/// #[source]
231-
/// MiniError
232-
/// );
233-
///
234-
/// #[derive(Debug, Error)]
235-
/// #[error(transparent)]
236-
/// struct MiniTransparent(#[from] MiniError);
237-
///
238-
/// let wrapped = MiniWrapper::from(MiniError {
239-
/// code: 500,
240-
/// message: "boom"
241-
/// });
242-
/// assert_eq!(wrapped.to_string(), "wrapper -> 500: boom");
243-
/// assert_eq!(
244-
/// StdError::source(&wrapped).map(|err| err.to_string()),
245-
/// Some(String::from("500: boom"))
246-
/// );
247-
///
248-
/// let expected_source = StdError::source(&MiniError {
249-
/// code: 503,
250-
/// message: "oops"
251-
/// })
252-
/// .map(|err| err.to_string());
223+
/// let app: AppError = MissingFlag {
224+
/// name: "feature"
225+
/// }
226+
/// .into();
227+
/// assert!(matches!(app.kind, AppErrorKind::BadRequest));
253228
///
254-
/// let transparent = MiniTransparent::from(MiniError {
255-
/// code: 503,
256-
/// message: "oops"
257-
/// });
258-
/// assert_eq!(transparent.to_string(), "503: oops");
259-
/// assert_eq!(
260-
/// StdError::source(&transparent).map(|err| err.to_string()),
261-
/// expected_source
262-
/// );
229+
/// let code: AppCode = MissingFlag {
230+
/// name: "other"
231+
/// }
232+
/// .into();
233+
/// assert!(matches!(code, AppCode::BadRequest));
263234
/// ```
264-
pub use masterror_derive::Error;
235+
pub use masterror_derive::*;
265236
pub use response::{ErrorResponse, RetryAdvice};

0 commit comments

Comments
 (0)