Skip to content

Commit d7e2791

Browse files
committed
test: validate Micrometer opt-in compatibility
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
1 parent cadb2ba commit d7e2791

7 files changed

Lines changed: 281 additions & 0 deletions

File tree

.github/renovate-tracked-deps.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
"mise"
3737
]
3838
},
39+
".github/workflows/micrometer-compatibility.yml": {
40+
"regex": [
41+
"mise"
42+
]
43+
},
3944
".github/workflows/lint.yml": {
4045
"regex": [
4146
"mise"
@@ -125,6 +130,7 @@
125130
"hugo",
126131
"java",
127132
"lychee",
133+
"maven",
128134
"node",
129135
"npm:renovate",
130136
"protoc",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
name: Micrometer Opt-In Compatibility
3+
4+
on:
5+
pull_request:
6+
workflow_dispatch:
7+
inputs:
8+
micrometer-repository:
9+
description: Micrometer repository to test, in owner/name form
10+
required: false
11+
default: zeitlinger/micrometer
12+
micrometer-ref:
13+
description: Micrometer branch, tag, or commit to test
14+
required: false
15+
default: feat/prometheus-client-opt-in
16+
17+
permissions: {}
18+
19+
jobs:
20+
micrometer-compatibility:
21+
runs-on: ubuntu-24.04
22+
steps:
23+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
24+
with:
25+
persist-credentials: false
26+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1
27+
with:
28+
version: v2026.5.5
29+
sha256: 3aaab5c05a8a94a93b42b4f581779bbd5c44ddb251e7f3639fc671ec5c6aab8a
30+
- name: Cache local Maven repository
31+
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
32+
with:
33+
path: ~/.m2/repository
34+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
35+
restore-keys: |
36+
${{ runner.os }}-maven-
37+
- name: Run Micrometer compatibility tests
38+
run: |
39+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
40+
export MICROMETER_REPOSITORY="${{ github.event.inputs.micrometer-repository }}"
41+
export MICROMETER_REF="${{ github.event.inputs.micrometer-ref }}"
42+
fi
43+
mise run micrometer:test

.mise/lib/micrometer_compat.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env python3
2+
3+
from __future__ import annotations
4+
5+
import os
6+
import subprocess
7+
import xml.etree.ElementTree as ET
8+
from pathlib import Path
9+
from typing import Optional
10+
11+
12+
DEFAULT_MICROMETER_DIR = Path(
13+
os.environ.get("MICROMETER_DIR", "/tmp/micrometer-compat")
14+
)
15+
DEFAULT_MICROMETER_REPOSITORY = os.environ.get(
16+
"MICROMETER_REPOSITORY", "zeitlinger/micrometer"
17+
)
18+
DEFAULT_MICROMETER_REMOTE = os.environ.get("MICROMETER_REMOTE", "origin")
19+
DEFAULT_MICROMETER_REF = os.environ.get(
20+
"MICROMETER_REF", "feat/prometheus-client-opt-in"
21+
)
22+
DEFAULT_INIT_SCRIPT = Path(
23+
os.environ.get("MICROMETER_INIT_SCRIPT", "/tmp/micrometer-prom-local.init.gradle")
24+
)
25+
DEFAULT_PROM_VERSION = os.environ.get("PROM_VERSION")
26+
27+
28+
def run_cmd(cmd: list[str], cwd: Optional[Path] = None) -> None:
29+
subprocess.run(cmd, cwd=cwd, check=True)
30+
31+
32+
def micrometer_repository_url(repository: str) -> str:
33+
return f"https://github.com/{repository}.git"
34+
35+
36+
def check_clean_worktree(micrometer_dir: Path) -> None:
37+
result = subprocess.run(
38+
["git", "status", "--short"],
39+
cwd=micrometer_dir,
40+
check=True,
41+
capture_output=True,
42+
text=True,
43+
)
44+
if result.stdout.strip():
45+
raise RuntimeError(
46+
f"{micrometer_dir} has uncommitted changes; use a clean clone or set MICROMETER_DIR"
47+
)
48+
49+
50+
def get_prom_version(root_dir: Path = Path.cwd()) -> str:
51+
configured_version = DEFAULT_PROM_VERSION
52+
if configured_version:
53+
return configured_version
54+
pom = ET.parse(root_dir / "pom.xml")
55+
root = pom.getroot()
56+
version = root.findtext("./{*}version")
57+
if not version:
58+
version = root.findtext("./{*}parent/{*}version")
59+
if not version:
60+
raise RuntimeError("could not determine Prometheus version from pom.xml")
61+
return version
62+
63+
64+
def write_init_script(
65+
init_script: Path = DEFAULT_INIT_SCRIPT, prom_version: Optional[str] = None
66+
) -> None:
67+
if prom_version is None:
68+
prom_version = get_prom_version()
69+
init_script.write_text(
70+
f"""allprojects {{
71+
repositories {{
72+
mavenLocal()
73+
mavenCentral()
74+
gradlePluginPortal()
75+
}}
76+
configurations.configureEach {{
77+
resolutionStrategy.eachDependency {{ details ->
78+
if (details.requested.group == 'io.prometheus') {{
79+
details.useVersion('{prom_version}')
80+
details.because(
81+
'Use local prom_client_java artifacts for downstream compatibility testing'
82+
)
83+
}}
84+
}}
85+
}}
86+
}}
87+
""",
88+
encoding="utf-8",
89+
)
90+
91+
92+
def prepare_repo(
93+
micrometer_dir: Path = DEFAULT_MICROMETER_DIR,
94+
repository: str = DEFAULT_MICROMETER_REPOSITORY,
95+
remote: str = DEFAULT_MICROMETER_REMOTE,
96+
ref: str = DEFAULT_MICROMETER_REF,
97+
) -> None:
98+
repository_url = micrometer_repository_url(repository)
99+
if (micrometer_dir / ".git").is_dir():
100+
check_clean_worktree(micrometer_dir)
101+
run_cmd(
102+
["git", "remote", "set-url", remote, repository_url], cwd=micrometer_dir
103+
)
104+
run_cmd(["git", "fetch", remote, ref], cwd=micrometer_dir)
105+
else:
106+
run_cmd(
107+
[
108+
"git",
109+
"clone",
110+
repository_url,
111+
str(micrometer_dir),
112+
]
113+
)
114+
run_cmd(["git", "fetch", remote, ref], cwd=micrometer_dir)
115+
run_cmd(
116+
["git", "checkout", "-B", "codex-micrometer-compat", "FETCH_HEAD"],
117+
cwd=micrometer_dir,
118+
)
119+
120+
121+
def install_local_artifacts(root_dir: Path = Path.cwd()) -> None:
122+
run_cmd(
123+
[
124+
"./mvnw",
125+
"install",
126+
"-DskipTests",
127+
"-Dcoverage.skip=true",
128+
"-Dcheckstyle.skip=true",
129+
"-Dwarnings=-nowarn",
130+
],
131+
cwd=root_dir,
132+
)
133+
134+
135+
def run_gradle_test(
136+
test_selector: Optional[str] = None,
137+
micrometer_dir: Path = DEFAULT_MICROMETER_DIR,
138+
init_script: Path = DEFAULT_INIT_SCRIPT,
139+
) -> None:
140+
cmd = [
141+
"./gradlew",
142+
"--no-daemon",
143+
"-I",
144+
str(init_script),
145+
":micrometer-registry-prometheus:test",
146+
]
147+
if test_selector:
148+
cmd.extend(["--tests", test_selector])
149+
run_cmd(cmd, cwd=micrometer_dir)

.mise/tasks/micrometer/prepare.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env python3
2+
3+
# [MISE] description="Install local artifacts and check out a target Micrometer ref"
4+
# [MISE] alias="micrometer:prepare"
5+
6+
import sys
7+
8+
9+
sys.path.insert(0, ".mise/lib")
10+
11+
12+
def main() -> int:
13+
from micrometer_compat import (
14+
install_local_artifacts,
15+
prepare_repo,
16+
write_init_script,
17+
)
18+
19+
install_local_artifacts()
20+
prepare_repo()
21+
write_init_script()
22+
return 0
23+
24+
25+
if __name__ == "__main__":
26+
raise SystemExit(main())
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
3+
# [MISE] description="Run Micrometer PrometheusMeterRegistryTest against a target Micrometer ref"
4+
# [MISE] alias="micrometer:test-class"
5+
6+
import sys
7+
8+
9+
sys.path.insert(0, ".mise/lib")
10+
11+
12+
def main() -> int:
13+
from micrometer_compat import (
14+
install_local_artifacts,
15+
prepare_repo,
16+
run_gradle_test,
17+
write_init_script,
18+
)
19+
20+
install_local_artifacts()
21+
prepare_repo()
22+
write_init_script()
23+
run_gradle_test("io.micrometer.prometheusmetrics.PrometheusMeterRegistryTest")
24+
return 0
25+
26+
27+
if __name__ == "__main__":
28+
raise SystemExit(main())

.mise/tasks/micrometer/test.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
3+
# [MISE] description="Run Micrometer Prometheus registry tests against a target Micrometer ref"
4+
# [MISE] alias="micrometer:test"
5+
6+
import sys
7+
8+
9+
sys.path.insert(0, ".mise/lib")
10+
11+
12+
def main() -> int:
13+
from micrometer_compat import (
14+
install_local_artifacts,
15+
prepare_repo,
16+
run_gradle_test,
17+
write_init_script,
18+
)
19+
20+
install_local_artifacts()
21+
prepare_repo()
22+
write_init_script()
23+
run_gradle_test()
24+
return 0
25+
26+
27+
if __name__ == "__main__":
28+
raise SystemExit(main())

mise.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"go:github.com/grafana/oats" = "0.6.1"
33
hugo = "0.161.1"
44
java = "temurin-25.0.3+9.0.LTS"
5+
maven = "3.9.15"
56
node = "24.15.0"
67
protoc = "34.1"
78

0 commit comments

Comments
 (0)