Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions .config/service-branch-merge.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
{
"merge-flow-configurations": {
// regular branch flow
"release/dev17.12": {
"MergeToBranch": "release/dev17.13",
"ExtraSwitches": "-QuietComments"
},
"release/dev17.13": {
"MergeToBranch": "release/dev17.14",
"ExtraSwitches": "-QuietComments"
},
"release/dev17.14": {
"MergeToBranch": "release/dev18.0",
"ExtraSwitches": "-QuietComments"
},
"release/dev18.0": {
"release/10.0.4xx": {
"MergeToBranch": "main",
"ExtraSwitches": "-QuietComments",
"ResetToTargetPaths": [
Expand All @@ -26,6 +13,18 @@
"azure-pipelines.yml",
"azure-pipelines-PR.yml"
]
},
"main": {
"MergeToBranch": "feature/net12-scouting",
"ExtraSwitches": "-QuietComments",
"ResetToTargetPaths": [
"global.json",
"eng/Version.Details.xml",
"eng/Version.Details.props",
"eng/Versions.props",
"eng/common/**",
"eng/TargetFrameworks.props"
]
}
}
}
26 changes: 26 additions & 0 deletions .github/agents/release-notes-to-narrated-slides.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: Release notes to narrated slides
description: Turn a URL to written release notes into a short slide deck plus the script a presenter speaks over it. Inputs - release-notes URL, talk length in minutes.
---

# Release notes to narrated slides

Wrapper around [OnurGumus/codebase-video at commit 9deddc3](https://github.com/OnurGumus/codebase-video/tree/9deddc3f7b3a414650966850201b5da703367740). Download exactly that commit, not a branch head. Read its `SKILL.md` and engine notes, and use its setup, rendering and checks. Replace Claude-specific calls with your own. Do not copy it here.
It narrates with a synthetic voice. Here the presenter speaks, so you produce slides and a script, not audio.
To find release content, the [F# release announcement agent](fsharp-release-announcement.md) can run first.

**Inputs:** release-notes URL, minutes. Ask once with the ask tool: presenter name and team, audience, deep-dive topics, topics to skip, a one-line motivation, highlights of the previous release, and a design template (a style description, images or a URL). Never infer a team from a handle. Without answers, state your defaults.

**Output:** step-through slides (self-contained HTML plus PDF; no .pptx) and a script holding only the words to say, as speaker notes and a separate file. Show a rendered draft before the presenter records.

## Rules for release notes

- **Length:** about 30 s per slide, 1.8 spoken words per second, within the limit. Say the estimate is unverified until the presenter records.
- **Slide 1:** thanks; name and team only if known. One line on the preceding preview or RC of the same product with "go read those notes"; verify it, keep the presenter's claim, flag mismatches in the report. End with the agenda in one sentence.
- **Story:** lead with the benefit. One beat per slide, headline claim or number in the title, a one-sentence bridge at the end of each note. Depth on the presenter's topics; everything else on one "also" slide. Housekeeping goes in a footnote.
- **Evidence:** follow linked articles, tables and charts that back a slide. Show tables complete, including unchanged rows. Compile and run every code sample you show on the SDK the notes name, else mark it unverified. Show real compiler errors. Never retype numbers or code.
- **Narration:** say what the team did, then the range, never cherry-picked points. Caveats go on the slide, not in speech. Say preview, prototype, or not production once per topic. Separate what ships from copy-from-repo prototypes. Never promise speed; say "experiment and measure".
- **Voice:** natural first person, motivation before mechanism, the presenter's framing in plain terms. Do not invent technical claims.
- **Template:** follow its rules on type size and colour. It may be confidential: keep derived art, fonts and colours out of the repository.
- **Check:** render and look at every slide. Reject overflow, off-slide content, and text under the template's minimum (24 px at 1920 px wide if none).
- **Finish with a report:** recap verified, samples run (N/N), slides visually checked, claims you could not verify.
2 changes: 2 additions & 0 deletions docs/release-notes/.FSharp.Core/11.0.200.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

### Fixed

* Quotation debug text from `Expr.ToString()`, `Expr.ToString(full)`, and `%A` now prints struct tuple construction as `NewStructTuple`; reference tuples remain `NewTuple`. ([Issue #20800](https://github.com/dotnet/fsharp/issues/20800), [PR #20814](https://github.com/dotnet/fsharp/pull/20814))

### Changed
3 changes: 3 additions & 0 deletions eng/TargetFrameworks.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<!-- Derive major version by stripping 'net' prefix and '.0' suffix (e.g., net10.0 -> 10) -->
<FSharpNetCoreProductMajorVersion>$([System.Text.RegularExpressions.Regex]::Replace('$(FSharpNetCoreProductTargetFramework)', '^net(\d+)\.0$', '$1'))</FSharpNetCoreProductMajorVersion>

<!-- Early .NET 12 alpha SDKs set NETCoreAppMaximumVersion=11.0 before the SDK's own TFM bump lands. -->
<NETCoreAppMaximumVersion Condition="'$(FSharpNetCoreProductMajorVersion)' == '12'">12.0</NETCoreAppMaximumVersion>

<!-- Net TFM shipped in the FSharp.Core NuGet package. Lags the in-dev product TFM; bump deliberately. -->
<FSharpCoreShippedNetTargetFramework Condition="'$(FSharpCoreShippedNetTargetFramework)' == ''">net10.0</FSharpCoreShippedNetTargetFramework>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion eng/Version.Details.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props
<Project>
<PropertyGroup>
<!-- dotnet-arcade dependencies -->
<MicrosoftDotNetArcadeSdkPackageVersion>12.0.0-beta.26505.2</MicrosoftDotNetArcadeSdkPackageVersion>
<MicrosoftDotNetArcadeSdkPackageVersion>12.0.0-beta.26509.4</MicrosoftDotNetArcadeSdkPackageVersion>
<!-- dotnet-dotnet dependencies -->
<SystemCollectionsImmutablePackageVersion>10.0.14</SystemCollectionsImmutablePackageVersion>
<SystemCompositionPackageVersion>10.0.14</SystemCompositionPackageVersion>
Expand Down
4 changes: 2 additions & 2 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@
</Dependency>
</ProductDependencies>
<ToolsetDependencies>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="12.0.0-beta.26505.2">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="12.0.0-beta.26509.4">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>5a63d054ea793bdbdb6aa9f4558558e3a8f41529</Sha>
<Sha>7dad90156e9d69e991ad499ece9cf805cabcf506</Sha>
</Dependency>
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.26502.1">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
Expand Down
4 changes: 0 additions & 4 deletions eng/common/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,6 @@ try {
if (-not $PSBoundParameters.ContainsKey('nodeReuse')) {
$nodeReuse = $false
}
# MSBuild's multi-threaded mode isn't run on CI unless it was explicitly requested via -msbuildMultiThreaded.
if (-not $PSBoundParameters.ContainsKey('msbuildMultiThreaded')) {
$msbuildMultiThreaded = $false
}
}

if (-not [string]::IsNullOrEmpty($binaryLogName)) {
Expand Down
9 changes: 6 additions & 3 deletions eng/common/core-templates/steps/astred-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ steps:
FeedUrl: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet-internal-FoSSE/nuget/v3/index.json'

- pwsh: |
$ErrorActionPreference = 'Continue'
$ErrorActionPreference = 'Stop'
$apjOut = Join-Path $env:ASTRED_CAPTURE_PATH 'apj'
New-Item -ItemType Directory -Force -Path $apjOut | Out-Null

Expand All @@ -34,10 +34,13 @@ steps:

$project = Join-Path $apjOut '.astred.project.json'
$binlogPaths = @($binlogs.FullName)
$responseFile = Join-Path $apjOut 'binlogs.rsp'
$binlogPaths | ForEach-Object { '"{0}"' -f $_ } |
Set-Content -LiteralPath $responseFile -Encoding utf8
Write-Host "astproj: processing $($binlogPaths.Count) binlog(s)"
astred astproj -nofolders @binlogPaths "-o:$project"
astred astproj -nofolders "@$responseFile" "-o:$project"
if ($LASTEXITCODE -ne 0) {
Write-Host "##vso[task.logissue type=warning]astproj failed (exit $LASTEXITCODE)"
throw "astproj failed (exit $LASTEXITCODE)"
}
displayName: Generate Astred Project Files
workingDirectory: ${{ parameters.sourcesPath }}
Expand Down
5 changes: 0 additions & 5 deletions eng/common/msbuild.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ try {
$nodeReuse = $false
}

# MSBuild's multi-threaded mode isn't run on CI unless it was explicitly requested via -msbuildMultiThreaded.
if ($ci -and -not $PSBoundParameters.ContainsKey('msbuildMultiThreaded')) {
$msbuildMultiThreaded = $false
}

MSBuild @extraArgs
}
catch {
Expand Down
10 changes: 6 additions & 4 deletions eng/common/tools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
# Set to true to reuse msbuild nodes. Recommended to not reuse on CI.
[bool]$nodeReuse = if (Test-Path variable:nodeReuse) { $nodeReuse } else { !$ci }

# Set to true to build with MSBuild's multi-threaded mode (-mt). Enabled by default for local builds and not run on CI.
[bool]$msbuildMultiThreaded = if (Test-Path variable:msbuildMultiThreaded) { $msbuildMultiThreaded } else { !$ci }
# Set to true to build with MSBuild's multi-threaded mode (-mt). Enabled by default for both local and CI builds.
# Not applied when building with msbuild.exe (VS MSBuild).
[bool]$msbuildMultiThreaded = if (Test-Path variable:msbuildMultiThreaded) { $msbuildMultiThreaded } else { $true }

# Configures warning treatment in msbuild.
[bool]$warnAsError = if (Test-Path variable:warnAsError) { $warnAsError } else { $true }
Expand Down Expand Up @@ -812,8 +813,9 @@ function MSBuild() {

$cmdArgs = "$($buildTool.Command) /m /nologo /clp:Summary /v:$verbosity /nr:$nodeReuse /p:ContinuousIntegrationBuild=$ci"

# Build with MSBuild's multi-threaded mode.
if ($msbuildMultiThreaded) {
# Build with MSBuild's multi-threaded mode, but not with msbuild.exe (VS MSBuild) for now.
# TODO: Enable for VS MSBuild as well: https://github.com/dotnet/dotnet/issues/9989
if ($msbuildMultiThreaded -and [System.IO.Path]::GetFileName($buildTool.Path) -ne 'msbuild.exe') {
$cmdArgs += ' -mt'
}

Expand Down
8 changes: 2 additions & 6 deletions eng/common/tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,9 @@ else
node_reuse=${node_reuse:-true}
fi

# Set to true to build with MSBuild's multi-threaded mode (-mt). Enabled by default for local builds and not run on CI.
# Set to true to build with MSBuild's multi-threaded mode (-mt). Enabled by default for both local and CI builds.
msbuild_multi_threaded=$(NormalizeBoolArg "${msbuild_multi_threaded:-}")
if [[ "$ci" == true ]]; then
msbuild_multi_threaded=${msbuild_multi_threaded:-false}
else
msbuild_multi_threaded=${msbuild_multi_threaded:-true}
fi
msbuild_multi_threaded=${msbuild_multi_threaded:-true}

# Configures warning treatment in msbuild.
warn_as_error=$(NormalizeBoolArg "${warn_as_error:-}")
Expand Down
6 changes: 3 additions & 3 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "11.0.100-rc.1.26420.103",
"version": "12.0.100-alpha.1.26480.102",
"allowPrerelease": true,
"rollForward": "latestMinor",
"paths": [
Expand All @@ -13,7 +13,7 @@
"runner": "Microsoft.Testing.Platform"
},
"tools": {
"dotnet": "11.0.100-rc.1.26420.103",
"dotnet": "12.0.100-alpha.1.26480.102",
"vs": {
"version": "18.0",
"components": [
Expand All @@ -23,7 +23,7 @@
"xcopy-msbuild": "18.0.0"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "12.0.0-beta.26505.2",
"Microsoft.DotNet.Arcade.Sdk": "12.0.0-beta.26509.4",
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2"
}
}
8 changes: 7 additions & 1 deletion src/FSharp.Core/quotations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,13 @@ and [<CompiledName("FSharpExpr"); StructuredFormatDisplay("{DebugText}")>] Expr(
| CombTerm(NewRecordOp ty, args) -> combL "NewRecord" (typeL ty :: exprs args)
| CombTerm(NewUnionCaseOp unionCase, args) -> combL "NewUnionCase" (ucaseL unionCase :: exprs args)
| CombTerm(UnionCaseTestOp unionCase, args) -> combL "UnionCaseTest" (exprs args @ [ ucaseL unionCase ])
| CombTerm(NewTupleOp _, args) -> combL "NewTuple" (exprs args)
| CombTerm(NewTupleOp ty, args) ->
combL
(if ty.IsValueType then
"NewStructTuple"
else
"NewTuple")
(exprs args)
| CombTerm(TupleGetOp(_, i), [ arg ]) -> combL "TupleGet" ([ expr arg ] @ [ objL i ])
| CombTerm(ValueOp(v, _, Some nm), []) -> combL "ValueWithName" [ objL v; wordL (tagLocal nm) ]
| CombTerm(ValueOp(v, _, None), []) -> combL "Value" [ objL v ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ $(POUND_R)

<PropertyGroup>
<TargetFramework>$(TARGETFRAMEWORK)</TargetFramework>
<NETCoreAppMaximumVersion Condition="'$(TargetFramework)' == 'net12.0'">12.0</NETCoreAppMaximumVersion>
<RuntimeIdentifier>$(RUNTIMEIDENTIFIER)</RuntimeIdentifier>
<IsPackable>false</IsPackable>
<DisableFSharpCorePreviewCheck>true</DisableFSharpCorePreviewCheck> <!-- Disable preview FSharp.Core current DotNet Sdks -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net11.0</TargetFramework>
<TargetFramework>$(FSharpNetCoreProductTargetFramework)</TargetFramework>
<OutputType>Exe</OutputType>
<UseAppHost>false</UseAppHost>
<Deterministic>true</Deterministic>
Expand Down
25 changes: 15 additions & 10 deletions tests/EndToEndBuildTests/MultithreadedTasks/run.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,17 @@ let succeed label arguments =

let _, sdk = succeed "sdk" [ "--version" ]
let _, msbuild = succeed "msbuild" [ "msbuild"; "-version"; "-nologo" ]
let tfm =
let props = File.ReadAllText(Path.Combine(repo, "eng", "TargetFrameworks.props"))
let matched = Regex.Match(props, @"<FSharpNetCoreProductTargetFramework[^>]*>(net\d+\.\d+)</FSharpNetCoreProductTargetFramework>")
if not matched.Success then failwith "Could not determine FSharpNetCoreProductTargetFramework from eng/TargetFrameworks.props"
matched.Groups[1].Value
let sdkPath = Path.Combine(repo, ".dotnet", "sdk", sdk.Trim())
let product = Path.Combine(repo, "artifacts", "bin", "fsc", configuration, "net11.0")
let product = Path.Combine(repo, "artifacts", "bin", "fsc", configuration, tfm)
let taskProduct = Path.Combine(repo, "artifacts", "bin", "FSharp.Build", configuration, "netstandard2.0")
let taskAssembly = Path.Combine(taskProduct, "FSharp.Build.dll")
let compiler = Path.Combine(product, "fsc.dll")
let localFsi = Path.Combine(repo, "artifacts", "bin", "fsi", configuration, "net11.0", "fsi.dll")
let localFsi = Path.Combine(repo, "artifacts", "bin", "fsi", configuration, tfm, "fsi.dll")
for path in [ taskAssembly; compiler; localFsi ] do
if not (File.Exists path) then failwithf "Build local product bits first: missing %s" path
let taskHash = hash taskAssembly
Expand All @@ -67,18 +72,18 @@ write (Path.Combine(root, "versions.txt")) $"SDK {sdk}MSBuild {msbuild}Tasks {ta

// An ordinary SDK helper project uses only assemblies supplied by the running SDK, without NuGet packages.
let helper = Path.Combine(root, "probe")
write (Path.Combine(root, "Directory.Build.props")) "<Project><PropertyGroup><ImportDirectoryPackagesProps>false</ImportDirectoryPackagesProps></PropertyGroup></Project>"
write (Path.Combine(root, "Directory.Build.props")) $"""<Project><Import Project="{xml repo}/eng/TargetFrameworks.props" /><PropertyGroup><ImportDirectoryPackagesProps>false</ImportDirectoryPackagesProps></PropertyGroup></Project>"""
write (Path.Combine(root, "Directory.Build.targets")) "<Project />"
write (Path.Combine(helper, "Probe.cs")) (File.ReadAllText(Path.Combine(__SOURCE_DIRECTORY__, "Probe.cs")))
write (Path.Combine(helper, "Probe.csproj")) $"""<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup><TargetFramework>net11.0</TargetFramework><EnableDefaultCompileItems>false</EnableDefaultCompileItems></PropertyGroup>
<PropertyGroup><TargetFramework>{tfm}</TargetFramework><EnableDefaultCompileItems>false</EnableDefaultCompileItems></PropertyGroup>
<ItemGroup><Compile Include="Probe.cs" />
<Reference Include="Microsoft.Build.Framework"><HintPath>{xml sdkPath}/Microsoft.Build.Framework.dll</HintPath><Private>false</Private></Reference>
<Reference Include="Microsoft.Build.Utilities.Core"><HintPath>{xml sdkPath}/Microsoft.Build.Utilities.Core.dll</HintPath><Private>false</Private></Reference>
</ItemGroup>
</Project>"""
succeed "probe-build" [ "build"; Path.Combine(helper, "Probe.csproj"); "-nologo"; "-v:minimal"; "-nr:false" ] |> ignore
let probeAssembly = Path.Combine(helper, "bin", "Debug", "net11.0", "Probe.dll")
let probeAssembly = Path.Combine(helper, "bin", "Debug", tfm, "Probe.dll")
let graph = Path.Combine(root, "graph")
let projects = [| for index in 1 .. projectCount -> sprintf "P%02d" index |]
write (Path.Combine(graph, "Directory.Build.props")) $"""<Project>
Expand Down Expand Up @@ -192,10 +197,10 @@ let validateOutputs label =
for file in [ "fsi.txt"; "obj/substituted/template.txt" ] do
if File.ReadAllText(Path.Combine(directory, file)) <> name then failwithf "%s: wrong %s" name file
for file, marker in [ "Strings.fs", "RESX_" + name; "ILLink.Substitutions.xml", $"fullname=\"{name}\"" ] do
if not (File.ReadAllText(Path.Combine(directory, "obj/Release/net11.0", file)).Contains marker) then
if not (File.ReadAllText(Path.Combine(directory, $"obj/Release/{tfm}", file)).Contains marker) then
failwithf "%s: generated %s has the wrong marker" name file
succeed (label + "-" + name) [ Path.Combine(directory, "bin", "Release", "net11.0", name + ".dll") ] |> ignore
for child in [ "bin/Release/net11.0"; "obj/Release/net11.0" ] do
succeed (label + "-" + name) [ Path.Combine(directory, "bin", "Release", tfm, name + ".dll") ] |> ignore
for child in [ $"bin/Release/{tfm}"; $"obj/Release/{tfm}" ] do
for file in Directory.GetFiles(Path.Combine(directory, child), "*", SearchOption.AllDirectories) do
if [ ".dll"; ".pdb"; ".fs"; ".resx"; ".resources"; ".xml" ] |> List.contains (Path.GetExtension file) then
yield Path.GetRelativePath(graph, file), hash file ] |> Map.ofList
Expand Down Expand Up @@ -248,7 +253,7 @@ for mt in [ false; true ] do
if failure = "resource" && errors.Length <> 1 then
failwithf "%s reported %d errors for one malformed resource" label errors.Length
for name in projects |> Array.skip 1 do
let dll = Path.Combine(graph, name, "bin/Release/net11.0", name + ".dll")
let dll = Path.Combine(graph, name, $"bin/Release/{tfm}", name + ".dll")
succeed (label + "-" + name) [ dll ] |> ignore
if hash dll <> baseline[Path.GetRelativePath(graph, dll)] then failwithf "%s contaminated %s" label name
printfn "%s: expected failure; %d unaffected executables match baseline" label (projectCount - 1)
Expand All @@ -263,7 +268,7 @@ let resourceNames file =
[ for handle in metadata.ManifestResources -> metadata.GetString(metadata.GetManifestResource(handle).Name) ]
let trimProject = Path.Combine(graph, projects[1])
let metadata names = names |> List.filter (fun (name: string) -> name.StartsWith("FSharpSignature") || name.StartsWith("FSharpOptimization")) |> Set.ofList
let untrimmed = Path.Combine(trimProject, "bin/Release/net11.0", projects[1] + ".dll")
let untrimmed = Path.Combine(trimProject, $"bin/Release/{tfm}", projects[1] + ".dll")
let originalMetadata = metadata (resourceNames untrimmed)
if originalMetadata.IsEmpty then failwith "Trimming control has no F# metadata"
let trimFailures = ResizeArray<string>()
Expand Down
1 change: 1 addition & 0 deletions tests/FSharp.Build.UnitTests/ResourceTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ let private createSdkProjectDirectory () =
<PropertyGroup>
<ImportDirectoryPackagesProps>false</ImportDirectoryPackagesProps>
<TargetFramework>{productTfm}</TargetFramework>
<NETCoreAppMaximumVersion Condition="'$(TargetFramework)' == 'net12.0'">12.0</NETCoreAppMaximumVersion>
<FSharpTargetsShim>{buildDirectory ++ "Microsoft.FSharp.NetSdk.targets"}</FSharpTargetsShim>
<FSharpBuildAssemblyFile>{initialConfig.FSharpBuild}</FSharpBuildAssemblyFile>
<DotnetFscCompilerPath>"{initialConfig.DOTNETFSCCOMPILERPATH}"</DotnetFscCompilerPath>
Expand Down
Loading
Loading