Skip to content
Merged
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
20 changes: 0 additions & 20 deletions .claude/skills/winapp-setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,6 @@ winapp restore ./my-project

Use `restore` when you clone a repo that already has `winapp.yaml` but no `.winapp/` folder.

### Private or custom NuGet feeds

`init`, `restore`, and `update` download the Windows SDK and Windows App SDK packages through NuGet, honoring your standard `nuget.config` hierarchy (project, user, and machine level). To restore the SDK packages from an internal feed or mirror, add it under `<packageSources>`; winapp queries every enabled source — over HTTPS, or a local folder path — and picks the highest listed version for `init`/`update` (excluding versions the publisher has *unlisted* — except on a v3 feed that exposes only a flat-container `PackageBaseAddress` with no registration resource, which carries no listed/unlisted flag, so an unlisted version could be selected there; registration-backed feeds such as nuget.org and most Azure Artifacts feeds are unaffected). A plain-**HTTP** feed is refused unless it opts in with `allowInsecureConnections="true"` on the `<add>` entry (the SDK packages are executables, so an unencrypted feed is a code-substitution vector) — switch the mirror to HTTPS or set that attribute. If your `nuget.config` defines a `<packageSourceMapping>`, only the sources mapped to a given package are queried for it, so an enabled feed excluded by the mapping is skipped (and an unmapped package fails to resolve rather than falling back to another feed). To use *only* your feed, `<clear />` the inherited sources first:

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="contoso" value="https://pkgs.dev.azure.com/contoso/_packaging/winsdk-mirror/nuget/v3/index.json" />
</packageSources>
</configuration>
```

Authentication uses credentials from `nuget.config` (`<packageSourceCredentials>`), environment-based credentials, and NuGet credential-provider plugins automatically — interactive prompts only appear on interactive terminals, so CI relies on pre-configured/environment credentials. The package cache location follows `NUGET_PACKAGES` / `globalPackagesFolder`, falling back to `~/.nuget/packages`.

> **Security note:** winapp honors the `nuget.config` in the selected project/config directory — the working directory by default, or the directory passed to `init <dir>` / `restore --config-dir <dir>` — so it restores from the feeds (and into the `globalPackagesFolder`) that config specifies. Run `init`/`restore`/`update` only against directories you trust, the same as `dotnet restore`. Use `<packageSourceMapping>` to pin packages to specific feeds when more than one source is configured.

### Update SDK versions

```powershell
Expand Down Expand Up @@ -177,8 +159,6 @@ For full debugging scenarios and IDE setup, see the [Debugging Guide](https://gi
| "winapp.yaml not found" | Running `restore`/`update` without config | Run `winapp init` first, or ensure you're in the right directory |
| "Directory not found" | Target directory doesn't exist | Create the directory first or check the path |
| SDK download fails | Network issue or firewall | Ensure internet access; check proxy settings |
| SDK download fails with 401/403 | Private feed requires authentication | Store credentials in `nuget.config` (`<packageSourceCredentials>`) or configure a credential provider / feed environment credentials before running in CI |
| SDK package not found on private feed | Feed doesn't mirror the SDK packages, or the wrong source is configured | Ensure the feed serves `Microsoft.WindowsAppSDK`, `Microsoft.Windows.SDK.CPP`, `Microsoft.Windows.CppWinRT`, etc.; keep `nuget.org` enabled if the feed only supplements it |
| `init` prompts unexpectedly in CI | Missing `--use-defaults` flag | Add `--use-defaults` to skip all prompts (note: non-interactive shells are now auto-detected) |


Expand Down
20 changes: 0 additions & 20 deletions .github/plugin/skills/winapp-cli/setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,6 @@ winapp restore ./my-project

Use `restore` when you clone a repo that already has `winapp.yaml` but no `.winapp/` folder.

### Private or custom NuGet feeds

`init`, `restore`, and `update` download the Windows SDK and Windows App SDK packages through NuGet, honoring your standard `nuget.config` hierarchy (project, user, and machine level). To restore the SDK packages from an internal feed or mirror, add it under `<packageSources>`; winapp queries every enabled source — over HTTPS, or a local folder path — and picks the highest listed version for `init`/`update` (excluding versions the publisher has *unlisted* — except on a v3 feed that exposes only a flat-container `PackageBaseAddress` with no registration resource, which carries no listed/unlisted flag, so an unlisted version could be selected there; registration-backed feeds such as nuget.org and most Azure Artifacts feeds are unaffected). A plain-**HTTP** feed is refused unless it opts in with `allowInsecureConnections="true"` on the `<add>` entry (the SDK packages are executables, so an unencrypted feed is a code-substitution vector) — switch the mirror to HTTPS or set that attribute. If your `nuget.config` defines a `<packageSourceMapping>`, only the sources mapped to a given package are queried for it, so an enabled feed excluded by the mapping is skipped (and an unmapped package fails to resolve rather than falling back to another feed). To use *only* your feed, `<clear />` the inherited sources first:

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="contoso" value="https://pkgs.dev.azure.com/contoso/_packaging/winsdk-mirror/nuget/v3/index.json" />
</packageSources>
</configuration>
```

Authentication uses credentials from `nuget.config` (`<packageSourceCredentials>`), environment-based credentials, and NuGet credential-provider plugins automatically — interactive prompts only appear on interactive terminals, so CI relies on pre-configured/environment credentials. The package cache location follows `NUGET_PACKAGES` / `globalPackagesFolder`, falling back to `~/.nuget/packages`.

> **Security note:** winapp honors the `nuget.config` in the selected project/config directory — the working directory by default, or the directory passed to `init <dir>` / `restore --config-dir <dir>` — so it restores from the feeds (and into the `globalPackagesFolder`) that config specifies. Run `init`/`restore`/`update` only against directories you trust, the same as `dotnet restore`. Use `<packageSourceMapping>` to pin packages to specific feeds when more than one source is configured.

### Update SDK versions

```powershell
Expand Down Expand Up @@ -177,8 +159,6 @@ For full debugging scenarios and IDE setup, see the [Debugging Guide](https://gi
| "winapp.yaml not found" | Running `restore`/`update` without config | Run `winapp init` first, or ensure you're in the right directory |
| "Directory not found" | Target directory doesn't exist | Create the directory first or check the path |
| SDK download fails | Network issue or firewall | Ensure internet access; check proxy settings |
| SDK download fails with 401/403 | Private feed requires authentication | Store credentials in `nuget.config` (`<packageSourceCredentials>`) or configure a credential provider / feed environment credentials before running in CI |
| SDK package not found on private feed | Feed doesn't mirror the SDK packages, or the wrong source is configured | Ensure the feed serves `Microsoft.WindowsAppSDK`, `Microsoft.Windows.SDK.CPP`, `Microsoft.Windows.CppWinRT`, etc.; keep `nuget.org` enabled if the feed only supplements it |
| `init` prompts unexpectedly in CI | Missing `--use-defaults` flag | Add `--use-defaults` to skip all prompts (note: non-interactive shells are now auto-detected) |


Expand Down
8 changes: 0 additions & 8 deletions .pipelines/release-nuget.config
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@
<packageSources>
<clear />
<add key="pde-oss_Internal" value="https://pkgs.dev.azure.com/microsoft/pde-oss/_packaging/pde-oss_Internal/nuget/v3/index.json" />
<!--
CI/release restore uses ONLY this internal feed (single source). winapp depends on prerelease
NuGet client libraries (NuGet.* 7.9.0-rc, required for Native AOT — see
src/winapp-CLI/Directory.Packages.props); the public dnceng "dotnet-tools" feed
(https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json) is
configured as an upstream source on pde-oss_Internal, so those packages resolve through it.
Once a 7.8+ stable ships to nuget.org, the prerelease pin (and that upstream) can be removed.
-->
</packageSources>
<disabledPackageSources>
<clear />
Expand Down
27 changes: 11 additions & 16 deletions docs/dotnet-run-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,22 +172,17 @@ Capture OutputDebugString messages and first-chance exceptions:

## Production Blockers

### 1. CLI AOT Build Issues (RESOLVED)

Earlier prototypes of the CLI hit NativeAOT compilation errors from Newtonsoft.Json (reflection-heavy
serialization) and NuGet.Protocol (dynamic code generation), which blocked shipping the CLI binaries in
the NuGet package.

**Resolution (shipped):**
- The CLI consumes the NuGet client libraries (`NuGet.Protocol`/`Packaging`/`Configuration`/`Credentials`)
and opts into their AOT-friendly JSON path with the runtime feature switch
`NuGet.UseSystemTextJsonDeserialization=true` (`Trim=true`) in `WinApp.Cli.csproj`.
- With System.Text.Json deserialization enabled, Newtonsoft.Json is fully trimmed out of the native image,
so the DynamicProxy code paths that produced the trim/AOT warnings are no longer reachable.
- `dotnet publish -c Release -r <rid> -p:PublishAot=true` now completes with **0 warnings** under
`TreatWarningsAsErrors` for both `win-x64` and `win-arm64`.

See the [NuGet AOT tracking issue](https://github.com/NuGet/Home/issues/14408) (now closed) for background.
### 1. CLI AOT Build Issues (BLOCKING)

The CLI currently has NativeAOT compilation errors related to Newtonsoft.Json and NuGet.Protocol. These must be resolved before the NuGet package can include the CLI binaries.

**Error summary:**
- 146 trim/AOT analysis errors
- Related to reflection-heavy code in Newtonsoft.Json
Comment on lines +177 to +181
- Related to dynamic code generation in NuGet.Protocol

**Resolution:**
- Wait until https://github.com/NuGet/Home/issues/14408

### 2. Developer Mode Requirement

Expand Down
20 changes: 0 additions & 20 deletions docs/fragments/skills/winapp-cli/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,6 @@ winapp restore ./my-project

Use `restore` when you clone a repo that already has `winapp.yaml` but no `.winapp/` folder.

### Private or custom NuGet feeds

`init`, `restore`, and `update` download the Windows SDK and Windows App SDK packages through NuGet, honoring your standard `nuget.config` hierarchy (project, user, and machine level). To restore the SDK packages from an internal feed or mirror, add it under `<packageSources>`; winapp queries every enabled source — over HTTPS, or a local folder path — and picks the highest listed version for `init`/`update` (excluding versions the publisher has *unlisted* — except on a v3 feed that exposes only a flat-container `PackageBaseAddress` with no registration resource, which carries no listed/unlisted flag, so an unlisted version could be selected there; registration-backed feeds such as nuget.org and most Azure Artifacts feeds are unaffected). A plain-**HTTP** feed is refused unless it opts in with `allowInsecureConnections="true"` on the `<add>` entry (the SDK packages are executables, so an unencrypted feed is a code-substitution vector) — switch the mirror to HTTPS or set that attribute. If your `nuget.config` defines a `<packageSourceMapping>`, only the sources mapped to a given package are queried for it, so an enabled feed excluded by the mapping is skipped (and an unmapped package fails to resolve rather than falling back to another feed). To use *only* your feed, `<clear />` the inherited sources first:

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="contoso" value="https://pkgs.dev.azure.com/contoso/_packaging/winsdk-mirror/nuget/v3/index.json" />
</packageSources>
</configuration>
```

Authentication uses credentials from `nuget.config` (`<packageSourceCredentials>`), environment-based credentials, and NuGet credential-provider plugins automatically — interactive prompts only appear on interactive terminals, so CI relies on pre-configured/environment credentials. The package cache location follows `NUGET_PACKAGES` / `globalPackagesFolder`, falling back to `~/.nuget/packages`.

> **Security note:** winapp honors the `nuget.config` in the selected project/config directory — the working directory by default, or the directory passed to `init <dir>` / `restore --config-dir <dir>` — so it restores from the feeds (and into the `globalPackagesFolder`) that config specifies. Run `init`/`restore`/`update` only against directories you trust, the same as `dotnet restore`. Use `<packageSourceMapping>` to pin packages to specific feeds when more than one source is configured.

### Update SDK versions

```powershell
Expand Down Expand Up @@ -172,6 +154,4 @@ For full debugging scenarios and IDE setup, see the [Debugging Guide](https://gi
| "winapp.yaml not found" | Running `restore`/`update` without config | Run `winapp init` first, or ensure you're in the right directory |
| "Directory not found" | Target directory doesn't exist | Create the directory first or check the path |
| SDK download fails | Network issue or firewall | Ensure internet access; check proxy settings |
| SDK download fails with 401/403 | Private feed requires authentication | Store credentials in `nuget.config` (`<packageSourceCredentials>`) or configure a credential provider / feed environment credentials before running in CI |
| SDK package not found on private feed | Feed doesn't mirror the SDK packages, or the wrong source is configured | Ensure the feed serves `Microsoft.WindowsAppSDK`, `Microsoft.Windows.SDK.CPP`, `Microsoft.Windows.CppWinRT`, etc.; keep `nuget.org` enabled if the feed only supplements it |
| `init` prompts unexpectedly in CI | Missing `--use-defaults` flag | Add `--use-defaults` to skip all prompts (note: non-interactive shells are now auto-detected) |
27 changes: 0 additions & 27 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,33 +138,6 @@ winapp restore [options]
winapp restore
```

**Custom and private NuGet feeds:**

`winapp init`, `restore`, and `update` download the Windows SDK and Windows App SDK packages through NuGet, honoring your standard [`nuget.config`](https://learn.microsoft.com/nuget/reference/nuget-config-file) hierarchy (project, user, and machine level). This lets you:

- **Use a private feed or mirror** — add it under `<packageSources>` (for example, an internal Azure Artifacts feed that mirrors the SDK packages). winapp queries every enabled source — over HTTPS, or a local folder path — and, for `init`/`update`, selects the highest listed version across all of them. A plain-**HTTP** feed is refused unless it explicitly opts in with `allowInsecureConnections="true"` on the `<add>` entry, because the SDK packages are executables and an unencrypted feed is a code-substitution vector; switch the mirror to HTTPS or set that attribute. If your `nuget.config` defines a [`<packageSourceMapping>`](https://learn.microsoft.com/nuget/consume-packages/package-source-mapping), only the sources mapped to a given package are queried for it — an enabled feed that the mapping excludes is intentionally skipped, so a package that is not mapped to any source fails to resolve rather than falling back to an unmapped feed. To make winapp use *only* your feed (e.g., an air-gapped mirror), `<clear />` the inherited sources and add just yours.
- **Authenticate to private feeds** — credentials stored in `nuget.config` (`<packageSourceCredentials>`), environment-based credentials, and NuGet credential-provider plugins (such as the Azure Artifacts provider) are all used automatically. Interactive prompts appear only on interactive terminals; CI and other non-interactive runs rely on pre-configured or environment credentials.
- **Control the package cache location** — the global packages folder is resolved from the `NUGET_PACKAGES` environment variable or the `globalPackagesFolder` setting in `nuget.config`, falling back to `~/.nuget/packages`.

Example `nuget.config` that restores the SDK packages exclusively from a private mirror:

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="contoso" value="https://pkgs.dev.azure.com/contoso/_packaging/winsdk-mirror/nuget/v3/index.json" />
</packageSources>
</configuration>
```

> **Security note:** winapp honors the `nuget.config` in the selected project/config directory — the working directory by default, or the directory you pass to `winapp init <dir>` / `restore --config-dir <dir>` — so it restores SDK packages from whatever feeds, and into whatever `globalPackagesFolder`, that config specifies. Only run `winapp init`/`restore`/`update` against directories you trust, the same caution that applies to `dotnet restore`/`dotnet build`. When more than one source is configured, use [Package Source Mapping](https://learn.microsoft.com/nuget/consume-packages/package-source-mapping) (`<packageSourceMapping>`) to pin each package to a specific feed and mitigate dependency-confusion attacks. Note that mapping governs where a package is *downloaded from*, not one already present in the global packages folder: NuGet — and winapp's cache check that reuses a completed package — restores an already-cached package regardless of which feed first populated it. If you rely on mapping for source *trust*, restore into a clean or repository-scoped global packages folder (set `NUGET_PACKAGES` or `globalPackagesFolder`) so a package can't be reused from a copy a different feed populated earlier.

> **Resolution limitations:** winapp targets the curated Windows App SDK dependency graphs and resolves them as it installs, so it does **not** implement NuGet's full graph unification. Two consequences to be aware of when pointing it at arbitrary private feeds:
>
> - **Diamond dependencies keep the first-selected version.** When two branches of the graph require the same package at *different lower bounds* (for example `[1.0,)` on one path and `[2.0,)` on another), winapp keeps the version chosen by the first branch it resolved rather than upgrading to a version that satisfies both. A graph whose ranges are genuinely *incompatible* (for example `[1.0,2.0)` and `[2.0,3.0)`, which no single version can satisfy) still fails the restore.
> - **Flat-container-only feeds can't hide unlisted versions.** A v3 feed that exposes only a `PackageBaseAddress` (flat container) resource with **no** registration resource carries no listed/unlisted flag, so `init`/`update` may select an unlisted version as "latest". Registration-backed feeds — nuget.org and most Azure Artifacts feeds — are unaffected.

---

### update
Expand Down
Loading
Loading