diff --git a/.github/workflows/fw-lite.yaml b/.github/workflows/fw-lite.yaml index 8a49a2dd42..04a2772b64 100644 --- a/.github/workflows/fw-lite.yaml +++ b/.github/workflows/fw-lite.yaml @@ -50,7 +50,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Cache NuGet packages uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -123,7 +123,7 @@ jobs: submodules: true - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Dotnet build (Release) run: dotnet build backend/FwLite/FwLiteProjectSync.Tests/FwLiteProjectSync.Tests.csproj -c Release @@ -300,7 +300,7 @@ jobs: path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Dotnet build working-directory: backend/FwLite/FwLiteWeb @@ -335,7 +335,7 @@ jobs: path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Publish Linux working-directory: backend/FwLite/FwLiteWeb @@ -383,7 +383,7 @@ jobs: path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Setup Maui run: dotnet workload install maui-android @@ -404,7 +404,7 @@ jobs: KEYSTORE_PASS: ${{ secrets.FW_LITE_KEYSTORE_PASS }} KEYSTORE_ALIAS: ${{ vars.FW_LITE_KEYSTORE_UPLOAD_KEY_ALIAS }} run: | - dotnet publish -f net10.0-android -p:BuildApple=false --artifacts-path ../artifacts \ + dotnet publish -f net11.0-android -p:BuildApple=false --artifacts-path ../artifacts \ -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} \ -p:ApplicationVersion=${{ github.run_number }} \ -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} \ @@ -421,7 +421,7 @@ jobs: working-directory: backend/FwLite/FwLiteMaui run: | echo "::warning::Signing key unavailable (likely a fork PR); building an unsigned Android APK." - dotnet publish -f net10.0-android -p:BuildApple=false --artifacts-path ../artifacts \ + dotnet publish -f net11.0-android -p:BuildApple=false --artifacts-path ../artifacts \ -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} \ -p:ApplicationVersion=${{ github.run_number }} \ -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} \ @@ -432,8 +432,8 @@ jobs: with: name: fw-lite-android if-no-files-found: error -# path looks like this: backend/FwLite/artifacts/publish/FwLiteMaui/release_net10.0-android/org.sil.fwlitemaui-signed.apk - path: backend/FwLite/artifacts/publish/FwLiteMaui/release_net10.0-android/* +# path looks like this: backend/FwLite/artifacts/publish/FwLiteMaui/release_net11.0-android/org.sil.fwlitemaui-signed.apk + path: backend/FwLite/artifacts/publish/FwLiteMaui/release_net11.0-android/* publish-win: name: Publish FW Lite app for Windows @@ -449,7 +449,7 @@ jobs: path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Cache NuGet packages uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 @@ -482,7 +482,7 @@ jobs: - name: Publish Windows MAUI portable app working-directory: backend/FwLite/FwLiteMaui run: | - dotnet publish -f net10.0-windows10.0.19041.0 -p:BuildAndroid=false --artifacts-path ../artifacts -p:WindowsPackageType=None -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} + dotnet publish -f net11.0-windows10.0.19041.0 -p:BuildAndroid=false --artifacts-path ../artifacts -p:WindowsPackageType=None -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} mkdir -p ../artifacts/sign/portable cp -r ../artifacts/publish/FwLiteMaui/* ../artifacts/sign/portable/ @@ -492,7 +492,7 @@ jobs: # AppxPackageDir is the MSIX-targets equivalent of --artifacts-path: without it # MAUI 10 writes AppPackages to $(MSBuildProjectDirectory)/AppPackages, ignoring # --artifacts-path. Redirect it under artifacts/ so everything lives in one tree. - dotnet publish -f net10.0-windows10.0.19041.0 -p:BuildAndroid=false --artifacts-path ../artifacts -p:AppxPackageDir=../artifacts/AppPackages/ -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} + dotnet publish -f net11.0-windows10.0.19041.0 -p:BuildAndroid=false --artifacts-path ../artifacts -p:AppxPackageDir=../artifacts/AppPackages/ -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} mkdir -p ../artifacts/msix cp ../artifacts/AppPackages/*/*.msix ../artifacts/msix/ @@ -609,7 +609,7 @@ jobs: path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Publish FwLiteWeb (linux-x64) working-directory: backend/FwLite/FwLiteWeb run: dotnet publish -r linux-x64 --artifacts-path ../artifacts -p:PublishSingleFile=true diff --git a/.github/workflows/integration-test-gha.yaml b/.github/workflows/integration-test-gha.yaml index f18eba9fc4..a112e0b177 100644 --- a/.github/workflows/integration-test-gha.yaml +++ b/.github/workflows/integration-test-gha.yaml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - uses: ./.github/actions/setup-k8s with: lexbox-api-tag: ${{ inputs.lexbox-api-tag }} diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index a6358768a6..95c3552536 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - uses: MatteoH2O1999/setup-python@429b7dee8a48c31eb72ce0b420ea938ff51c2f11 # v3.2.1 id: python if: ${{ inputs.runs-on != 'windows-latest' && !env.act && inputs.hg-version == '3' }} diff --git a/.github/workflows/lexbox-api.yaml b/.github/workflows/lexbox-api.yaml index 7dd81f5549..be3dc149a1 100644 --- a/.github/workflows/lexbox-api.yaml +++ b/.github/workflows/lexbox-api.yaml @@ -47,7 +47,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Install Task uses: arduino/setup-task@c0bc642852239c2689f73f4ea6459c29405f3c52 # v3.0.0 with: diff --git a/.github/workflows/lexbox-fw-headless.yaml b/.github/workflows/lexbox-fw-headless.yaml index 706af1da46..5c72efd27f 100644 --- a/.github/workflows/lexbox-fw-headless.yaml +++ b/.github/workflows/lexbox-fw-headless.yaml @@ -47,7 +47,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: - dotnet-version: '10.x' + global-json-file: global.json - name: Dotnet build run: dotnet build backend/FwHeadless/FwHeadless.csproj - name: Unit tests diff --git a/.vscode/tasks.json b/.vscode/tasks.json index bbe63c24bd..a7d94c7641 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -9,7 +9,7 @@ "build", "${workspaceFolder}/backend/FwLite/FwLiteMaui/FwLiteMaui.csproj", "--framework", - "net10.0-windows10.0.19041.0", + "net11.0-windows10.0.19041.0", ], "problemMatcher": "$msCompile" }, diff --git a/AGENTS.md b/AGENTS.md index d7ad9b5408..3b667c3917 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,7 +9,7 @@ This is a monorepo containing: ### Tech Stack -- **Backend**: .NET 10, C#, Entity Framework Core, GraphQL (Hot Chocolate) +- **Backend**: .NET 11, C#, Entity Framework Core, GraphQL (Hot Chocolate) - **Frontend**: SvelteKit, TypeScript - **Database**: PostgreSQL - **Infrastructure**: Docker, Kubernetes, Skaffold, Tilt @@ -117,7 +117,7 @@ If you are struggling, explain the difficulty to the user instead of cheating. * ## Cursor Cloud specific instructions -System deps (.NET 10 SDK, Taskfile/`task`) are baked into the VM snapshot; the startup update script only refreshes pnpm + FwLiteWeb NuGet deps. The generated TS types under `frontend/viewer/src/lib/dotnet-types/generated-types/` are committed, so the viewer runs without a backend build. +System deps (.NET 11 SDK, Taskfile/`task`) are baked into the VM snapshot; the startup update script only refreshes pnpm + FwLiteWeb NuGet deps. The generated TS types under `frontend/viewer/src/lib/dotnet-types/generated-types/` are committed, so the viewer runs without a backend build. ### Running FW Lite Web (headless) diff --git a/backend/AGENTS.md b/backend/AGENTS.md index 081083c0cb..66bcc0e029 100644 --- a/backend/AGENTS.md +++ b/backend/AGENTS.md @@ -1,6 +1,6 @@ # Backend -.NET 10 backend for LexBox and FwLite applications. +.NET 11 backend for LexBox and FwLite applications. ## Build & Test @@ -13,7 +13,7 @@ dotnet test # Build specific project dotnet build LexBoxApi/LexBoxApi.csproj -dotnet build FwLite/FwLiteMaui/FwLiteMaui.csproj --framework net10.0-windows10.0.19041.0 +dotnet build FwLite/FwLiteMaui/FwLiteMaui.csproj --framework net11.0-windows10.0.19041.0 ``` ## Project Structure @@ -38,7 +38,7 @@ To build against local Harmony source (e.g. when developing the CRDT substrate), - **Nullable**: Enabled globally, `Nullable` warnings are errors - **Implicit usings**: Enabled -- **Target framework**: net10.0 (unless platform-specific) +- **Target framework**: net11.0 (unless platform-specific) - **Async**: Use `async/await`, not `.Result` or `.Wait()`. Prefer `return await Foo()` over returning the task directly — awaiting keeps this method on the stack trace when the inner call throws. Only drop the `await` (return the task) as a hot-path micro-optimization ([#2435](https://github.com/sillsdev/languageforge-lexbox/pull/2435#discussion_r3584331713)) - **Records**: Prefer for DTOs and immutable data diff --git a/backend/Directory.Build.props b/backend/Directory.Build.props index a2aa73bf47..34ef124bd5 100644 --- a/backend/Directory.Build.props +++ b/backend/Directory.Build.props @@ -11,7 +11,7 @@ dev - net10.0 + net11.0 false enable enable diff --git a/backend/Dockerfile b/backend/Dockerfile index c6eaba94a7..ff3a8190d8 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,10 +1,10 @@ # syntax=docker/dockerfile:1 -FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base +FROM mcr.microsoft.com/dotnet/aspnet:11.0-preview AS base WORKDIR /app EXPOSE 80 EXPOSE 443 -FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:11.0-preview AS build COPY . . # WORKDIR /src diff --git a/backend/FwHeadless/Dockerfile b/backend/FwHeadless/Dockerfile index e5f0eb552a..3da4955593 100644 --- a/backend/FwHeadless/Dockerfile +++ b/backend/FwHeadless/Dockerfile @@ -1,10 +1,10 @@ # syntax=docker/dockerfile:1 -FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base +FROM mcr.microsoft.com/dotnet/aspnet:11.0-preview AS base WORKDIR /app EXPOSE 80 EXPOSE 443 -FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:11.0-preview AS build COPY . . RUN --mount=type=cache,target=/root/.nuget/packages dotnet restore "FwHeadless/FwHeadless.csproj" @@ -19,20 +19,50 @@ RUN --mount=type=cache,target=/root/.nuget/packages dotnet publish /p:Informatio FROM mcr.microsoft.com/dotnet/runtime:8.0 AS dotnet8 +# Chorus Mercurial 6.5 needs Python 3.12. aspnet:11.0-preview is Ubuntu 26.04 +# (python3 is 3.14). Build 3.12 in a throwaway stage (same base, so glibc/ssl match); +# curl/gnupg/deadsnakes never enter the runtime image. +FROM base AS python312 +RUN apt-get update \ + && apt-get install --yes --no-install-recommends ca-certificates curl gnupg \ + && curl -fsSL 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xF23C5A6CF475977595C89F51BA6932366A755776' \ + | gpg --dearmor -o /etc/apt/keyrings/deadsnakes.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/deadsnakes.gpg] https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") main" \ + > /etc/apt/sources.list.d/deadsnakes.list \ + && apt-get update \ + && apt-get install --yes --no-install-recommends python3.12 \ + && rm -rf /var/lib/apt/lists/* + FROM base AS final RUN mkdir -p /var/lib/fw-headless /var/www/.local/share && chown -R www-data:www-data /var/lib/fw-headless /var/www/.local/share +# Shared libs python3.12 / stdlib extensions need; the aspnet image does not ship them. +# Installing python3.12 itself here would also pull distro python3 (3.14). RUN apt-get update \ - && apt-get install --yes --no-install-recommends tini iputils-ping python3 \ + && apt-get install --yes --no-install-recommends tini iputils-ping ca-certificates \ + libexpat1 zlib1g libbz2-1.0 libcrypt1 libdb5.3t64 libffi8 liblzma5 \ + libncursesw6 libreadline8t64 libsqlite3-0 libssl3t64 libtinfo6 libuuid1 \ && rm -rf /var/lib/apt/lists/* +COPY --from=python312 /usr/bin/python3.12 /usr/bin/python3.12 +COPY --from=python312 /usr/lib/python3.12 /usr/lib/python3.12 +COPY --from=python312 /etc/python3.12 /etc/python3.12 WORKDIR /app +# Mercurial 6.5's demandimport breaks on 3.12+ (circular import of threading.RLock). +# Chorus spawns hg as a child, so this must be in the image env. +ENV HGDEMANDIMPORT=disable # dotnet 8 runtime is for ChorusMerge COPY --from=dotnet8 /usr/share/dotnet/host/fxr/ /usr/share/dotnet/host/fxr/ COPY --from=dotnet8 /usr/share/dotnet/shared/Microsoft.NETCore.App/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ COPY --from=publish /app/publish . # Ensure Chorus and Mercurial exec bits were not stripped by dotnet CLI tools RUN chmod +x chorusmerge && chmod +x Mercurial/hg && chmod +x Mercurial/chg 2>/dev/null || true -# Fix up mercurial.ini path to fixutf8 -RUN sed -i -e 's/fixutf8 = \/FwHeadless/fixutf8 = \/app/' Mercurial/mercurial.ini +# Fix up mercurial.ini path to fixutf8; point hg at python3.12 (shebang is python3) +RUN sed -i -e 's/fixutf8 = \/FwHeadless/fixutf8 = \/app/' Mercurial/mercurial.ini \ + && sed -i '1s|^#!.*python3.*|#!/usr/bin/env python3.12|' Mercurial/hg +# Smoke-test: bundled hg must start (python3.12). Chorus treats hg exit 1 as +# success, so a dead interpreter looks like "no .hg" at clone time. +RUN python3.12 --version \ + && ./Mercurial/hg version \ + || { echo "hg version smoke test failed (python3.12 $(python3.12 --version 2>&1))"; exit 1; } COPY Testing/test-template-repo.zip /tmp/test-template-repo.zip # Smoke-test FixFwData at image build time: FwHeadless runs under dotnet (AspNetCore shared # framework) but FixFwData is a standalone apphost (Core only). Web publish does not copy the @@ -40,7 +70,7 @@ COPY Testing/test-template-repo.zip /tmp/test-template-repo.zip # target must publish it into the same output. Running it here catches a broken publish early. RUN test -f FixFwData \ && chmod +x FixFwData \ - && python3 -c "import zipfile; open('/tmp/smoke.fwdata','wb').write(zipfile.ZipFile('/tmp/test-template-repo.zip').read('kevin-test-01.fwdata'))" \ + && python3.12 -c "import zipfile; open('/tmp/smoke.fwdata','wb').write(zipfile.ZipFile('/tmp/test-template-repo.zip').read('kevin-test-01.fwdata'))" \ && ./FixFwData /tmp/smoke.fwdata; ec=$?; rm -f /tmp/test-template-repo.zip /tmp/smoke.fwdata; \ if [ $ec -gt 1 ]; then echo "FixFwData smoke test failed with exit $ec"; exit 1; fi # Smoke-test: chorusmerge must engage the FieldWorks merge handler, not silently keep one diff --git a/backend/FwHeadless/FwHeadless.csproj b/backend/FwHeadless/FwHeadless.csproj index 9b6dd151ba..e7e6faab93 100644 --- a/backend/FwHeadless/FwHeadless.csproj +++ b/backend/FwHeadless/FwHeadless.csproj @@ -44,7 +44,7 @@ chorusmerge PreserveNewest - + ChorusMerge.runtimeconfig.json PreserveNewest diff --git a/backend/FwLite/AGENTS.md b/backend/FwLite/AGENTS.md index 2bc1a1d26a..41252dcbea 100644 --- a/backend/FwLite/AGENTS.md +++ b/backend/FwLite/AGENTS.md @@ -27,7 +27,7 @@ task fw-lite-web # from repo root dotnet test FwLiteOnly.slnf # Build MAUI app (Windows) -dotnet build FwLiteMaui/FwLiteMaui.csproj --framework net10.0-windows10.0.19041.0 +dotnet build FwLiteMaui/FwLiteMaui.csproj --framework net11.0-windows10.0.19041.0 ``` ## Testing on Android (agents) @@ -48,6 +48,8 @@ task fw-lite:has-stale-generated-types The configuration for this lives in `FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs` and `FwLiteShared/Reinforced.Typings.settings.xml`. +> **.NET 11 preview note:** Reinforced.Typings 1.6.7 has no net11 tool, so `FwLiteShared.csproj` forces its net10 `rtcli` and patches the tool's runtimeconfig to run on the net11 runtime (`_RtPatchToolRuntimeConfig` target). It's self-contained — no env vars needed. Delete `RtForceTargetFramework` + that target once the package ships a net11 tool. + ⚠️ **`[JSInvokable]` methods must not have optional/defaulted parameters (nor a `CancellationToken`).** The generated TS marks them optional (`arg?`), but that's a lie: Blazor JSInterop requires JS to pass every parameter, and can't marshal a `CancellationToken` — so JS callers break at runtime. If a server-side (REST) caller needs cancellation or an extra arg, add a separate **non-`[JSInvokable]`** overload for it (see `AuthService.SignInWebView`). ## Project Structure diff --git a/backend/FwLite/FwLiteMaui.Tests/FwLiteMaui.Tests.csproj b/backend/FwLite/FwLiteMaui.Tests/FwLiteMaui.Tests.csproj index 36af9daff8..45f70505bd 100644 --- a/backend/FwLite/FwLiteMaui.Tests/FwLiteMaui.Tests.csproj +++ b/backend/FwLite/FwLiteMaui.Tests/FwLiteMaui.Tests.csproj @@ -5,10 +5,10 @@ true - $(TargetFrameworks);net10.0-android - $(TargetFrameworks);net10.0-ios;net10.0-maccatalyst - $(TargetFrameworks);net10.0-windows10.0.19041.0 - $(NoWarn);XA0101 + $(TargetFrameworks);net11.0-android + $(TargetFrameworks);net11.0-ios;net11.0-maccatalyst + $(TargetFrameworks);net11.0-windows10.0.19041.0 + $(NoWarn);XA0101 diff --git a/backend/FwLite/FwLiteMaui/FwLiteMaui.csproj b/backend/FwLite/FwLiteMaui/FwLiteMaui.csproj index 69624a297c..e695ab09db 100644 --- a/backend/FwLite/FwLiteMaui/FwLiteMaui.csproj +++ b/backend/FwLite/FwLiteMaui/FwLiteMaui.csproj @@ -2,9 +2,9 @@ - $(TargetFrameworks);net10.0-android; - $(TargetFrameworks);net10.0-ios;net10.0-maccatalyst - $(TargetFrameworks);net10.0-windows10.0.19041.0 + $(TargetFrameworks);net11.0-android; + $(TargetFrameworks);net11.0-ios;net11.0-maccatalyst + $(TargetFrameworks);net11.0-windows10.0.19041.0 preview - android-arm;android-arm64;android-x86;android-x64 + android-arm;android-arm64;android-x64 Exe FwLiteMaui true @@ -60,7 +60,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - + @@ -133,7 +133,7 @@ DependsOnTargets="_VerifyLinq2DbEfCoreVersionPin" BeforeTargets="_ResolveAssemblies;_LinkAssembliesNoShrink;_AfterILLinkAdditionalSteps;_RemoveRegisterAttribute" Inputs="build\Linq2DbCctorPatcher\Program.cs;build\Linq2DbCctorPatcher\Linq2DbCctorPatcher.csproj" - Outputs="build\Linq2DbCctorPatcher\bin\$(Configuration)\net10.0\Linq2DbCctorPatcher.dll"> + Outputs="build\Linq2DbCctorPatcher\bin\$(Configuration)\net11.0\Linq2DbCctorPatcher.dll"> @@ -156,7 +156,7 @@ Inputs="@(_Linq2DbStagedAssemblies)" Outputs="@(_Linq2DbStagedAssemblies->'%(FullPath).cctor-patched')"> - <_Linq2DbPatcherDll>$(MSBuildThisFileDirectory)build\Linq2DbCctorPatcher\bin\$(Configuration)\net10.0\Linq2DbCctorPatcher.dll + <_Linq2DbPatcherDll>$(MSBuildThisFileDirectory)build\Linq2DbCctorPatcher\bin\$(Configuration)\net11.0\Linq2DbCctorPatcher.dll diff --git a/backend/FwLite/FwLiteMaui/build/Linq2DbCctorPatcher/Linq2DbCctorPatcher.csproj b/backend/FwLite/FwLiteMaui/build/Linq2DbCctorPatcher/Linq2DbCctorPatcher.csproj index 7c1483ed72..8bbaaca53e 100644 --- a/backend/FwLite/FwLiteMaui/build/Linq2DbCctorPatcher/Linq2DbCctorPatcher.csproj +++ b/backend/FwLite/FwLiteMaui/build/Linq2DbCctorPatcher/Linq2DbCctorPatcher.csproj @@ -1,7 +1,7 @@ Exe - net10.0 + net11.0 enable enable diff --git a/backend/FwLite/FwLiteShared/FwLiteShared.csproj b/backend/FwLite/FwLiteShared/FwLiteShared.csproj index d299ef8c46..f6d6ef7180 100644 --- a/backend/FwLite/FwLiteShared/FwLiteShared.csproj +++ b/backend/FwLite/FwLiteShared/FwLiteShared.csproj @@ -1,6 +1,17 @@ false + + net10.0 + + $(BundledNETCoreAppPackageVersion) @@ -14,7 +25,7 @@ - + @@ -22,4 +33,37 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/backend/FwLite/FwLiteWeb/Dockerfile b/backend/FwLite/FwLiteWeb/Dockerfile index ecbb8f887b..abe7f2a17a 100644 --- a/backend/FwLite/FwLiteWeb/Dockerfile +++ b/backend/FwLite/FwLiteWeb/Dockerfile @@ -1,10 +1,10 @@ -FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base +FROM mcr.microsoft.com/dotnet/aspnet:11.0-preview AS base USER $APP_UID WORKDIR /app EXPOSE 8080 EXPOSE 8081 -FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:11.0-preview AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["FwLiteWeb/FwLiteWeb.csproj", "FwLiteWeb/"] diff --git a/backend/FwLite/README.md b/backend/FwLite/README.md index 66fad5e3dc..d8aa89d9fd 100644 --- a/backend/FwLite/README.md +++ b/backend/FwLite/README.md @@ -34,7 +34,7 @@ dotnet test FwLiteOnly.slnf ### Building for a specific framework ```bash -dotnet build -f net10.0-ios +dotnet build -f net11.0-ios ``` You can choose which framework to build for with the `-f` flag. diff --git a/backend/FwLite/Taskfile.yml b/backend/FwLite/Taskfile.yml index 5960ddffc9..165ecaee81 100644 --- a/backend/FwLite/Taskfile.yml +++ b/backend/FwLite/Taskfile.yml @@ -67,7 +67,7 @@ tasks: maui-windows: desc: Run Maui Windows, requires vite dev server to be running, use task fw-lite-win in root dir: ./FwLiteMaui - cmd: dotnet run -f net10.0-windows10.0.19041.0 + cmd: dotnet run -f net11.0-windows10.0.19041.0 publish-maui-windows: deps: [ publish-maui-windows-msix, publish-maui-windows-portable] @@ -75,12 +75,12 @@ tasks: publish-maui-windows-portable: dir: ./FwLiteMaui cmds: - - dotnet publish -f net10.0-windows10.0.19041.0 --artifacts-path ../artifacts -p:WindowsPackageType=None -p:BuildAndroid=false + - dotnet publish -f net11.0-windows10.0.19041.0 --artifacts-path ../artifacts -p:WindowsPackageType=None -p:BuildAndroid=false publish-maui-windows-msix: dir: ./FwLiteMaui cmds: - - dotnet publish -f net10.0-windows10.0.19041.0 --artifacts-path ../artifacts -p:BuildAndroid=false + - dotnet publish -f net11.0-windows10.0.19041.0 --artifacts-path ../artifacts -p:BuildAndroid=false run-maui-android: dir: ./FwLiteMaui @@ -106,12 +106,12 @@ tasks: deps: [ ui:build-viewer ] dir: ./FwLiteMaui # EXTRA_ARGS goes through a Task var so multi-token values stay separate; CLI_ARGS gets re-quoted into a single shell arg. - cmd: dotnet build -f net10.0-android -t:InstallAndroidDependencies -p:AcceptAndroidSdkLicenses=True -p:FwLiteFlavor={{.FLAVOR}} {{.EXTRA_ARGS}} {{.CLI_ARGS}} + cmd: dotnet build -f net11.0-android -t:InstallAndroidDependencies -p:AcceptAndroidSdkLicenses=True -p:FwLiteFlavor={{.FLAVOR}} {{.EXTRA_ARGS}} {{.CLI_ARGS}} install-maui-android: desc: Retry install + run without rebuilding (for when you miss the permission prompt) - uses existing build artifacts dir: ./FwLiteMaui - cmd: dotnet build -f net10.0-android -t:Install,Run --no-restore --no-dependencies -p:FwLiteFlavor={{.FLAVOR}} {{.EXTRA_ARGS}} + cmd: dotnet build -f net11.0-android -t:Install,Run --no-restore --no-dependencies -p:FwLiteFlavor={{.FLAVOR}} {{.EXTRA_ARGS}} install-maui-android-dev: desc: Retry install + run for the "Dev" flavor without rebuilding @@ -128,9 +128,9 @@ tasks: publish-maui-android-release: deps: [ ui:build-viewer ] dir: ./FwLiteMaui - # Produces a signed AAB/APK at bin/Release/net10.0-android/-Signed.{aab,apk}. + # Produces a signed AAB/APK at bin/Release/net11.0-android/-Signed.{aab,apk}. # No -t:Run — the SDK's Run uses bundletool, which errors out with multiple devices/emulators. - cmd: dotnet build -f net10.0-android -c Release -t:InstallAndroidDependencies -p:AcceptAndroidSdkLicenses=True -p:FwLiteFlavor={{.FLAVOR}} {{.CLI_ARGS}} + cmd: dotnet build -f net11.0-android -c Release -t:InstallAndroidDependencies -p:AcceptAndroidSdkLicenses=True -p:FwLiteFlavor={{.FLAVOR}} {{.CLI_ARGS}} install-maui-android-release-dev: desc: Build a Release "Dev" APK and adb-install it on the connected USB device (uses `adb -d`) @@ -138,7 +138,7 @@ tasks: cmds: - task: publish-maui-android-release vars: { FLAVOR: 'Dev' } - - adb -d install -r bin/Release/net10.0-android/org.sil.FwLiteMaui.dev-Signed.apk + - adb -d install -r bin/Release/net11.0-android/org.sil.FwLiteMaui.dev-Signed.apk build-mini-lcm-sdk: desc: Builds the sdk, a zip with the FwLiteWeb server with a project and config to run locally @@ -185,7 +185,7 @@ tasks: test-verified: desc: Run only tests that generate verified snapshot files # always produces exit status 1, because the framework isn't valid for all test projects - cmd: dotnet test ../../FwLiteOnly.slnf --filter "Category=Verified" --framework net10.0 --logger "console;verbosity=minimal" + cmd: dotnet test ../../FwLiteOnly.slnf --filter "Category=Verified" --framework net11.0 --logger "console;verbosity=minimal" reset-verified: desc: Reset all verified snapshot files to their state on origin/develop cmds: diff --git a/backend/WebServiceDefaults/WebServiceDefaults.csproj b/backend/WebServiceDefaults/WebServiceDefaults.csproj index 8b58ee4f35..def4384183 100644 --- a/backend/WebServiceDefaults/WebServiceDefaults.csproj +++ b/backend/WebServiceDefaults/WebServiceDefaults.csproj @@ -1,6 +1,6 @@ - net10.0 + net11.0 enable enable diff --git a/docs/research/msix-appinstaller-fwlite.md b/docs/research/msix-appinstaller-fwlite.md index 5e261b2fbd..f88b5f820d 100644 --- a/docs/research/msix-appinstaller-fwlite.md +++ b/docs/research/msix-appinstaller-fwlite.md @@ -171,7 +171,7 @@ experiment before committing to the approach.** FW Lite's generated file uses the **2021 schema** and `OnLaunch` + `ShowPrompt` + `UpdateBlocksActivation` + `AutomaticBackgroundTask` + `ForceUpdateFromAnyVersion`, so the effective floor is **Windows 10 2004 (19041)** — which is also the MAUI target framework floor -(`net10.0-windows10.0.19041.0`), so no new constraint is introduced. +(`net11.0-windows10.0.19041.0`), so no new constraint is introduced. **Signing / trust:** packages must be signed with a certificate trusted by the device. A CA-trusted cert (Trusted Signing, which FW Lite uses) means Windows already trusts it and nothing needs to be diff --git a/global.json b/global.json index 1e7fdfa95f..2b40c8f6cb 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,7 @@ { + "//": "version is a floor: CI installs it exactly (setup-dotnet global-json-file); locally rollForward:latestMinor uses the newest installed 11.x SDK.", "sdk": { - "version": "10.0.100", + "version": "11.0.100-preview.7.26381.103", "rollForward": "latestMinor" } }