Skip to content

Commit 89b340d

Browse files
authored
Merge branch 'main' into repo-assist/fix-issue-1251-http-response-default-utf8-rebase-9c637d7c2e08fb9f
2 parents 1ad16ea + 59a17a6 commit 89b340d

8 files changed

Lines changed: 140 additions & 91 deletions

File tree

.github/aw/actions-lock.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010
"version": "v8",
1111
"sha": "ed597411d8f924073f98dfc5c65a23a2325f34cd"
1212
},
13-
"github/gh-aw-actions/setup@v0.64.3": {
13+
"github/gh-aw-actions/setup@v0.65.4": {
1414
"repo": "github/gh-aw-actions/setup",
15-
"version": "v0.64.3",
16-
"sha": "84dc9c12e0d955a200911a3a07c3f5dd96a175d7"
15+
"version": "v0.65.4",
16+
"sha": "934698b44320d87a7a9196339f90293f10bd2247"
1717
},
18-
"github/gh-aw/actions/setup@v0.64.3": {
18+
"github/gh-aw/actions/setup@v0.65.4": {
1919
"repo": "github/gh-aw/actions/setup",
20-
"version": "v0.64.3",
21-
"sha": "7a91ad396dfe21b7c462b59b6aecd4680815c419"
20+
"version": "v0.65.4",
21+
"sha": "b5a9fb08751b738a86b3b605ff1fdf34956adbf4"
2222
}
2323
}
2424
}

.github/workflows/repo-assist.lock.yml

Lines changed: 70 additions & 74 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/repo-assist.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ tools:
5757

5858
safe-outputs:
5959
messages:
60-
footer: "> Generated by 🌈 Repo Assist at [{run-started}]({run_url}). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md)."
61-
run-started: "Repo Assist is processing {event_type}, started at at [{run-started}]({run_url})..."
62-
run-success: "Repo Assist completed successfully at {run-ended}."
63-
run-failure: "Repo Assist encountered {status} at {run-ended}."
60+
footer: "> Generated by 🌈 {workflow_name}, see [workflow run]({run_url}). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md)."
61+
run-started: "{workflow_name} is processing {event_type}, see [workflow run]({run_url})..."
62+
run-success: "{workflow_name} completed successfully, see [workflow run]({run_url})."
63+
run-failure: "{workflow_name} encountered {status}, see [workflow run]({run_url})."
6464
add-comment:
6565
max: 10
6666
target: "*"
@@ -185,7 +185,7 @@ steps:
185185
json.dump(result, f, indent=2)
186186
EOF
187187
188-
source: githubnext/agentics/workflows/repo-assist.md@1f672aef974f4246124860fc532f82fe8a93a57e
188+
source: githubnext/agentics/workflows/repo-assist.md@e1ecf341a90b7bc2021e77c58685d7e269e20b99
189189
---
190190

191191
# Repo Assist

RELEASE_NOTES.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# Release Notes
22

3-
## 8.1.4 - Apr 01 2026
3+
## 9.0.0 - Apr 01 2026
44

55
- Change HTTP response default encoding from ISO-8859-1 to UTF-8 to match `System.Net.Http.HttpClient` behaviour (closes #1251)
66

7+
## 8.1.4 - Mar 30 2026
8+
9+
- Performance: `JsonValue.Parse` now copies unescaped string runs in bulk instead of appending character-by-character, reducing `StringBuilder.Append` calls for strings with few or no escape sequences
10+
711
## 8.1.3 - Mar 23 2026
812

913
- Fix JSON `/* ... */` comment parser: `*` or `/` characters inside the comment body no longer cause premature termination and parse failure

build/build.fs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,32 @@ let buildscript () =
123123

124124
"FSharp.Data.sln" |> DotNet.test setParams)
125125

126+
// --------------------------------------------------------------------------------------
127+
// Run tests with code coverage (uses Coverlet collector already present in test projects)
128+
129+
Target.create "Coverage" (fun _ ->
130+
let setParams (o: DotNet.TestOptions) =
131+
{ o with
132+
Configuration = DotNet.BuildConfiguration.Release
133+
Collect = Some "XPlat Code Coverage"
134+
ResultsDirectory = Some "coverage-results"
135+
MSBuildParams =
136+
{ o.MSBuildParams with
137+
DisableInternalBinLog = true }
138+
Logger = if isCI then Some "GitHubActions" else None }
139+
140+
"FSharp.Data.sln" |> DotNet.test setParams
141+
142+
Trace.log ""
143+
Trace.log "Coverage results written to ./coverage-results/"
144+
Trace.log "To generate an HTML report, install dotnet-reportgenerator-globaltool:"
145+
Trace.log " dotnet tool install -g dotnet-reportgenerator-globaltool"
146+
147+
Trace.log
148+
" reportgenerator -reports:coverage-results/**/coverage.cobertura.xml -targetdir:coverage-report -reporttypes:Html"
149+
150+
Trace.log "")
151+
126152
// --------------------------------------------------------------------------------------
127153
// Build packages
128154

