2021-06-24 16:36:04 -05:00
#!/usr/bin/env bash
2023-04-24 16:23:43 +02:00
### Usage: $0 [options]
###
### Options:
### --clean-while-building Cleans each repo after building (reduces disk space usage)
### --online Build using online sources
### --poison Build with poisoning checks
### --run-smoke-test Don't build; run smoke tests
### --source-repository <URL> Source Link repository URL, required when building from tarball
### --source-version <SHA> Source Link revision, required when building from tarball
### --release-manifest <FILE> A JSON file, an alternative source of Source Link metadata
### --use-mono-runtime Output uses the mono runtime
### --with-packages <DIR> Use the specified directory of previously-built packages
### --with-sdk <DIR> Use the SDK in the specified directory for bootstrapping
###
### Use -- to send the remaining arguments to MSBuild
2021-06-24 16:36:04 -05:00
set -euo pipefail
IFS = $'\n\t'
2023-04-24 16:23:43 +02:00
source = " ${ BASH_SOURCE [0] } "
2021-06-24 16:36:04 -05:00
SCRIPT_ROOT = " $( cd -P " $( dirname " $0 " ) " && pwd ) "
2023-04-24 16:23:43 +02:00
function print_help ( ) {
sed -n '/^### /,/^$/p' " $source " | cut -b 5-
}
2022-10-18 09:31:59 -05:00
MSBUILD_ARGUMENTS = ( "-flp:v=detailed" )
2022-09-08 14:23:06 -05:00
CUSTOM_PACKAGES_DIR = ''
2021-06-24 16:36:04 -05:00
alternateTarget = false
2022-09-08 14:23:06 -05:00
runningSmokeTests = false
2022-12-16 11:52:21 -06:00
packagesDir = " $SCRIPT_ROOT /prereqs/packages/ "
packagesArchiveDir = " ${ packagesDir } archive/ "
packagesRestoredDir = " ${ packagesDir } restored/ "
packagesPreviouslySourceBuiltDir = " ${ packagesDir } previously-source-built/ "
2021-06-24 16:36:04 -05:00
CUSTOM_SDK_DIR = ''
2023-04-24 16:23:43 +02:00
sourceRepository = ''
sourceVersion = ''
releaseManifest = ''
2021-06-24 16:36:04 -05:00
while :; do
2023-04-24 16:23:43 +02:00
if [ $# -le 0 ] ; then
break
fi
2021-06-24 16:36:04 -05:00
2023-04-24 16:23:43 +02:00
lowerI = " $( echo " $1 " | awk '{print tolower($0)}' ) "
case $lowerI in
--clean-while-building)
MSBUILD_ARGUMENTS += ( "-p:CleanWhileBuilding=true" )
; ;
--online)
MSBUILD_ARGUMENTS += ( "-p:BuildWithOnlineSources=true" )
; ;
--poison)
MSBUILD_ARGUMENTS += ( "-p:EnablePoison=true" )
; ;
--run-smoke-test)
alternateTarget = true
runningSmokeTests = true
MSBUILD_ARGUMENTS += ( "-t:RunSmokeTest" )
; ;
--source-repository)
sourceRepository = " $2 "
shift
; ;
--source-version)
sourceVersion = " $2 "
shift
; ;
--release-manifest)
releaseManifest = " $2 "
shift
; ;
--use-mono-runtime)
MSBUILD_ARGUMENTS += ( "/p:SourceBuildUseMonoRuntime=true" )
; ;
--with-packages)
CUSTOM_PACKAGES_DIR = " $( cd -P " $2 " && pwd ) "
if [ ! -d " $CUSTOM_PACKAGES_DIR " ] ; then
echo " Custom prviously built packages directory ' $CUSTOM_PACKAGES_DIR ' does not exist "
exit 1
fi
shift
; ;
--with-sdk)
CUSTOM_SDK_DIR = " $( cd -P " $2 " && pwd ) "
if [ ! -d " $CUSTOM_SDK_DIR " ] ; then
echo " Custom SDK directory ' $CUSTOM_SDK_DIR ' does not exist "
exit 1
fi
if [ ! -x " $CUSTOM_SDK_DIR /dotnet " ] ; then
echo " Custom SDK ' $CUSTOM_SDK_DIR /dotnet' does not exist or is not executable "
exit 1
fi
shift
; ;
--)
shift
echo " Detected '--': passing remaining parameters ' $@ ' as build.sh arguments. "
break
; ;
'-?' | -h| --help)
print_help
exit 0
; ;
*)
echo " Unrecognized argument ' $1 ' "
print_help
exit 1
; ;
esac
shift
2021-06-24 16:36:04 -05:00
done
2023-04-26 11:10:53 +02:00
# For build purposes, we need to make sure we have all the SourceLink information
if [ " $alternateTarget " != "true" ] ; then
GIT_DIR = " $SCRIPT_ROOT /.git "
if [ -f " $GIT_DIR /index " ] ; then # We check for index because if outside of git, we create config and HEAD manually
if [ -n " $sourceRepository " ] || [ -n " $sourceVersion " ] || [ -n " $releaseManifest " ] ; then
echo "ERROR: Source Link arguments cannot be used in a git repository"
2023-04-24 16:23:43 +02:00
exit 1
fi
else
2023-04-26 11:10:53 +02:00
if [ -z " $releaseManifest " ] ; then
if [ -z " $sourceRepository " ] || [ -z " $sourceVersion " ] ; then
echo " ERROR: $SCRIPT_ROOT is not a git repository, either --release-manifest or --source-repository and --source-version must be specified "
exit 1
fi
else
if [ -n " $sourceRepository " ] || [ -n " $sourceVersion " ] ; then
echo "ERROR: --release-manifest cannot be specified together with --source-repository and --source-version"
exit 1
fi
2023-04-24 16:23:43 +02:00
2023-04-26 11:10:53 +02:00
get_property( ) {
local json_file_path = " $1 "
local property_name = " $2 "
grep -oP '(?<="' $property_name '": ")[^"]*' " $json_file_path "
}
2023-04-24 16:23:43 +02:00
2023-04-26 11:10:53 +02:00
sourceRepository = $( get_property " $releaseManifest " sourceRepository) \
|| ( echo " ERROR: Failed to find sourceRepository in $releaseManifest " && exit 1)
sourceVersion = $( get_property " $releaseManifest " sourceVersion) \
|| ( echo " ERROR: Failed to find sourceVersion in $releaseManifest " && exit 1)
2023-04-24 16:23:43 +02:00
2023-04-26 11:10:53 +02:00
if [ -z " $sourceRepository " ] || [ -z " $sourceVersion " ] ; then
echo " ERROR: sourceRepository and sourceVersion must be specified in $releaseManifest "
exit 1
fi
2023-04-24 16:23:43 +02:00
fi
2023-04-26 11:10:53 +02:00
# We need to add "fake" .git/ files when not building from a git repository
mkdir -p " $GIT_DIR "
echo '[remote "origin"]' > " $GIT_DIR /config "
echo " url=\" $sourceRepository \" " >> " $GIT_DIR /config "
echo " $sourceVersion " > " $GIT_DIR /HEAD "
fi
2023-04-24 16:23:43 +02:00
fi
2022-09-08 14:23:06 -05:00
if [ " $CUSTOM_PACKAGES_DIR " != "" ] ; then
if [ " $runningSmokeTests " = = "true" ] ; then
2022-10-18 09:31:59 -05:00
MSBUILD_ARGUMENTS += ( " -p:CustomSourceBuiltPackagesPath= $CUSTOM_PACKAGES_DIR " )
2022-09-08 14:23:06 -05:00
else
2022-10-18 09:31:59 -05:00
MSBUILD_ARGUMENTS += ( " -p:CustomPrebuiltSourceBuiltPackagesPath= $CUSTOM_PACKAGES_DIR " )
2022-09-08 14:23:06 -05:00
fi
fi
2022-12-16 11:52:21 -06:00
if [ -f " ${ packagesArchiveDir } archiveArtifacts.txt " ] ; then
2021-06-24 16:36:04 -05:00
ARCHIVE_ERROR = 0
if [ ! -d " $SCRIPT_ROOT /.dotnet " ] && [ " $CUSTOM_SDK_DIR " = = "" ] ; then
2023-01-10 08:50:31 -06:00
echo " ERROR: SDK not found at ' $SCRIPT_ROOT /.dotnet'. Either run prep.sh to acquire one or specify one via the --with-sdk parameter. "
2021-06-24 16:36:04 -05:00
ARCHIVE_ERROR = 1
fi
2022-12-16 11:52:21 -06:00
if [ ! -f ${ packagesArchiveDir } Private.SourceBuilt.Artifacts*.tar.gz ] && [ " $CUSTOM_PACKAGES_DIR " = = "" ] ; then
2023-01-10 08:50:31 -06:00
echo " ERROR: Private.SourceBuilt.Artifacts artifact not found at ' $packagesArchiveDir '. Either run prep.sh to acquire it or specify one via the --with-packages parameter. "
2021-06-24 16:36:04 -05:00
ARCHIVE_ERROR = 1
fi
if [ $ARCHIVE_ERROR = = 1 ] ; then
exit 1
fi
fi
2023-04-03 18:55:55 +02:00
if [ ! -d " $SCRIPT_ROOT /.git " ] ; then
echo " ERROR: $SCRIPT_ROOT is not a git repository. Please run prep.sh add initialize Source Link metadata. "
exit 1
fi
2021-06-24 16:36:04 -05:00
if [ -d " $CUSTOM_SDK_DIR " ] ; then
2023-03-13 14:44:42 +01:00
export SDK_VERSION = $( " $CUSTOM_SDK_DIR /dotnet " --version)
2021-06-24 16:36:04 -05:00
export CLI_ROOT = " $CUSTOM_SDK_DIR "
export _InitializeDotNetCli = " $CLI_ROOT /dotnet "
export CustomDotNetSdkDir = " $CLI_ROOT "
echo " Using custom bootstrap SDK from ' $CLI_ROOT ', version ' $SDK_VERSION ' "
else
2023-03-13 14:44:42 +01:00
sdkLine = $( grep -m 1 'dotnet' " $SCRIPT_ROOT /global.json " )
2021-06-24 16:36:04 -05:00
sdkPattern = "\"dotnet\" *: *\"(.*)\""
if [ [ $sdkLine = ~ $sdkPattern ] ] ; then
export SDK_VERSION = ${ BASH_REMATCH [1] }
export CLI_ROOT = " $SCRIPT_ROOT /.dotnet "
fi
fi
packageVersionsPath = ''
2022-09-08 14:23:06 -05:00
if [ [ " $CUSTOM_PACKAGES_DIR " != "" && -f " $CUSTOM_PACKAGES_DIR /PackageVersions.props " ] ] ; then
packageVersionsPath = " $CUSTOM_PACKAGES_DIR /PackageVersions.props "
2022-12-16 11:52:21 -06:00
elif [ -d " $packagesArchiveDir " ] ; then
2023-03-13 14:44:42 +01:00
sourceBuiltArchive = $( find " $packagesArchiveDir " -maxdepth 1 -name 'Private.SourceBuilt.Artifacts*.tar.gz' )
2022-12-16 11:52:21 -06:00
if [ -f " ${ packagesPreviouslySourceBuiltDir } }PackageVersions.props " ] ; then
packageVersionsPath = ${ packagesPreviouslySourceBuiltDir } PackageVersions.props
2022-03-28 09:15:59 -07:00
elif [ -f " $sourceBuiltArchive " ] ; then
2021-06-24 16:36:04 -05:00
tar -xzf " $sourceBuiltArchive " -C /tmp PackageVersions.props
packageVersionsPath = /tmp/PackageVersions.props
fi
fi
if [ ! -f " $packageVersionsPath " ] ; then
echo "Cannot find PackagesVersions.props. Debugging info:"
2022-12-16 11:52:21 -06:00
echo " Attempted archive path: $packagesArchiveDir "
2022-09-08 14:23:06 -05:00
echo " Attempted custom PVP path: $CUSTOM_PACKAGES_DIR /PackageVersions.props "
2021-06-24 16:36:04 -05:00
exit 1
fi
2023-03-13 14:44:42 +01:00
arcadeSdkLine = $( grep -m 1 'MicrosoftDotNetArcadeSdkVersion' " $packageVersionsPath " )
2021-06-24 16:36:04 -05:00
versionPattern = "<MicrosoftDotNetArcadeSdkVersion>(.*)</MicrosoftDotNetArcadeSdkVersion>"
if [ [ $arcadeSdkLine = ~ $versionPattern ] ] ; then
export ARCADE_BOOTSTRAP_VERSION = ${ BASH_REMATCH [1] }
# Ensure that by default, the bootstrap version of the Arcade SDK is used. Source-build infra
2023-01-10 08:50:31 -06:00
# projects use bootstrap Arcade SDK, and would fail to find it in the build. The repo
2021-06-24 16:36:04 -05:00
# projects overwrite this so that they use the source-built Arcade SDK instad.
export SOURCE_BUILT_SDK_ID_ARCADE = Microsoft.DotNet.Arcade.Sdk
export SOURCE_BUILT_SDK_VERSION_ARCADE = $ARCADE_BOOTSTRAP_VERSION
2022-12-16 11:52:21 -06:00
export SOURCE_BUILT_SDK_DIR_ARCADE = $packagesRestoredDir /ArcadeBootstrapPackage/microsoft.dotnet.arcade.sdk/$ARCADE_BOOTSTRAP_VERSION
2021-06-24 16:36:04 -05:00
fi
2023-03-13 14:44:42 +01:00
sourceLinkLine = $( grep -m 1 'MicrosoftSourceLinkCommonVersion' " $packageVersionsPath " )
2021-06-24 16:36:04 -05:00
versionPattern = "<MicrosoftSourceLinkCommonVersion>(.*)</MicrosoftSourceLinkCommonVersion>"
if [ [ $sourceLinkLine = ~ $versionPattern ] ] ; then
export SOURCE_LINK_BOOTSTRAP_VERSION = ${ BASH_REMATCH [1] }
fi
echo " Found bootstrap SDK $SDK_VERSION , bootstrap Arcade $ARCADE_BOOTSTRAP_VERSION , bootstrap SourceLink $SOURCE_LINK_BOOTSTRAP_VERSION "
export DOTNET_CLI_TELEMETRY_OPTOUT = 1
2022-12-16 11:52:21 -06:00
export NUGET_PACKAGES = $packagesRestoredDir /
2021-06-24 16:36:04 -05:00
2021-12-14 17:29:29 -05:00
LogDateStamp = $( date +"%m%d%H%M%S" )
2022-10-18 09:31:59 -05:00
" $CLI_ROOT /dotnet " build-server shutdown
2021-06-24 16:36:04 -05:00
if [ " $alternateTarget " = = "true" ] ; then
2023-03-13 14:44:42 +01:00
" $CLI_ROOT /dotnet " msbuild " $SCRIPT_ROOT /build.proj " -bl:" $SCRIPT_ROOT /artifacts/log/Debug/BuildTests_ $LogDateStamp .binlog " -flp:" LogFile= $SCRIPT_ROOT /artifacts/logs/BuildTests_ $LogDateStamp .log " -clp:v= m ${ MSBUILD_ARGUMENTS [@] } " $@ "
2021-06-24 16:36:04 -05:00
else
2023-03-13 14:44:42 +01:00
" $CLI_ROOT /dotnet " msbuild " $SCRIPT_ROOT /eng/tools/init-build.proj " -bl:" $SCRIPT_ROOT /artifacts/log/Debug/BuildXPlatTasks_ $LogDateStamp .binlog " -flp:LogFile= " $SCRIPT_ROOT /artifacts/logs/BuildXPlatTasks_ $LogDateStamp .log " -t:PrepareOfflineLocalTools ${ MSBUILD_ARGUMENTS [@] } " $@ "
2022-10-18 09:31:59 -05:00
# kill off the MSBuild server so that on future invocations we pick up our custom SDK Resolver
" $CLI_ROOT /dotnet " build-server shutdown
2021-06-24 16:36:04 -05:00
2023-03-13 14:44:42 +01:00
" $CLI_ROOT /dotnet " msbuild " $SCRIPT_ROOT /build.proj " -bl:" $SCRIPT_ROOT /artifacts/log/Debug/Build_ $LogDateStamp .binlog " -flp:" LogFile= $SCRIPT_ROOT /artifacts/logs/Build_ $LogDateStamp .log " ${ MSBUILD_ARGUMENTS [@] } " $@ "
2021-06-24 16:36:04 -05:00
fi