mirror of
https://github.com/microsoft/setup-msbuild.git
synced 2026-10-05 16:44:15 +07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e272ef36d |
No files matched your search
@@ -5,25 +5,11 @@ This action will help discover where the `MSBuild` tool is and automatically add
|
||||
> [!IMPORTANT]
|
||||
> Please note this tool does NOT add other Visual Studio tools (like VSTest, cl, cmake, or others) to `PATH`
|
||||
|
||||
## Breaking Changes in v4
|
||||
|
||||
Starting with `v4`, the default value of `msbuild-architecture` is no longer always `x86`. When
|
||||
`msbuild-architecture` is not explicitly specified, the action now **auto-detects** the best
|
||||
architecture:
|
||||
|
||||
- `x64` when running on a 64-bit machine **and** the resolved Visual Studio/MSBuild install is
|
||||
version 17.0 or later (Visual Studio 2022+, which ships a native 64-bit MSBuild).
|
||||
- `x86` otherwise (older Visual Studio versions, or 32-bit hosts), matching the previous behavior.
|
||||
|
||||
If you explicitly set `msbuild-architecture` (e.g. `x86`, `x64`, or `arm64`), that value is always
|
||||
respected and this auto-detection does not apply. If your workflow depends on always getting the
|
||||
32-bit MSBuild by default, set `msbuild-architecture: x86` explicitly.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```yml
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v4
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Build app for release
|
||||
run: msbuild src\YourProjectFile.csproj -t:rebuild -verbosity:diag -property:Configuration=Release
|
||||
@@ -43,7 +29,7 @@ You may have a situation where your Actions runner has multiple versions of Visu
|
||||
|
||||
```yml
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v4
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
with:
|
||||
vs-version: '[16.4,16.5)'
|
||||
```
|
||||
@@ -56,22 +42,18 @@ If you need your Actions runner to target a pre-release version of Visual Studio
|
||||
|
||||
```yml
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v4
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
with:
|
||||
vs-prerelease: true
|
||||
```
|
||||
|
||||
### Specifying MSBuild architecture (optional)
|
||||
|
||||
By default (as of `v4`), the action auto-detects the preferred MSBuild architecture: it uses `x64`
|
||||
when running on a 64-bit machine with Visual Studio/MSBuild 17.0 or later installed, and falls back
|
||||
to `x86` otherwise. You can override this by explicitly setting the `msbuild-architecture` input.
|
||||
Valid input values are `x86`, `x64`, and `arm64`. Note that the success of these will rely on the
|
||||
runner OS.
|
||||
By default the action will use the x86 architecture for MSBuild, but it is possible to target the x64 versions instead. Simply add the `msbuild-architecture` input. Valid input values are `x86` (default), `x64`, and `arm64`. Note that the success of these will rely on the runner OS.
|
||||
|
||||
```yml
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v4
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
```
|
||||
@@ -82,7 +64,7 @@ This makes use of the vswhere tool which is a tool delivered by Microsoft to hel
|
||||
|
||||
```yml
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v4
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
with:
|
||||
vswhere-path: 'C:\path\to\your\tools\'
|
||||
```
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import {
|
||||
MIN_VS_VERSION_FOR_X64,
|
||||
parseMajorVersion,
|
||||
resolveMSBuildArchitecture
|
||||
} from '../src/main'
|
||||
|
||||
describe('parseMajorVersion', () => {
|
||||
it('parses a standard installationVersion string', () => {
|
||||
expect(parseMajorVersion('17.9.34728.123')).toBe(17)
|
||||
})
|
||||
|
||||
it('parses a single-segment version', () => {
|
||||
expect(parseMajorVersion('16')).toBe(16)
|
||||
})
|
||||
|
||||
it('trims whitespace before parsing', () => {
|
||||
expect(parseMajorVersion(' 17.0.0.0 ')).toBe(17)
|
||||
})
|
||||
|
||||
it('returns undefined for an empty string', () => {
|
||||
expect(parseMajorVersion('')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('returns undefined for a non-numeric string', () => {
|
||||
expect(parseMajorVersion('not-a-version')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('resolveMSBuildArchitecture', () => {
|
||||
it('always respects an explicit architecture, regardless of OS/version', () => {
|
||||
expect(resolveMSBuildArchitecture('x86', true, 17)).toBe('x86')
|
||||
expect(resolveMSBuildArchitecture('x64', false, 15)).toBe('x64')
|
||||
expect(resolveMSBuildArchitecture('arm64', true, 17)).toBe('arm64')
|
||||
})
|
||||
|
||||
it('defaults to x64 on a 64-bit host with VS/MSBuild 17+', () => {
|
||||
expect(resolveMSBuildArchitecture('', true, MIN_VS_VERSION_FOR_X64)).toBe(
|
||||
'x64'
|
||||
)
|
||||
expect(resolveMSBuildArchitecture('', true, 18)).toBe('x64')
|
||||
})
|
||||
|
||||
it('defaults to x86 on a 64-bit host with VS/MSBuild older than 17', () => {
|
||||
expect(resolveMSBuildArchitecture('', true, 16)).toBe('x86')
|
||||
})
|
||||
|
||||
it('defaults to x86 on a non-64-bit host even with VS/MSBuild 17+', () => {
|
||||
expect(resolveMSBuildArchitecture('', false, 17)).toBe('x86')
|
||||
})
|
||||
|
||||
it('defaults to x86 when the VS/MSBuild version could not be determined', () => {
|
||||
expect(resolveMSBuildArchitecture('', true, undefined)).toBe('x86')
|
||||
})
|
||||
})
|
||||
+2
-1
@@ -15,8 +15,9 @@ inputs:
|
||||
description: "Enable searching for pre-release versions of Visual Studio/MSBuild"
|
||||
required: false
|
||||
msbuild-architecture:
|
||||
description: 'The preferred processor architecture of MSBuild. Can be either "x86", "x64", or "arm64". "x64" is only available from Visual Studio version 17.0 and later. If left unspecified, the action auto-detects the best option: "x64" on 64-bit machines when a Visual Studio/MSBuild 17.0+ install is found, otherwise "x86".'
|
||||
description: 'The preferred processor architecture of MSBuild. Can be either "x86", "x64", or "arm64". "x64" is only available from Visual Studio version 17.0 and later.'
|
||||
required: false
|
||||
default: "x86"
|
||||
outputs:
|
||||
msbuildPath:
|
||||
description: "The resulting location of msbuild for your inputs"
|
||||
|
||||
Vendored
+2
-72
@@ -26,45 +26,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const core = __importStar(__nccwpck_require__(484));
|
||||
const exec = __importStar(__nccwpck_require__(236));
|
||||
const fs = __importStar(__nccwpck_require__(896));
|
||||
const os = __importStar(__nccwpck_require__(857));
|
||||
const path = __importStar(__nccwpck_require__(928));
|
||||
const io = __importStar(__nccwpck_require__(994));
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
const VS_VERSION = core.getInput('vs-version') || 'latest';
|
||||
const VSWHERE_PATH = core.getInput('vswhere-path');
|
||||
const ALLOW_PRERELEASE = core.getInput('vs-prerelease') || 'false';
|
||||
const MSBUILD_ARCH_INPUT = core.getInput('msbuild-architecture');
|
||||
let MSBUILD_ARCH = MSBUILD_ARCH_INPUT;
|
||||
// The minimum Visual Studio/MSBuild major version that ships a native x64 MSBuild.exe
|
||||
exports.MIN_VS_VERSION_FOR_X64 = 17;
|
||||
// Determines the effective MSBuild architecture to use.
|
||||
// If the user explicitly specified `msbuild-architecture`, that choice is always respected.
|
||||
// Otherwise (breaking change as of v4), the action auto-detects and prefers x64 when
|
||||
// running on a 64-bit OS and the resolved VS/MSBuild installation is version 17.0 or later.
|
||||
// If the VS version can't be determined, or the host isn't 64-bit, it falls back to x86.
|
||||
function resolveMSBuildArchitecture(explicitArch, isWindows64Bit, vsMajorVersion) {
|
||||
if (explicitArch) {
|
||||
return explicitArch;
|
||||
}
|
||||
if (isWindows64Bit &&
|
||||
vsMajorVersion !== undefined &&
|
||||
vsMajorVersion >= exports.MIN_VS_VERSION_FOR_X64) {
|
||||
return 'x64';
|
||||
}
|
||||
return 'x86';
|
||||
}
|
||||
exports.resolveMSBuildArchitecture = resolveMSBuildArchitecture;
|
||||
// Parses the major version number out of a vswhere `installationVersion` string
|
||||
// such as "17.9.34728.123". Returns undefined if it cannot be parsed.
|
||||
function parseMajorVersion(installationVersion) {
|
||||
const match = installationVersion.trim().match(/^(\d+)/);
|
||||
if (!match) {
|
||||
return undefined;
|
||||
}
|
||||
const major = parseInt(match[1], 10);
|
||||
return isNaN(major) ? undefined : major;
|
||||
}
|
||||
exports.parseMajorVersion = parseMajorVersion;
|
||||
let MSBUILD_ARCH = core.getInput('msbuild-architecture') || 'x86';
|
||||
// if a specific version of VS is requested
|
||||
let VSWHERE_EXEC = '-products * -requires Microsoft.Component.MSBuild -property installationPath -latest ';
|
||||
if (ALLOW_PRERELEASE === 'true') {
|
||||
@@ -107,27 +75,6 @@ function run() {
|
||||
return;
|
||||
}
|
||||
core.debug(`Full tool exe: ${vswhereToolExe}`);
|
||||
// if the user did not explicitly specify an architecture, auto-detect the
|
||||
// preferred architecture based on the host OS and the resolved VS/MSBuild version
|
||||
if (!MSBUILD_ARCH_INPUT) {
|
||||
let vsMajorVersion;
|
||||
const versionOptions = {};
|
||||
versionOptions.listeners = {
|
||||
stdout: (data) => {
|
||||
const installationVersion = data.toString().trim();
|
||||
core.debug(`Found installation version: ${installationVersion}`);
|
||||
const parsed = parseMajorVersion(installationVersion);
|
||||
if (parsed !== undefined) {
|
||||
vsMajorVersion = parsed;
|
||||
}
|
||||
}
|
||||
};
|
||||
const versionExec = VSWHERE_EXEC.replace('-property installationPath', '-property installationVersion');
|
||||
yield exec.exec(`"${vswhereToolExe}" ${versionExec}`, [], versionOptions);
|
||||
const isWindows64Bit = os.arch() === 'x64' || os.arch() === 'arm64';
|
||||
MSBUILD_ARCH = resolveMSBuildArchitecture(MSBUILD_ARCH_INPUT, isWindows64Bit, vsMajorVersion);
|
||||
core.info(`Auto-detected msbuild-architecture: ${MSBUILD_ARCH} (os.arch=${os.arch()}, vsMajorVersion=${vsMajorVersion})`);
|
||||
}
|
||||
let foundToolPath = '';
|
||||
const options = {};
|
||||
options.listeners = {
|
||||
@@ -167,30 +114,13 @@ function run() {
|
||||
core.setFailed('Unable to find MSBuild.');
|
||||
return;
|
||||
}
|
||||
core.info(`Found MSBuild tool path: ${foundToolPath}`);
|
||||
core.info(`Using MSBuild architecture: ${MSBUILD_ARCH}`);
|
||||
// try to get the MSBuild version for diagnostic purposes; a failure here shouldn't fail the action
|
||||
try {
|
||||
let msbuildVersion = '';
|
||||
const versionOptions = {};
|
||||
versionOptions.listeners = {
|
||||
stdout: (data) => {
|
||||
msbuildVersion += data.toString();
|
||||
}
|
||||
};
|
||||
yield exec.exec(`"${foundToolPath}" -version -nologo`, [], versionOptions);
|
||||
core.info(`Found MSBuild version: ${msbuildVersion.trim()}`);
|
||||
}
|
||||
catch (error) {
|
||||
core.debug(`Unable to determine MSBuild version: ${error.message}`);
|
||||
}
|
||||
// extract the folder location for the tool
|
||||
const toolFolderPath = path.dirname(foundToolPath);
|
||||
// set the outputs for the action to the folder path of msbuild
|
||||
core.setOutput('msbuildPath', toolFolderPath);
|
||||
// add tool path to PATH
|
||||
core.addPath(toolFolderPath);
|
||||
core.info(`Tool path added to PATH: ${toolFolderPath}`);
|
||||
core.debug(`Tool path added to PATH: ${toolFolderPath}`);
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
|
||||
Generated
+7
-6
@@ -1292,10 +1292,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"version": "1.1.18",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
|
||||
"integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -9237,9 +9238,9 @@
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"version": "1.1.18",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
|
||||
"integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "setup-msbuild",
|
||||
"version": "4.0.0",
|
||||
"version": "3.0.0",
|
||||
"private": true,
|
||||
"description": "Helps set up specific MSBuild tool into PATH for later usage.",
|
||||
"main": "lib/main.js",
|
||||
|
||||
+5
-100
@@ -1,7 +1,6 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import * as fs from 'fs'
|
||||
import * as os from 'os'
|
||||
import * as path from 'path'
|
||||
import * as io from '@actions/io'
|
||||
import {ExecOptions} from '@actions/exec/lib/interfaces'
|
||||
@@ -10,56 +9,13 @@ const IS_WINDOWS = process.platform === 'win32'
|
||||
const VS_VERSION = core.getInput('vs-version') || 'latest'
|
||||
const VSWHERE_PATH = core.getInput('vswhere-path')
|
||||
const ALLOW_PRERELEASE = core.getInput('vs-prerelease') || 'false'
|
||||
const MSBUILD_ARCH_INPUT = core.getInput('msbuild-architecture')
|
||||
let MSBUILD_ARCH = MSBUILD_ARCH_INPUT
|
||||
|
||||
// The minimum Visual Studio/MSBuild major version that ships a native x64 MSBuild.exe
|
||||
export const MIN_VS_VERSION_FOR_X64 = 17
|
||||
|
||||
// Determines the effective MSBuild architecture to use.
|
||||
// If the user explicitly specified `msbuild-architecture`, that choice is always respected.
|
||||
// Otherwise (breaking change as of v4), the action auto-detects and prefers x64 when
|
||||
// running on a 64-bit OS and the resolved VS/MSBuild installation is version 17.0 or later.
|
||||
// If the VS version can't be determined, or the host isn't 64-bit, it falls back to x86.
|
||||
export function resolveMSBuildArchitecture(
|
||||
explicitArch: string,
|
||||
isWindows64Bit: boolean,
|
||||
vsMajorVersion: number | undefined
|
||||
): string {
|
||||
if (explicitArch) {
|
||||
return explicitArch
|
||||
}
|
||||
|
||||
if (
|
||||
isWindows64Bit &&
|
||||
vsMajorVersion !== undefined &&
|
||||
vsMajorVersion >= MIN_VS_VERSION_FOR_X64
|
||||
) {
|
||||
return 'x64'
|
||||
}
|
||||
|
||||
return 'x86'
|
||||
}
|
||||
|
||||
// Parses the major version number out of a vswhere `installationVersion` string
|
||||
// such as "17.9.34728.123". Returns undefined if it cannot be parsed.
|
||||
export function parseMajorVersion(
|
||||
installationVersion: string
|
||||
): number | undefined {
|
||||
const match = installationVersion.trim().match(/^(\d+)/)
|
||||
if (!match) {
|
||||
return undefined
|
||||
}
|
||||
const major = parseInt(match[1], 10)
|
||||
return isNaN(major) ? undefined : major
|
||||
}
|
||||
let MSBUILD_ARCH = core.getInput('msbuild-architecture') || 'x86'
|
||||
|
||||
// if a specific version of VS is requested
|
||||
let VSWHERE_EXEC =
|
||||
'-products * -requires Microsoft.Component.MSBuild -property installationPath -latest '
|
||||
let VSWHERE_EXEC = '-products * -requires Microsoft.Component.MSBuild -property installationPath -latest '
|
||||
if (ALLOW_PRERELEASE === 'true') {
|
||||
VSWHERE_EXEC += ' -prerelease '
|
||||
}
|
||||
VSWHERE_EXEC += ' -prerelease '
|
||||
}
|
||||
|
||||
if (VS_VERSION !== 'latest') {
|
||||
VSWHERE_EXEC += `-version "${VS_VERSION}" `
|
||||
@@ -108,39 +64,6 @@ async function run(): Promise<void> {
|
||||
|
||||
core.debug(`Full tool exe: ${vswhereToolExe}`)
|
||||
|
||||
// if the user did not explicitly specify an architecture, auto-detect the
|
||||
// preferred architecture based on the host OS and the resolved VS/MSBuild version
|
||||
if (!MSBUILD_ARCH_INPUT) {
|
||||
let vsMajorVersion: number | undefined
|
||||
const versionOptions: ExecOptions = {}
|
||||
versionOptions.listeners = {
|
||||
stdout: (data: Buffer) => {
|
||||
const installationVersion = data.toString().trim()
|
||||
core.debug(`Found installation version: ${installationVersion}`)
|
||||
const parsed = parseMajorVersion(installationVersion)
|
||||
if (parsed !== undefined) {
|
||||
vsMajorVersion = parsed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const versionExec = VSWHERE_EXEC.replace(
|
||||
'-property installationPath',
|
||||
'-property installationVersion'
|
||||
)
|
||||
await exec.exec(`"${vswhereToolExe}" ${versionExec}`, [], versionOptions)
|
||||
|
||||
const isWindows64Bit = os.arch() === 'x64' || os.arch() === 'arm64'
|
||||
MSBUILD_ARCH = resolveMSBuildArchitecture(
|
||||
MSBUILD_ARCH_INPUT,
|
||||
isWindows64Bit,
|
||||
vsMajorVersion
|
||||
)
|
||||
core.info(
|
||||
`Auto-detected msbuild-architecture: ${MSBUILD_ARCH} (os.arch=${os.arch()}, vsMajorVersion=${vsMajorVersion})`
|
||||
)
|
||||
}
|
||||
|
||||
let foundToolPath = ''
|
||||
const options: ExecOptions = {}
|
||||
options.listeners = {
|
||||
@@ -195,24 +118,6 @@ async function run(): Promise<void> {
|
||||
return
|
||||
}
|
||||
|
||||
core.info(`Found MSBuild tool path: ${foundToolPath}`)
|
||||
core.info(`Using MSBuild architecture: ${MSBUILD_ARCH}`)
|
||||
|
||||
// try to get the MSBuild version for diagnostic purposes; a failure here shouldn't fail the action
|
||||
try {
|
||||
let msbuildVersion = ''
|
||||
const versionOptions: ExecOptions = {}
|
||||
versionOptions.listeners = {
|
||||
stdout: (data: Buffer) => {
|
||||
msbuildVersion += data.toString()
|
||||
}
|
||||
}
|
||||
await exec.exec(`"${foundToolPath}" -version -nologo`, [], versionOptions)
|
||||
core.info(`Found MSBuild version: ${msbuildVersion.trim()}`)
|
||||
} catch (error) {
|
||||
core.debug(`Unable to determine MSBuild version: ${error.message}`)
|
||||
}
|
||||
|
||||
// extract the folder location for the tool
|
||||
const toolFolderPath = path.dirname(foundToolPath)
|
||||
|
||||
@@ -221,7 +126,7 @@ async function run(): Promise<void> {
|
||||
|
||||
// add tool path to PATH
|
||||
core.addPath(toolFolderPath)
|
||||
core.info(`Tool path added to PATH: ${toolFolderPath}`)
|
||||
core.debug(`Tool path added to PATH: ${toolFolderPath}`)
|
||||
} catch (error) {
|
||||
core.setFailed(error.message)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user