@@ -179,6 +205,7 @@ let buildscript () =
179205
printfn " Targets for building:"
180206
printfn " * Build"
181207
printfn " * RunTests"
208+
printfn " * Coverage (run tests with Coverlet code coverage; results in ./coverage-results/)"
182209
printfn " * GenerateDocs"
183210
printfn " * Pack (creates package only, doesn't publish)"
184211
printfn " * All (calls previous 5)"
@@ -247,6 +274,7 @@ let buildscript () =
247274
"Build" ==> "Pack" ==> "All"
248275
"Build" ==> "All"
249276
"Build" ==> "RunTests" ==> "All"
277+
"Build" ==> "Coverage"
250278
"Build" ==> "RunBenchmarks"
251279

252280
[<EntryPoint>]

src/FSharp.Data.DesignTime/Json/JsonConversionsGenerator.fs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,19 @@ let internal convertJsonValue
100100
(<@ (%varExpr).Path() @>, convert <@ Some (%varExpr).JsonValue @>, <@ Some (%varExpr).JsonValue @>))
101101
| TypeWrapper.Option, true -> convert <@ (%%value: JsonValue option) @>
102102
| TypeWrapper.Option, false ->
103-
//TODO: not covered in tests
103+
// Reached when canPassAllConversionCallingTypes=false (e.g. for array element types or
104+
// heterogeneous type variants). The caller passes an IJsonDocument; we extract its
105+
// JsonValue and wrap it in Some before handing it to the conversion quotation.
104106
convert <@ Some (%%value: IJsonDocument).JsonValue @>
105107
| TypeWrapper.Nullable, true ->
106-
//TODO: not covered in tests
108+
// TypeWrapper.Nullable is never produced by JSON inference (which only emits None or Option).
109+
// This branch exists for structural completeness and potential future extensibility.
107110
typeof<TextRuntime>?(nameof (TextRuntime.OptionToNullable))
108111
(field.RuntimeType)
109112
(convert <@ (%%value: JsonValue option) @>)
110113
| TypeWrapper.Nullable, false ->
111-
//TODO: not covered in tests
114+
// TypeWrapper.Nullable is never produced by JSON inference (which only emits None or Option).
115+
// This branch exists for structural completeness and potential future extensibility.
112116
typeof<TextRuntime>?(nameof (TextRuntime.OptionToNullable))
113117
(field.RuntimeType)
114118
(convert <@ Some (%%value: IJsonDocument).JsonValue @>)

src/FSharp.Data.DesignTime/Json/JsonGenerator.fs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,12 @@ module JsonTypeBuilder =
632632

633633
match propResult.OptionalConverter with
634634
| Some _ ->
635-
//TODO: not covered in tests
635+
// Reached when a property is optional (IsOptional=true) but its
636+
// ConversionCallingType is JsonDocument (optionalityHandledByProperty=false),
637+
// meaning the property type has a converter but optionality is not handled
638+
// by the conversion calling type alone. In practice this requires an
639+
// InferedType.Json(optional=true) property, which the JSON provider does
640+
// not currently produce.
636641
ctx.JsonRuntimeType?(nameof (JsonRuntime.ConvertOptionalProperty))
637642
(propResult.ConvertedTypeErased ctx)
638643
(jDoc, propName, propResult.ConverterFunc ctx)

src/FSharp.Data.Json.Core/JsonValue.fs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,18 @@ type private JsonParser(jsonText: string) =
315315
ensure (i < s.Length && s.[i] = '"')
316316
i <- i + 1
317317

318+
// Track start of current unescaped run; flush as a bulk chunk when an escape or end is hit.
319+
// This avoids per-character StringBuilder.Append calls for strings with few/no escapes,
320+
// which is the common case in real-world JSON.
321+
let mutable chunkStart = i
322+
323+
let inline flushChunk upTo =
324+
if upTo > chunkStart then
325+
buf.Append(s, chunkStart, upTo - chunkStart) |> ignore
326+
318327
while i < s.Length && s.[i] <> '"' do
319328
if s.[i] = '\\' then
329+
flushChunk i
320330
ensure (i + 1 < s.Length)
321331

322332
match s.[i + 1] with
@@ -371,10 +381,12 @@ type private JsonParser(jsonText: string) =
371381
| _ -> throw ()
372382

373383
i <- i + 2 // skip past \ and next char
384+
chunkStart <- i
374385
else
375-
buf.Append(s.[i]) |> ignore
376386
i <- i + 1
377387

388+
// Flush any remaining unescaped characters
389+
flushChunk i
378390
ensure (i < s.Length && s.[i] = '"')
379391
i <- i + 1
380392
let str = buf.ToString()

0 commit comments

Comments
 (0)