upd-cli 0.0.24__tar.gz → 0.0.25__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. {upd_cli-0.0.24 → upd_cli-0.0.25}/CHANGELOG.md +7 -0
  2. {upd_cli-0.0.24 → upd_cli-0.0.25}/Cargo.lock +1 -1
  3. {upd_cli-0.0.24 → upd_cli-0.0.25}/Cargo.toml +1 -1
  4. upd_cli-0.0.25/Makefile +57 -0
  5. {upd_cli-0.0.24 → upd_cli-0.0.25}/PKG-INFO +4 -6
  6. {upd_cli-0.0.24 → upd_cli-0.0.25}/README.md +3 -5
  7. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/pypi.rs +147 -23
  8. upd_cli-0.0.25/vership.toml +2 -0
  9. upd_cli-0.0.24/Makefile +0 -127
  10. {upd_cli-0.0.24 → upd_cli-0.0.25}/.mise.toml +0 -0
  11. {upd_cli-0.0.24 → upd_cli-0.0.25}/.pre-commit-config.yaml +0 -0
  12. {upd_cli-0.0.24 → upd_cli-0.0.25}/.pre-commit-hooks.yaml +0 -0
  13. {upd_cli-0.0.24 → upd_cli-0.0.25}/.rumdl.toml +0 -0
  14. {upd_cli-0.0.24 → upd_cli-0.0.25}/LICENSE +0 -0
  15. {upd_cli-0.0.24 → upd_cli-0.0.25}/assets/logo-wide.svg +0 -0
  16. {upd_cli-0.0.24 → upd_cli-0.0.25}/assets/logo.svg +0 -0
  17. {upd_cli-0.0.24 → upd_cli-0.0.25}/pyproject.toml +0 -0
  18. {upd_cli-0.0.24 → upd_cli-0.0.25}/python/upd_cli/__init__.py +0 -0
  19. {upd_cli-0.0.24 → upd_cli-0.0.25}/python/upd_cli/__main__.py +0 -0
  20. {upd_cli-0.0.24 → upd_cli-0.0.25}/python/upd_cli/py.typed +0 -0
  21. {upd_cli-0.0.24 → upd_cli-0.0.25}/rust-toolchain.toml +0 -0
  22. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/align.rs +0 -0
  23. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/audit.rs +0 -0
  24. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/cache.rs +0 -0
  25. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/cli.rs +0 -0
  26. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/config.rs +0 -0
  27. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/interactive.rs +0 -0
  28. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/lib.rs +0 -0
  29. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/lockfile.rs +0 -0
  30. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/main.rs +0 -0
  31. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/crates_io.rs +0 -0
  32. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/github_releases.rs +0 -0
  33. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/go_proxy.rs +0 -0
  34. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/mock.rs +0 -0
  35. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/mod.rs +0 -0
  36. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/npm.rs +0 -0
  37. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/nuget.rs +0 -0
  38. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/rubygems.rs +0 -0
  39. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/terraform.rs +0 -0
  40. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/registry/utils.rs +0 -0
  41. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/cargo_toml.rs +0 -0
  42. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/csproj.rs +0 -0
  43. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/gemfile.rs +0 -0
  44. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/github_actions.rs +0 -0
  45. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/go_mod.rs +0 -0
  46. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/mise.rs +0 -0
  47. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/mod.rs +0 -0
  48. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/package_json.rs +0 -0
  49. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/pre_commit.rs +0 -0
  50. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/pyproject.rs +0 -0
  51. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/requirements.rs +0 -0
  52. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/updater/terraform.rs +0 -0
  53. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/version/mod.rs +0 -0
  54. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/version/pep440.rs +0 -0
  55. {upd_cli-0.0.24 → upd_cli-0.0.25}/src/version/semver_util.rs +0 -0
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+
9
+ ## [0.0.25](https://github.com/rvben/upd/compare/v0.0.24...v0.0.25) - 2026-04-15
10
+
11
+ ### Fixed
12
+
13
+ - **pypi**: handle string-valued yanked field in PEP 691 JSON Simple API ([b17034b](https://github.com/rvben/upd/commit/b17034b540f6a5b62e446131c6e87f43695bbd9b))
14
+
8
15
  ## [0.0.24] - 2026-03-23
9
16
 
10
17
  ### Added
@@ -1780,7 +1780,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
1780
1780
 
1781
1781
  [[package]]
1782
1782
  name = "upd"
1783
- version = "0.0.24"
1783
+ version = "0.0.25"
1784
1784
  dependencies = [
1785
1785
  "anyhow",
1786
1786
  "async-trait",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "upd"
3
- version = "0.0.24"
3
+ version = "0.0.25"
4
4
  edition = "2024"
5
5
  rust-version = "1.91.1"
6
6
  description = "A fast dependency updater for Python, Node.js, Rust, Go, Ruby, Terraform, GitHub Actions, pre-commit, and Mise projects"
@@ -0,0 +1,57 @@
1
+ .PHONY: build release test lint fmt check clean run install release-patch release-minor release-major
2
+
3
+ # Build debug binary
4
+ build:
5
+ cargo build
6
+
7
+ # Build release binary
8
+ release:
9
+ cargo build --release
10
+
11
+ # Run all tests
12
+ test:
13
+ cargo test
14
+
15
+ # Run tests with output
16
+ test-verbose:
17
+ cargo test -- --nocapture
18
+
19
+ # Run clippy lints
20
+ lint:
21
+ cargo clippy -- -D warnings
22
+
23
+ # Format code
24
+ fmt:
25
+ cargo fmt
26
+
27
+ # Check formatting without changing files
28
+ fmt-check:
29
+ cargo fmt -- --check
30
+
31
+ # Run all checks (format, lint, test)
32
+ check: fmt-check lint test
33
+
34
+ # Clean build artifacts
35
+ clean:
36
+ cargo clean
37
+
38
+ # Run debug build
39
+ run:
40
+ cargo run
41
+
42
+ # Run with arguments
43
+ run-release:
44
+ ./target/release/upd
45
+
46
+ # Install to ~/.cargo/bin
47
+ install:
48
+ cargo install --path .
49
+
50
+ release-patch:
51
+ vership bump patch
52
+
53
+ release-minor:
54
+ vership bump minor
55
+
56
+ release-major:
57
+ vership bump major
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: upd-cli
3
- Version: 0.0.24
3
+ Version: 0.0.25
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -595,8 +595,8 @@ Add `upd` to your `.pre-commit-config.yaml`:
595
595
 
596
596
  ```yaml
597
597
  repos:
598
- - repo: https://github.com/rvben/upd
599
- rev: v0.0.24 # Use the latest version
598
+ - repo: https://github.com/rvben/upd-pre-commit
599
+ rev: v0.0.24
600
600
  hooks:
601
601
  - id: upd-check
602
602
  # Optional: only check specific ecosystems
@@ -610,9 +610,7 @@ Available hooks:
610
610
  | `upd-check` | Fail if any dependencies are outdated |
611
611
  | `upd-check-major` | Fail only on major (breaking) updates |
612
612
 
613
- Both hooks run on `pre-push` by default and trigger when dependency files change.
614
-
615
- **Note:** Requires `upd` to be installed and available in PATH.
613
+ Both hooks run on `pre-push` by default. Uses `language: python` which installs `upd-cli` from PyPI automatically — no manual installation needed.
616
614
 
617
615
  ## Development
618
616
 
@@ -572,8 +572,8 @@ Add `upd` to your `.pre-commit-config.yaml`:
572
572
 
573
573
  ```yaml
574
574
  repos:
575
- - repo: https://github.com/rvben/upd
576
- rev: v0.0.24 # Use the latest version
575
+ - repo: https://github.com/rvben/upd-pre-commit
576
+ rev: v0.0.24
577
577
  hooks:
578
578
  - id: upd-check
579
579
  # Optional: only check specific ecosystems
@@ -587,9 +587,7 @@ Available hooks:
587
587
  | `upd-check` | Fail if any dependencies are outdated |
588
588
  | `upd-check-major` | Fail only on major (breaking) updates |
589
589
 
590
- Both hooks run on `pre-push` by default and trigger when dependency files change.
591
-
592
- **Note:** Requires `upd` to be installed and available in PATH.
590
+ Both hooks run on `pre-push` by default. Uses `language: python` which installs `upd-cli` from PyPI automatically — no manual installation needed.
593
591
 
594
592
  ## Development
595
593
 
@@ -60,11 +60,50 @@ struct SimpleApiResponse {
60
60
  files: Vec<SimpleApiFile>,
61
61
  }
62
62
 
63
+ /// Deserialize the `yanked` field from PyPI's Simple API (PEP 592 / PEP 700).
64
+ /// The field can be:
65
+ /// - absent / `null` → not yanked (false)
66
+ /// - `false` → not yanked
67
+ /// - `true` → yanked (rare)
68
+ /// - a non-empty string (the yank reason) → yanked
69
+ fn deserialize_yanked_flag<'de, D>(deserializer: D) -> Result<bool, D::Error>
70
+ where
71
+ D: serde::Deserializer<'de>,
72
+ {
73
+ struct YankedVisitor;
74
+
75
+ impl<'de> serde::de::Visitor<'de> for YankedVisitor {
76
+ type Value = bool;
77
+
78
+ fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
79
+ formatter.write_str("a boolean or yank-reason string")
80
+ }
81
+
82
+ fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<bool, E> {
83
+ Ok(v)
84
+ }
85
+
86
+ fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<bool, E> {
87
+ Ok(!v.is_empty())
88
+ }
89
+
90
+ fn visit_string<E: serde::de::Error>(self, v: String) -> Result<bool, E> {
91
+ Ok(!v.is_empty())
92
+ }
93
+
94
+ fn visit_unit<E: serde::de::Error>(self) -> Result<bool, E> {
95
+ Ok(false)
96
+ }
97
+ }
98
+
99
+ deserializer.deserialize_any(YankedVisitor)
100
+ }
101
+
63
102
  #[derive(Debug, Clone, Deserialize)]
64
103
  struct SimpleApiFile {
65
104
  filename: String,
66
- #[serde(default)]
67
- yanked: Option<bool>,
105
+ #[serde(default, deserialize_with = "deserialize_yanked_flag")]
106
+ yanked: bool,
68
107
  }
69
108
 
70
109
  #[derive(Debug, Deserialize)]
@@ -457,7 +496,7 @@ impl PyPiRegistry {
457
496
 
458
497
  for file in &data.files {
459
498
  // Skip yanked packages
460
- if file.yanked.unwrap_or(false) {
499
+ if file.yanked {
461
500
  continue;
462
501
  }
463
502
 
@@ -920,19 +959,19 @@ mod tests {
920
959
  files: vec![
921
960
  SimpleApiFile {
922
961
  filename: "my_package-1.0.0.tar.gz".to_string(),
923
- yanked: Some(false),
962
+ yanked: false,
924
963
  },
925
964
  SimpleApiFile {
926
965
  filename: "my_package-1.1.0.tar.gz".to_string(),
927
- yanked: None,
966
+ yanked: false,
928
967
  },
929
968
  SimpleApiFile {
930
969
  filename: "my_package-1.2.0-py3-none-any.whl".to_string(),
931
- yanked: Some(false),
970
+ yanked: false,
932
971
  },
933
972
  SimpleApiFile {
934
973
  filename: "my_package-2.0.0a1.tar.gz".to_string(),
935
- yanked: Some(false),
974
+ yanked: false,
936
975
  },
937
976
  ],
938
977
  };
@@ -961,19 +1000,19 @@ mod tests {
961
1000
  files: vec![
962
1001
  SimpleApiFile {
963
1002
  filename: "my_package-1.0.0.tar.gz".to_string(),
964
- yanked: Some(false),
1003
+ yanked: false,
965
1004
  },
966
1005
  SimpleApiFile {
967
1006
  filename: "my_package-1.1.0.tar.gz".to_string(),
968
- yanked: Some(true), // Yanked
1007
+ yanked: true, // Yanked
969
1008
  },
970
1009
  SimpleApiFile {
971
1010
  filename: "my_package-1.2.0.tar.gz".to_string(),
972
- yanked: Some(true), // Yanked
1011
+ yanked: true, // Yanked
973
1012
  },
974
1013
  SimpleApiFile {
975
1014
  filename: "my_package-1.3.0.tar.gz".to_string(),
976
- yanked: Some(false),
1015
+ yanked: false,
977
1016
  },
978
1017
  ],
979
1018
  };
@@ -987,6 +1026,89 @@ mod tests {
987
1026
  assert_eq!(versions[1].1, "1.0.0");
988
1027
  }
989
1028
 
1029
+ #[test]
1030
+ fn test_parse_simple_api_json_response_string_yanked() {
1031
+ // PyPI can return yanked as a string (the yank reason) per PEP 592 / PEP 700.
1032
+ // Packages with string yanked values used to cause a serde deserialization
1033
+ // failure (Option<bool> vs String), which caused the entire response to be
1034
+ // discarded and fell through to the fallback registry with misleading 404 errors.
1035
+ let registry = PyPiRegistry::new();
1036
+ let json = r#"{
1037
+ "files": [
1038
+ {"filename": "my_package-1.0.0.tar.gz", "yanked": false},
1039
+ {"filename": "my_package-1.1.0.tar.gz", "yanked": "Backward compatibility bug"},
1040
+ {"filename": "my_package-1.2.0.tar.gz", "yanked": "security issue"},
1041
+ {"filename": "my_package-2.0.0.tar.gz", "yanked": false}
1042
+ ]
1043
+ }"#;
1044
+ let data: SimpleApiResponse = serde_json::from_str(json).unwrap();
1045
+ let versions = registry
1046
+ .parse_simple_api_json_response(data, "my-package", false)
1047
+ .unwrap();
1048
+ // 1.1.0 and 1.2.0 are yanked (string reason), should be skipped
1049
+ assert_eq!(versions.len(), 2);
1050
+ assert_eq!(versions[0].1, "2.0.0");
1051
+ assert_eq!(versions[1].1, "1.0.0");
1052
+ }
1053
+
1054
+ #[test]
1055
+ fn test_parse_simple_api_json_response_empty_string_yanked() {
1056
+ // yanked: "" is treated as not-yanked — an empty string carries no yank reason.
1057
+ // PyPI uses true (bool) for no-reason yanks; empty string is not a valid yank signal.
1058
+ let registry = PyPiRegistry::new();
1059
+ let json = r#"{
1060
+ "files": [
1061
+ {"filename": "my_package-1.0.0.tar.gz", "yanked": ""},
1062
+ {"filename": "my_package-2.0.0.tar.gz", "yanked": ""}
1063
+ ]
1064
+ }"#;
1065
+ let data: SimpleApiResponse = serde_json::from_str(json).unwrap();
1066
+ let versions = registry
1067
+ .parse_simple_api_json_response(data, "my-package", false)
1068
+ .unwrap();
1069
+ assert_eq!(versions.len(), 2);
1070
+ assert_eq!(versions[0].1, "2.0.0");
1071
+ assert_eq!(versions[1].1, "1.0.0");
1072
+ }
1073
+
1074
+ #[test]
1075
+ fn test_parse_simple_api_json_response_null_yanked() {
1076
+ // yanked: null must be treated as not-yanked (visit_unit)
1077
+ let registry = PyPiRegistry::new();
1078
+ let json = r#"{
1079
+ "files": [
1080
+ {"filename": "my_package-1.0.0.tar.gz", "yanked": null},
1081
+ {"filename": "my_package-2.0.0.tar.gz", "yanked": null}
1082
+ ]
1083
+ }"#;
1084
+ let data: SimpleApiResponse = serde_json::from_str(json).unwrap();
1085
+ let versions = registry
1086
+ .parse_simple_api_json_response(data, "my-package", false)
1087
+ .unwrap();
1088
+ assert_eq!(versions.len(), 2);
1089
+ assert_eq!(versions[0].1, "2.0.0");
1090
+ assert_eq!(versions[1].1, "1.0.0");
1091
+ }
1092
+
1093
+ #[test]
1094
+ fn test_parse_simple_api_json_response_absent_yanked() {
1095
+ // yanked field absent entirely must be treated as not-yanked (#[serde(default)])
1096
+ let registry = PyPiRegistry::new();
1097
+ let json = r#"{
1098
+ "files": [
1099
+ {"filename": "my_package-1.0.0.tar.gz"},
1100
+ {"filename": "my_package-2.0.0.tar.gz"}
1101
+ ]
1102
+ }"#;
1103
+ let data: SimpleApiResponse = serde_json::from_str(json).unwrap();
1104
+ let versions = registry
1105
+ .parse_simple_api_json_response(data, "my-package", false)
1106
+ .unwrap();
1107
+ assert_eq!(versions.len(), 2);
1108
+ assert_eq!(versions[0].1, "2.0.0");
1109
+ assert_eq!(versions[1].1, "1.0.0");
1110
+ }
1111
+
990
1112
  #[test]
991
1113
  fn test_base64_encode() {
992
1114
  assert_eq!(base64_encode("hello"), "aGVsbG8=");
@@ -1524,18 +1646,20 @@ mod tests {
1524
1646
  let mock_server1 = MockServer::start().await;
1525
1647
  let mock_server2 = MockServer::start().await;
1526
1648
 
1527
- // Both servers return 404
1528
- Mock::given(method("GET"))
1529
- .and(path("/testpkg/json"))
1530
- .respond_with(ResponseTemplate::new(404))
1531
- .mount(&mock_server1)
1532
- .await;
1533
-
1534
- Mock::given(method("GET"))
1535
- .and(path("/testpkg/json"))
1536
- .respond_with(ResponseTemplate::new(404))
1537
- .mount(&mock_server2)
1538
- .await;
1649
+ // Both servers: Simple API returns 404, JSON API also returns 404
1650
+ for server in [&mock_server1, &mock_server2] {
1651
+ Mock::given(method("GET"))
1652
+ .and(path("/simple/testpkg/"))
1653
+ .respond_with(ResponseTemplate::new(404))
1654
+ .mount(server)
1655
+ .await;
1656
+
1657
+ Mock::given(method("GET"))
1658
+ .and(path("/pypi/testpkg/json"))
1659
+ .respond_with(ResponseTemplate::new(404))
1660
+ .mount(server)
1661
+ .await;
1662
+ }
1539
1663
 
1540
1664
  let primary = PyPiRegistry::with_index_url(mock_server1.uri());
1541
1665
  let extras = vec![mock_server2.uri()];
@@ -0,0 +1,2 @@
1
+ [hooks]
2
+ post-push = "gh api repos/rvben/upd-pre-commit/dispatches -f event_type=pypi_release"
upd_cli-0.0.24/Makefile DELETED
@@ -1,127 +0,0 @@
1
- .PHONY: build release test lint fmt check clean run install version-get version-major version-minor version-patch version-push release-major release-minor release-patch build-wheel verify-release pre-commit-update
2
-
3
- # Get version from Cargo.toml
4
- VERSION := $(shell grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
5
-
6
- # Verify release is ready
7
- verify-release:
8
- @echo "Verifying release readiness..."
9
- @./scripts/verify-release-ready.sh
10
-
11
- # Build Python wheel locally
12
- build-wheel:
13
- @echo "Building Python wheel..."
14
- maturin build --release
15
-
16
- # Build debug binary
17
- build:
18
- cargo build
19
-
20
- # Build release binary
21
- release:
22
- cargo build --release
23
-
24
- # Run all tests
25
- test:
26
- cargo test
27
-
28
- # Run tests with output
29
- test-verbose:
30
- cargo test -- --nocapture
31
-
32
- # Run clippy lints
33
- lint:
34
- cargo clippy -- -D warnings
35
-
36
- # Format code
37
- fmt:
38
- cargo fmt
39
-
40
- # Check formatting without changing files
41
- fmt-check:
42
- cargo fmt -- --check
43
-
44
- # Run all checks (format, lint, test)
45
- check: fmt-check lint test
46
-
47
- # Clean build artifacts
48
- clean:
49
- cargo clean
50
-
51
- # Run debug build
52
- run:
53
- cargo run
54
-
55
- # Run with arguments
56
- run-release:
57
- ./target/release/upd
58
-
59
- # Install to ~/.cargo/bin
60
- install:
61
- cargo install --path .
62
-
63
- # Show current version
64
- version-get:
65
- @echo "Current version: v$(VERSION)"
66
-
67
- # Version tagging targets
68
- version-major:
69
- @echo "Creating new major version tag..."
70
- $(eval CURRENT := $(shell git describe --tags --abbrev=0 2>/dev/null || echo v0.0.0))
71
- $(eval MAJOR := $(shell echo $(CURRENT) | sed -E 's/v([0-9]+)\.[0-9]+\.[0-9]+/\1/'))
72
- $(eval NEW_MAJOR := $(shell echo $$(( $(MAJOR) + 1 ))))
73
- $(eval NEW_TAG := v$(NEW_MAJOR).0.0)
74
- @echo "Current: $(CURRENT) -> New: $(NEW_TAG)"
75
- @sed -i '' 's/^version = ".*"/version = "$(NEW_MAJOR).0.0"/' Cargo.toml
76
- @cargo check --quiet
77
- @git add Cargo.toml Cargo.lock
78
- @git commit -m "chore: bump version to $(NEW_TAG)"
79
- @git tag -a $(NEW_TAG) -m "Release $(NEW_TAG)"
80
- @echo "Version $(NEW_TAG) created. Run 'make version-push' to trigger release."
81
-
82
- version-minor:
83
- @echo "Creating new minor version tag..."
84
- $(eval CURRENT := $(shell git describe --tags --abbrev=0 2>/dev/null || echo v0.0.0))
85
- $(eval MAJOR := $(shell echo $(CURRENT) | sed -E 's/v([0-9]+)\.[0-9]+\.[0-9]+/\1/'))
86
- $(eval MINOR := $(shell echo $(CURRENT) | sed -E 's/v[0-9]+\.([0-9]+)\.[0-9]+/\1/'))
87
- $(eval NEW_MINOR := $(shell echo $$(( $(MINOR) + 1 ))))
88
- $(eval NEW_TAG := v$(MAJOR).$(NEW_MINOR).0)
89
- @echo "Current: $(CURRENT) -> New: $(NEW_TAG)"
90
- @sed -i '' 's/^version = ".*"/version = "$(MAJOR).$(NEW_MINOR).0"/' Cargo.toml
91
- @cargo check --quiet
92
- @git add Cargo.toml Cargo.lock
93
- @git commit -m "chore: bump version to $(NEW_TAG)"
94
- @git tag -a $(NEW_TAG) -m "Release $(NEW_TAG)"
95
- @echo "Version $(NEW_TAG) created. Run 'make version-push' to trigger release."
96
-
97
- version-patch:
98
- @echo "Creating new patch version tag..."
99
- $(eval CURRENT := $(shell git describe --tags --abbrev=0 2>/dev/null || echo v0.0.0))
100
- $(eval MAJOR := $(shell echo $(CURRENT) | sed -E 's/v([0-9]+)\.[0-9]+\.[0-9]+/\1/'))
101
- $(eval MINOR := $(shell echo $(CURRENT) | sed -E 's/v[0-9]+\.([0-9]+)\.[0-9]+/\1/'))
102
- $(eval PATCH := $(shell echo $(CURRENT) | sed -E 's/v[0-9]+\.[0-9]+\.([0-9]+)/\1/'))
103
- $(eval NEW_PATCH := $(shell echo $$(( $(PATCH) + 1 ))))
104
- $(eval NEW_TAG := v$(MAJOR).$(MINOR).$(NEW_PATCH))
105
- @echo "Current: $(CURRENT) -> New: $(NEW_TAG)"
106
- @sed -i '' 's/^version = ".*"/version = "$(MAJOR).$(MINOR).$(NEW_PATCH)"/' Cargo.toml
107
- @cargo check --quiet
108
- @git add Cargo.toml Cargo.lock
109
- @git commit -m "chore: bump version to $(NEW_TAG)"
110
- @git tag -a $(NEW_TAG) -m "Release $(NEW_TAG)"
111
- @echo "Version $(NEW_TAG) created. Run 'make version-push' to trigger release."
112
-
113
- version-push:
114
- $(eval LATEST_TAG := $(shell git describe --tags --abbrev=0))
115
- @echo "Pushing latest commit and tag $(LATEST_TAG) to origin..."
116
- @git push
117
- @git push origin $(LATEST_TAG)
118
- @echo "Release workflow triggered for $(LATEST_TAG)"
119
-
120
- # Combined release targets
121
- release-major: version-major version-push
122
- release-minor: version-minor version-push
123
- release-patch: version-patch version-push
124
-
125
- # Update pre-commit hooks to latest versions
126
- pre-commit-update:
127
- pre-commit autoupdate
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes