From 5006416b915ee2d0f10f6349b4762f588a899bcd Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 18:46:46 -0300 Subject: [PATCH 1/5] fix: write multiline action outputs safely Signed-off-by: Vitor Mattos --- actions/sync-workflows/sync.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/actions/sync-workflows/sync.py b/actions/sync-workflows/sync.py index e7effba..1db33a9 100644 --- a/actions/sync-workflows/sync.py +++ b/actions/sync-workflows/sync.py @@ -245,8 +245,14 @@ def render_summary(report: dict[str, object]) -> str: def write_output(name: str, value: str) -> None: output = os.environ.get("GITHUB_OUTPUT") - if output: - with Path(output).open("a", encoding="utf-8") as handle: + if not output: + return + + with Path(output).open("a", encoding="utf-8") as handle: + if "\n" in value: + delimiter = f"WORKFLOW_SYNC_{name.upper()}" + handle.write(f"{name}<<{delimiter}\n{value}{delimiter}\n") + else: handle.write(f"{name}={value}\n") From 4d299ee8b5b103f0c4391f2586620b6b3887fb46 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 18:46:49 -0300 Subject: [PATCH 2/5] test: cover multiline action outputs Signed-off-by: Vitor Mattos --- tests/test_sync_workflows_action.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_sync_workflows_action.py b/tests/test_sync_workflows_action.py index 77adf89..a9397f0 100644 --- a/tests/test_sync_workflows_action.py +++ b/tests/test_sync_workflows_action.py @@ -3,9 +3,11 @@ import hashlib import importlib.util +import os import tempfile import unittest from pathlib import Path +from unittest.mock import patch MODULE_PATH = ( Path(__file__).resolve().parents[1] @@ -194,6 +196,20 @@ def test_broken_patch_sets_draft_signal_and_keeps_catalog_lock(self) -> None: sync_module.md5(source_file), ) + def test_writes_multiline_github_output(self) -> None: + with tempfile.TemporaryDirectory() as directory: + output = Path(directory) / "output" + with patch.dict(os.environ, {"GITHUB_OUTPUT": str(output)}): + sync_module.write_output("summary", "line one\nline two\n") + + self.assertEqual( + output.read_text(encoding="utf-8"), + "summary< None: summary = sync_module.render_summary( { From 237cba7e762c434de7b3410379d342c8507ff8b2 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 18:46:56 -0300 Subject: [PATCH 3/5] fix: pin hardened workflow sync action Signed-off-by: Vitor Mattos --- workflow-templates/sync-workflow-templates.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-templates/sync-workflow-templates.yml b/workflow-templates/sync-workflow-templates.yml index d6fbc8e..a0eeda8 100644 --- a/workflow-templates/sync-workflow-templates.yml +++ b/workflow-templates/sync-workflow-templates.yml @@ -67,7 +67,7 @@ jobs: - name: Synchronize workflow templates id: sync - uses: LibreCodeCoop/github-workflows/actions/sync-workflows@57e644fe4882e942ac19bbe99729b4b7e3c9014e + uses: LibreCodeCoop/github-workflows/actions/sync-workflows@5006416b915ee2d0f10f6349b4762f588a899bcd with: source: source/workflow-templates target: target From fb3a6bc86726a275010dbb425fd34b2f49655fe1 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 18:46:59 -0300 Subject: [PATCH 4/5] fix: pin hardened workflow sync action Signed-off-by: Vitor Mattos --- patches/nextcloud/sync-workflow-templates.yml.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/nextcloud/sync-workflow-templates.yml.patch b/patches/nextcloud/sync-workflow-templates.yml.patch index c3724ad..3bb152a 100644 --- a/patches/nextcloud/sync-workflow-templates.yml.patch +++ b/patches/nextcloud/sync-workflow-templates.yml.patch @@ -113,7 +113,7 @@ - echo "DRAFT_ONLY=${draft_only}" >> $GITHUB_ENV + - name: Synchronize workflow templates + id: sync -+ uses: LibreCodeCoop/github-workflows/actions/sync-workflows@57e644fe4882e942ac19bbe99729b4b7e3c9014e ++ uses: LibreCodeCoop/github-workflows/actions/sync-workflows@5006416b915ee2d0f10f6349b4762f588a899bcd + with: + source: source/workflow-templates + target: target From 5e848a8d058d85777a79b5613647860f899744bf Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 18:48:20 -0300 Subject: [PATCH 5/5] test: cover single-line action outputs Signed-off-by: Vitor Mattos --- tests/test_sync_workflows_action.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_sync_workflows_action.py b/tests/test_sync_workflows_action.py index a9397f0..7724986 100644 --- a/tests/test_sync_workflows_action.py +++ b/tests/test_sync_workflows_action.py @@ -196,6 +196,17 @@ def test_broken_patch_sets_draft_signal_and_keeps_catalog_lock(self) -> None: sync_module.md5(source_file), ) + def test_writes_single_line_github_output(self) -> None: + with tempfile.TemporaryDirectory() as directory: + output = Path(directory) / "output" + with patch.dict(os.environ, {"GITHUB_OUTPUT": str(output)}): + sync_module.write_output("changed", "true") + + self.assertEqual( + output.read_text(encoding="utf-8"), + "changed=true\n", + ) + def test_writes_multiline_github_output(self) -> None: with tempfile.TemporaryDirectory() as directory: output = Path(directory) / "output"