From de4cf351d9ce083c3666c7ffc0f1f900eacfa441 Mon Sep 17 00:00:00 2001
From: Tristan Partin <tristan@partin.io>
Date: Wed, 17 Jun 2026 19:20:47 +0000
Subject: [PATCH v1 4/7] Use a context manager to write grouped CI output

With a context manager, we can take responsibility from the caller to
write proper GitHub Action output syntax, and instead let the caller
focus on logging relevant output.

Signed-off-by: Tristan Partin <tristan@partin.io>
---
 src/tools/ci/gha_ccache_decide.py | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/tools/ci/gha_ccache_decide.py b/src/tools/ci/gha_ccache_decide.py
index 4b322b8087..58b1d14c96 100644
--- a/src/tools/ci/gha_ccache_decide.py
+++ b/src/tools/ci/gha_ccache_decide.py
@@ -3,6 +3,7 @@
 import json
 import os
 import subprocess
+from contextlib import contextmanager
 
 def run(cmd, check=True):
     return subprocess.run(
@@ -18,6 +19,14 @@ def append_github_output(key, value):
     with open(output_path, "a", encoding="utf-8") as f:
         f.write(f"{key}={value}\n")
 
+@contextmanager
+def group(name):
+    print(f"::group::{name}")
+    try:
+        yield
+    finally:
+        print("::endgroup::")
+
 def main():
     on_default_branch = os.environ["ON_DEFAULT_BRANCH"] == "true"
 
@@ -29,9 +38,8 @@ def main():
 
     # Log ccache stats, useful for more in-depth understanding. To avoid
     # swamping the output, collapse it in a group.
-    print("::group::ccache_stats")
-    print(run(["ccache", "--show-stats", "-vv"]))
-    print("::endgroup::")
+    with group("ccache_stats"):
+        print(run(["ccache", "--show-stats", "-vv"]))
 
     # compute cache hit ratio
     ccache_stats = json.loads(run(["ccache", "--print-stats", "--format", "json"]))
@@ -65,15 +73,14 @@ def main():
     # branch differs a lot). Therefore evict ccache entries that are a
     # bit older. The cutoff here is fairly arbitrary, it could
     # probably be improved.
-    print("::group::ccache_shrink")
-    print(run(["ccache", "--evict-older-than", f"{45*60}s"]))
-    print(run(["ccache", "--recompress", "10"]))
+    with group("ccache_shrink"):
+        print(run(["ccache", "--evict-older-than", f"{45*60}s"]))
+        print(run(["ccache", "--recompress", "10"]))
 
-    # Don't store ccache stats, otherwise we'd need to reset the cache access
-    # data after restoring the cache in the next run, to be able to get the
-    # hit ratio of the CI run.
-    print(run(["ccache", "--zero-stats"]))
-    print("::endgroup::")
+        # Don't store ccache stats, otherwise we'd need to reset the cache
+        # access data after restoring the cache in the next run, to be able to
+        # get the hit ratio of the CI run.
+        print(run(["ccache", "--zero-stats"]))
 
     # Before continuing, try to kill all ccache instances, otherwise
     # it's possible that on cancellations there is still running
-- 
Tristan Partin
https://tristan.partin.io

