diff --git a/src/Invex.StructuredText.GithubActions/GithubActionWriter.cs b/src/Invex.StructuredText.GithubActions/GithubActionWriter.cs
index a45c059..37fbae7 100644
--- a/src/Invex.StructuredText.GithubActions/GithubActionWriter.cs
+++ b/src/Invex.StructuredText.GithubActions/GithubActionWriter.cs
@@ -811,7 +811,7 @@ private IDisposable WriteSection(string key, string value) =>
private void WriteProperty(string key, string value)
{
- var lines = value.Split('\r', '\n', StringSplitOptions.RemoveEmptyEntries);
+ var lines = value.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
switch (lines.Length)
{
diff --git a/tests/Invex.StructuredText.GithubActions.Tests/GithubActionWriterPropertyTests.cs b/tests/Invex.StructuredText.GithubActions.Tests/GithubActionWriterPropertyTests.cs
new file mode 100644
index 0000000..c4b1a97
--- /dev/null
+++ b/tests/Invex.StructuredText.GithubActions.Tests/GithubActionWriterPropertyTests.cs
@@ -0,0 +1,75 @@
+namespace Invex.StructuredText.GithubActions.Tests;
+
+///
+/// Tests for how scalar properties are written, in particular multiline values that must be
+/// emitted as YAML block scalars. These exercise the WriteProperty(string, string) path
+/// via a job's env values.
+///
+[TestFixture]
+internal sealed class GithubActionWriterPropertyTests
+{
+ private static string WriteEnvValue(string value)
+ {
+ var job = GithubActionWriterHelper.MinimalJob() with
+ {
+ Env = new Dictionary
+ {
+ ["MY_VAR"] = new RawExpression(value),
+ },
+ };
+
+ return GithubActionWriterHelper.Write(GithubActionWriterHelper.MinimalAction() with
+ {
+ Jobs = [job],
+ });
+ }
+
+ [Test]
+ public void WriteProperty_ValueWithLineFeedNewlines_WritesBlockScalar()
+ {
+ var output = WriteEnvValue("line1\nline2");
+
+ output.ShouldContain("MY_VAR: |");
+ output.ShouldContain("line1");
+ output.ShouldContain("line2");
+ }
+
+ [Test]
+ public void WriteProperty_ValueWithCarriageReturnNewlines_WritesBlockScalar()
+ {
+ var output = WriteEnvValue("line1\rline2");
+
+ output.ShouldContain("MY_VAR: |");
+ output.ShouldContain("line1");
+ output.ShouldContain("line2");
+ }
+
+ [Test]
+ public void WriteProperty_ValueWithCarriageReturnLineFeedNewlines_WritesBlockScalar()
+ {
+ var output = WriteEnvValue("line1\r\nline2");
+
+ output.ShouldContain("MY_VAR: |");
+ output.ShouldContain("line1");
+ output.ShouldContain("line2");
+ }
+
+ [Test]
+ public void WriteProperty_ValueWithLineFeedNewlines_DoesNotWriteValueInline()
+ {
+ var output = WriteEnvValue("line1\nline2");
+
+ // The buggy behaviour would emit "MY_VAR: line1\nline2" inline rather than a block scalar.
+ output.ShouldNotContain("MY_VAR: line1");
+ }
+
+ [Test]
+ public void WriteProperty_SingleLineValue_WritesInline()
+ {
+ var output = WriteEnvValue("hello");
+
+ output.ShouldContain("MY_VAR: hello");
+ output.ShouldNotContain("MY_VAR: |");
+ }
+}
+