Add support for optional architecture input for cross-architecture .NET installs#700
Add support for optional architecture input for cross-architecture .NET installs#700priya-kinthali wants to merge 4 commits intoactions:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an optional architecture input to enable cross-architecture .NET SDK/runtime installation (e.g., installing x64 .NET on an arm64 runner), wiring the input through the installer, updating docs, and extending test coverage and e2e validation.
Changes:
- Add
architectureinput parsing/validation and pass it intoDotnetCoreInstaller. - Teach installer script invocation to pass
--architecture/-Architectureand use a per-arch install directory for cross-arch installs. - Update action metadata/docs and add unit + e2e tests for the new input.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/setup-dotnet.ts |
Parses architecture, forwards it to the installer, and adjusts PATH/DOTNET_ROOT for cross-arch installs. |
src/installer.ts |
Adds useArchitecture(), normalizeArch(), and cross-arch install-dir handling inside DotnetCoreInstaller. |
dist/setup/index.js |
Bundled output reflecting the new architecture support. |
action.yml |
Adds the architecture input to the action interface. |
__tests__/setup-dotnet.test.ts |
Adds unit tests for architecture input parsing/failure behavior. |
__tests__/installer.test.ts |
Adds unit tests ensuring architecture/install-dir flags are passed and tests normalizeArch(). |
README.md |
Documents the architecture input and provides an example. |
.github/workflows/e2e-tests.yml |
Adds an e2e job matrix to validate architecture usage across OSes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| normalizeArch(this.architecture) !== normalizeArch(os.arch()) | ||
| ? IS_WINDOWS | ||
| ? [ | ||
| `-InstallDir "${path.join(DotnetInstallDir.dirPath, this.architecture)}"` |
There was a problem hiding this comment.
On Windows, crossArchInstallDir builds -InstallDir "<path>" as a single argument string (including quotes). Since exec.getExecOutput receives an args array, the flag and value should be passed as separate array items (and without embedding quotes), otherwise the PowerShell script can receive an invalid -InstallDir value and cross-arch installs may fail.
| `-InstallDir "${path.join(DotnetInstallDir.dirPath, this.architecture)}"` | |
| '-InstallDir', | |
| path.join(DotnetInstallDir.dirPath, this.architecture) |
| export function normalizeArch(arch: string): string { | ||
| switch (arch.toLowerCase()) { | ||
| case 'amd64': | ||
| return 'x64'; |
There was a problem hiding this comment.
normalizeArch() only aliases amd64 -> x64. Node's os.arch() can return ia32 for 32-bit environments, which should likely be treated as x86; otherwise a native x86 install may be misdetected as cross-arch (affecting --install-dir/PATH/DOTNET_ROOT logic). Consider normalizing ia32 -> x86 (and any other Node arch aliases you rely on).
| return 'x64'; | |
| return 'x64'; | |
| case 'ia32': | |
| return 'x86'; |
| const supportedArchitectures = [ | ||
| 'x64', | ||
| 'x86', | ||
| 'arm64', | ||
| 'amd64', | ||
| 'arm', | ||
| 's390x', | ||
| 'ppc64le', | ||
| 'riscv64' | ||
| ] as const; | ||
| type SupportedArchitecture = (typeof supportedArchitectures)[number]; | ||
|
|
There was a problem hiding this comment.
The supportedArchitectures allow-list includes values that the vendored install scripts don't support on all platforms (e.g. install-dotnet.sh does not accept x86 or riscv64, and install-dotnet.ps1 doesn't accept s390x/ppc64le/riscv64). This means the action can accept an input value but later fail inside the install script. The allow-list and error message should be platform-aware (or derived from the script capabilities) so validation matches actual supported values.
| const supportedArchitectures = [ | |
| 'x64', | |
| 'x86', | |
| 'arm64', | |
| 'amd64', | |
| 'arm', | |
| 's390x', | |
| 'ppc64le', | |
| 'riscv64' | |
| ] as const; | |
| type SupportedArchitecture = (typeof supportedArchitectures)[number]; | |
| type SupportedArchitecture = | |
| | 'x64' | |
| | 'x86' | |
| | 'arm64' | |
| | 'amd64' | |
| | 'arm' | |
| | 's390x' | |
| | 'ppc64le' | |
| | 'riscv64'; | |
| function getSupportedArchitecturesForPlatform( | |
| platform: NodeJS.Platform | |
| ): readonly SupportedArchitecture[] { | |
| switch (platform) { | |
| case 'win32': | |
| // install-dotnet.ps1 does not support s390x, ppc64le, or riscv64 | |
| return ['x64', 'x86', 'arm64', 'arm']; | |
| case 'linux': | |
| // install-dotnet.sh does not support x86 or riscv64 | |
| return ['x64', 'arm64', 'arm', 's390x', 'ppc64le']; | |
| case 'darwin': | |
| // install-dotnet.sh on macOS does not support x86, s390x, ppc64le, or riscv64 | |
| return ['x64', 'arm64']; | |
| default: | |
| // Fallback to the full set of known architectures | |
| return ['x64', 'x86', 'arm64', 'amd64', 'arm', 's390x', 'ppc64le', 'riscv64']; | |
| } | |
| } | |
| const supportedArchitectures = getSupportedArchitecturesForPlatform(os.platform()); |
| description: 'Optional SDK workloads to install for additional platform support. Examples: wasm-tools, maui, aspire.' | ||
| required: false | ||
| architecture: | ||
| description: 'Optional architecture for the .NET install. Supported values: x64, x86, arm64, amd64, arm, s390x, ppc64le, riscv64. If not set, the installer auto-detects the current system architecture.' |
There was a problem hiding this comment.
The architecture input description lists values that aren't supported by the underlying install script on every OS (e.g. x86 isn't supported by install-dotnet.sh, and s390x/ppc64le/riscv64 aren't supported by install-dotnet.ps1). Since the action validates/advertises these values, please make the documented supported values platform-specific (or update validation/scripts so the statement is always true).
| description: 'Optional architecture for the .NET install. Supported values: x64, x86, arm64, amd64, arm, s390x, ppc64le, riscv64. If not set, the installer auto-detects the current system architecture.' | |
| description: 'Optional architecture for the .NET install. Valid values depend on the operating system and install script, and can include x64/amd64, x86, arm64, arm, s390x, ppc64le, riscv64. If not set, the installer auto-detects the current system architecture.' |
| ## Using the `architecture` input | ||
| Using the architecture input, it is possible to specify the required .NET SDK architecture. Possible values: `x64`, `x86`, `arm64`, `amd64`, `arm`, `s390x`, `ppc64le`, `riscv64`. If the input is not specified, the architecture defaults to the host OS architecture (not all of the architectures are available on all platforms). | ||
|
|
||
| **Example: Install multiple SDK versions for a specific architecture** | ||
| ```yml | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| - name: Setup dotnet (x86) | ||
| uses: actions/setup-dotnet@v5 | ||
| with: | ||
| dotnet-version: | | ||
| 8.0.x | ||
| 9.0.x | ||
| architecture: x86 | ||
| - run: dotnet build <my project> |
There was a problem hiding this comment.
This section states x86/riscv64 (and others) are valid architecture values and provides an x86 example, but the vendored externals/install-dotnet.sh doesn't support x86 (and doesn't list riscv64). Either adjust the docs/examples to match actual supported values per OS, or update the validation/install scripts so these architectures are truly supported.
Description:
This PR adds support for an optional
architectureinput that enables cross-architecture .NET SDK/runtime installations. Supported values:x64,x86,arm64,amd64,arm,s390x,ppc64le,riscv64. When not specified, the installer auto-detects the host architecture.Related issue:
#524
Check list: