diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 5fa19c28..7c57943f 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -63,7 +63,7 @@ datasourceTemplate: "github-release-attachments", packageNameTemplate: "jdx/mise", depNameTemplate: "mise", - matchStrings: ["jdx/mise-action.*\\n\\s*with:\\s*\\n\\s*version: [\"']?(?v[.\\d]+)[\"']?\\s*\\n\\s*sha256: [\"']?(?\\w+)[\"']?"], + matchStrings: ["jdx/mise-action.*\\n\\s*with:\\s*\\n\\s*version: [\"']?(?v[.\\d]+)[\"']?\\s*\\n\\s*sha256:\\s*(?:(?:[>|][-+]?)\\s*\\n\\s*)?[\"']?(?[a-f0-9]{64})[\"']?"], }, { customType: "regex", @@ -90,7 +90,7 @@ datasourceTemplate: "github-release-attachments", packageNameTemplate: "jdx/mise", depNameTemplate: "mise", - matchStrings: ["jdx/mise-action.*\\n\\s*with:\\s*\\n\\s*version: [\"']?(?v[.\\d]+)[\"']?\\s*\\n\\s*sha256: [\"']?(?\\w+)[\"']?"], + matchStrings: ["jdx/mise-action.*\\n\\s*with:\\s*\\n\\s*version: [\"']?(?v[.\\d]+)[\"']?\\s*\\n\\s*sha256:\\s*(?:(?:[>|][-+]?)\\s*\\n\\s*)?[\"']?(?[a-f0-9]{64})[\"']?"], }, ], packageRules: [ diff --git a/default.json b/default.json index 448b4523..02b31fca 100644 --- a/default.json +++ b/default.json @@ -30,7 +30,7 @@ "packageNameTemplate": "jdx/mise", "depNameTemplate": "mise", "matchStrings": [ - "jdx/mise-action.*\\n\\s*with:\\s*\\n\\s*version: [\"']?(?v[.\\d]+)[\"']?\\s*\\n\\s*sha256: [\"']?(?\\w+)[\"']?" + "jdx/mise-action.*\\n\\s*with:\\s*\\n\\s*version: [\"']?(?v[.\\d]+)[\"']?\\s*\\n\\s*sha256:\\s*(?:(?:[>|][-+]?)\\s*\\n\\s*)?[\"']?(?[a-f0-9]{64})[\"']?" ] } ], diff --git a/src/registry/tests.rs b/src/registry/tests.rs index 641408ae..b73b24a7 100644 --- a/src/registry/tests.rs +++ b/src/registry/tests.rs @@ -1,6 +1,8 @@ use std::collections::{BTreeSet, HashMap}; use std::path::Path; +use regex::Regex; + use super::*; #[path = "../readme_snippets.rs"] @@ -509,6 +511,68 @@ fn repo_renovate_config_stays_aligned_with_shared_preset_contract() { } } +#[test] +fn mise_action_custom_manager_matches_plain_and_block_scalar_sha256() { + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let default_json_path = manifest_dir.join("default.json"); + let default_json = + std::fs::read_to_string(&default_json_path).expect("default.json must be readable"); + let parsed: serde_json::Value = + serde_json::from_str(&default_json).expect("default.json must be valid JSON"); + + let description = "Update mise version in GitHub Actions workflows"; + let manager = custom_manager_by_description(&parsed, description) + .unwrap_or_else(|| panic!("default.json missing custom manager {description:?}")); + let pattern = manager["matchStrings"][0] + .as_str() + .expect("custom manager match string must be a string"); + let regex = Regex::new(pattern).expect("custom manager regex must compile"); + + for (name, sample) in [ + ( + "plain scalar", + r#" + - name: Setup mise + uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1 + with: + version: v2026.4.28 + sha256: 9655492db554e8f70a69830f54307ac0f4681d6c42f9844e862528b7853d09d1 +"#, + ), + ( + "block scalar", + r#" + - name: Setup mise + uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1 + with: + version: v2026.4.28 + sha256: >- + c55befc52e5694f388b927ef304362ca7b9e919d97d43c342fca57f2eccea255 +"#, + ), + ] { + let captures = regex + .captures(sample) + .unwrap_or_else(|| panic!("regex must match {name} mise-action YAML")); + assert_eq!( + captures.name("currentValue").map(|value| value.as_str()), + Some("v2026.4.28"), + "regex must capture the mise version for {name}" + ); + assert_eq!( + captures.name("currentDigest").map(|value| value.as_str()), + Some(match name { + "plain scalar" => + "9655492db554e8f70a69830f54307ac0f4681d6c42f9844e862528b7853d09d1", + "block scalar" => + "c55befc52e5694f388b927ef304362ca7b9e919d97d43c342fca57f2eccea255", + _ => unreachable!("unexpected sample"), + }), + "regex must capture the mise sha256 digest for {name}" + ); + } +} + #[test] fn linter_keys_include_mise_and_bare_tool_names() { let keys = linter_keys();