Skip to content

Create release scripts + generate PDB for RowsetImportEngine.dll #398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
189 changes: 189 additions & 0 deletions ReleaseProcess/FinalRelease.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
param (
[string]$ReleasePath
)



# Check if the script is being run with the correct number of parameters
if ($PSBoundParameters.Count -ne 1) {
Write-Host "Usage: .\FinalRelease.ps1 -InitialPath <path_to_root_folder>" -ForegroundColor Red
exit 1
}

# Check if the current user is an administrator
$principal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "The script must be run as an administrator. Please restart PowerShell with elevated permissions."
exit 1
}

# Validate the destination root folder
if (-not (Test-Path -Path $ReleasePath)) {
Write-Host "The provided initial path does not exist: '$ReleasePath'" -ForegroundColor Red
exit 1
}

$SignedFilesToCopy = @(
"\SQLNexus\Bin\Release\BulkLoadEx.dll",
"\SQLNexus\Bin\Release\LinuxPerfImporter.dll",
"\SQLNexus\Bin\Release\NexusInterfaces.dll",
"\SQLNexus\Bin\Release\PerfmonImporter.dll",
"\SQLNexus\Bin\Release\ReadTraceNexusImporter.dll",
"\SQLNexus\Bin\Release\RowsetImportEngine.dll",
"\SQLNexus\Bin\Release\sqlnexus.exe"
)

# Define the paths to the folders
$filesToSignFolder = Join-Path -Path $ReleasePath -ChildPath "FilesToSign"
$signedFilesFolder = Join-Path -Path $ReleasePath -ChildPath "SignedFiles"
$releaseSignedPrepFolder = Join-Path -Path $ReleasePath -ChildPath "Release_Signed_Prep"
$releaseSignedFolder = Join-Path -Path $ReleasePath -ChildPath "Release_Signed"
$releaseUnsignedFolder = Join-Path -Path $ReleasePath -ChildPath "Release_Unsigned"

Write-Host "Release Signed Prep Folder: $releaseSignedPrepFolder"

# Validate the existence of all three folders in a single check
if (-not (Test-Path -Path $filesToSignFolder) -or
-not (Test-Path -Path $signedFilesFolder) -or
-not (Test-Path -Path $releaseSignedPrepFolder)) {
Write-Host "One or more required folders do not exist. Please ensure that '\FilesToSign', '\SignedFiles', and '\Release_Signed_Prep' folders are present." -ForegroundColor Red
exit 1
}

# Get the list of files in each folder
$filesToSign = Get-ChildItem -Path $filesToSignFolder -File
$signedFiles = Get-ChildItem -Path $signedFilesFolder -File


# Compare the number of files
if (($filesToSign.Count) -ne ($signedFiles.Count)) {
Write-Host "The number of files in '\FilesToSign' ($($filesToSign.Count)) and '\SignedFiles' ($($signedFiles.Count))) folders do not match." -ForegroundColor Red
}
else {
Write-Host "The number of files in '\FilesToSign' ($($filesToSign.Count)) and '\SignedFiles' ($($signedFiles.Count)) folders match."
}

# Compare the signed files and filestosign filenames
$filesToSignNames = $filesToSign.Name
$signedFilesNames = $signedFiles.Name
$missingFiles = $filesToSignNames | Where-Object { $_ -notin $signedFilesNames }
if ($missingFiles.Count -gt 0) {
Write-Host "The following file(s) are missing in the '\SignedFiles' folder: `r`n $($missingFiles -join "`r`n ")" -ForegroundColor Red
exit 1
}

# Validate that the files in SignedFiles are digitally signed
$invalidCount = 0
foreach ($file in $signedFiles) {
$signature = Get-AuthenticodeSignature $file.FullName
if ($signature.Status -ne 'Valid') {
Write-Host "The file '$($file.FullName)' is not properly signed. Status: $($signature.StatusMessage)" -ForegroundColor Red
$invalidCount++
}
}

# Check if any files were found to be invalidly signed and exit with an error if so
if ($invalidCount -gt 0) {
Write-Host "$invalidCount file(s) in the '\SignedFiles' folder are not properly signed. Exiting."
exit 1
}
else {
Write-Host "All files in the '\SignedFiles' folder are properly signed." -ForegroundColor Green
}

# Validate that there are no extra files in Release_Signed_Prep that are not in SignedFilesToCopy and vice versa

# Get files in Release_Signed_Prep folder and filter to files that are to be overwritten with signed counterparts
# Extract just the filenames from SignedFilesToCopy
$SignedFileNamesToCopy = $SignedFilesToCopy | ForEach-Object { Split-Path -Path $_ -Leaf }

# Use the extracted filenames in the Where-Object filter
$releaseSignedPrepFiles = Get-ChildItem -Path $releaseSignedPrepFolder -Recurse -File | Where-Object { $_.Name -in $SignedFileNamesToCopy }


# Check if there are any files in Release_Signed_Prep folder
if ($releaseSignedPrepFiles.Count -eq 0) {
Write-Host "No files found in the '\Release_Signed_Prep' folder. Please ensure that the folder contains the expected signed files." -ForegroundColor Red
exit 1
}

# Get the full file names from Release_Signed_Prep folder and remove the folder path to get just the relative file names for comparison
$releaseSignedPrepFileNames = $releaseSignedPrepFiles.FullName | ForEach-Object { $_.Substring($releaseSignedPrepFolder.Length) }

$releaseSignedPrepFileNames

# Check for files in Release_Signed_Prep that are not in SignedFilesToCopy
$missingSignedFilesToCopy = $releaseSignedPrepFileNames | Where-Object { $_ -notin $SignedFilesToCopy }

# Check for files in SignedFilesToCopy array that are not in Release_Signed_Prep
$missingReleaseSignedPrepFiles = $SignedFilesToCopy | Where-Object {$_ -notin $releaseSignedPrepFileNames}

# If there are any missing files in either direction, report them and exit with an error
# This ensures that the files in SignedFilesToCopy are present in Release_Signed_Prep and vice versa

if ($missingSignedFilesToCopy.Count -gt 0 -or $missingReleaseSignedPrepFiles.Count -gt 0) {
if ($missingSignedFilesToCopy.Count -gt 0) {
Write-Host "Files missing in SignedFilesToCopy array:`r`n $($missingSignedFilesToCopy -join "`r`n ")" -ForegroundColor Red
}
if ($missingReleaseSignedPrepFiles.Count -gt 0) {
Write-Host "Files missing in Release_Signed_Prep directory:`r`n $($missingReleaseSignedPrepFiles -join "`r`n ")" -ForegroundColor Red
}
exit 1
}

# Validate that each file in SignedFilesToCopy exists in Release_Signed_Prep with matching subdirectory structure
$copiedFilesCount = 0

foreach ($file in $SignedFilesToCopy) {
# Construct the full path to the source file in the SignedFiles folder.
# They are expected to be in the one flat folder structure, so we just need to join the signedFilesFolder with the file name only.
$sourceFile = Join-Path -Path $signedFilesFolder -ChildPath $file.Split("\")[-1]

# Check if it exists in the Release_Signed_Prep folder with the subdirectory structure coming from $SignedFilesToCopy
# Use TrimStart to remove the leading backslash from the file path to avoid issues with Join-Path

if (-not (Test-Path -Path (Join-Path -Path $releaseSignedPrepFolder -ChildPath $file.TrimStart("\"))))
{
# If the file does not exist in the Release_Signed_Prep folder, report an error and exit
Write-Host "The file '$sourceFile' does not exist in the '\Release_Signed_Prep' folder with matching subdirectory structure." -ForegroundColor Red
exit 1
}
else
{
# Copy the file to the Release_Signed_Prep folder, preserving the subdirectory structure
$destinationFile = Join-Path -Path $releaseSignedPrepFolder -ChildPath $file.TrimStart("\")
Copy-Item -Path $sourceFile -Destination $destinationFile -Force -ErrorAction Stop

$copiedFilesCount++
# Output the copied file information
Write-Host "Copied '$sourceFile' to '$destinationFile'"
}
}

# Output the total number of copied files and expected to copy files
Write-Host "Total of $($SignedFilesToCopy.Count) file(s) expected to be copied from SignedFilesToCopy array"
Write-Host "Total of $copiedFilesCount file(s) actually copied to '$releaseSignedPrepFolder' "



# Final step: Rename the Release_Signed_Prep folder to Release_Signed
if (Test-Path -Path $releaseSignedFolder) {
Write-Host "The destination folder '$releaseSignedFolder' already exists. Please remove or rename it before running the script." -ForegroundColor Red
exit 1
}
try {
$seconds_to_wait = 15
Write-Host "Waiting $seconds_to_wait seconds for files to be processed by Anti-Virus and OneDrive sync..."
Start-Sleep -Seconds $seconds_to_wait
Rename-Item -Path $releaseSignedPrepFolder -NewName $releaseSignedFolder -ErrorAction Stop
} catch {
Write-Host "Failed to rename '$releaseSignedPrepFolder' to '$releaseSignedFolder'. Error: $_" -ForegroundColor Red
}

#check if the folder rename was successful
if (Test-Path -Path $releaseSignedFolder) {
Write-Host "The folder '$releaseSignedFolder' was successfully renamed from '$releaseSignedPrepFolder' and is ready for release."
} else {
Write-Host "The folder '$releaseSignedFolder' was not found after renaming. Please check the rename operation." -ForegroundColor Red
}
# End of script
225 changes: 225 additions & 0 deletions ReleaseProcess/PrepareFilesForSigning.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
param (
[string]$DestinationRootFolder
)


try {

# Define the source binary files to be signed
$SourceFiles = @(
"BulkLoadEx.dll",
"LinuxPerfImporter.dll",
"NexusInterfaces.dll",
"PerfmonImporter.dll",
"ReadTraceNexusImporter.dll",
"RowsetImportEngine.dll",
"sqlnexus.exe"
)

# Define an exclusion list for files and folders that should not be included in the project directory
$ExcludeFilesUnsignedArray = @(
"PrepareFilesForSigning.ps1",
"FinalRelease.ps1",
"azuredevops-pipelines.yml",
".gitignore"

)

# Define an exclusion list for the Signed_Prep folder, which includes all files in $ExcludeFilesUnsigned and additional files
$ExcludeFilesSignedArray = $ExcludeFilesUnsignedArray + @(
"BulkLoadEx.pdb",
"LinuxPerfImporter.pdb",
"Microsoft.Data.SqlClient.SNI.arm64.pdb",
"Microsoft.Data.SqlClient.SNI.x64.pdb",
"Microsoft.Data.SqlClient.SNI.x86.pdb",
"NexusInterfaces.pdb",
"PerfmonImporter.pdb",
"ReadTraceNexusImporter.pdb",
"RowsetImportEngine.pdb",
"sqlnexus.pdb"
)

# exclude these folders from the project directory
$ExcludeFoldersUnsignedArr = @(
".vscode"
)

$ExcludeFoldersSignedArr = $ExcludeFoldersUnsignedArr + @(
"app.publish"
)
# Go to the root solution directory
$Nexus_RootDir = (Get-Item (Get-Location)).Parent.FullName

# Validate the destination root folder
if (-not (Test-Path -Path $DestinationRootFolder)) {
Write-Error "The provided destination root folder path does not exist: '$DestinationRootFolder'"
exit 1
}

Write-Host "Before folder creation: $(Get-Date)"

# Create required folders
$ReleaseUnsignedFolder = Join-Path -Path $DestinationRootFolder -ChildPath "Release_Unsigned"
$FilesToSignFolder = Join-Path -Path $DestinationRootFolder -ChildPath "FilesToSign"
$SignedFilesFolder = Join-Path -Path $DestinationRootFolder -ChildPath "SignedFiles"
$ReleaseSignedFolder = Join-Path -Path $DestinationRootFolder -ChildPath "Release_Signed_Prep"

New-Item -ItemType Directory -Path $ReleaseUnsignedFolder -Force
New-Item -ItemType Directory -Path $FilesToSignFolder -Force
New-Item -ItemType Directory -Path $SignedFilesFolder -Force
New-Item -ItemType Directory -Path $ReleaseSignedFolder -Force


Write-Host "Before Get-ChildItem: $(Get-Date)"

# Get all project folders excluding the specified folders
$projectFilesUnsigned = @()
$projectFilesSigned = @()


# Get all items in the SQLNexus \Bin\Release directory
$releaseBinaries = $Nexus_RootDir + "\SQLNexus\Bin\Release"
$allItems = Get-ChildItem -Path $releaseBinaries -Recurse

# Loop through each item and exclude folders and their contents, as well as specific files
foreach ($item in $allItems) {

# filter out folders and files that are in the unsigned ExcludeFolders and ExcludeFiles arrays
# and add them to the projectFilesUnsigned array
$excludeUnSig = $false
foreach ($excludeFolder in $ExcludeFoldersUnsignedArr) {
if ($item.FullName -like "*$excludeFolder*") {
$excludeUnSig = $true
break
}
}
foreach ($excludeFile in $ExcludeFilesUnsignedArray) {
if ($item.Name -eq $excludeFile) {
$excludeUnSig = $true
break
}
}
if (-not $excludeUnSig) {
$projectFilesUnsigned += $item
}


# filter out folders and files that are in the signed ExcludeFolders and ExcludeFiles arrays
# and add them to the projectFilesSigned array
$excludeSig = $false
foreach ($excludeFolder in $ExcludeFoldersSignedArr) {
if ($item.FullName -like "*$excludeFolder*") {
$excludeSig = $true
break
}
}
foreach ($excludeFile in $ExcludeFilesSignedArray) {
if ($item.Name -eq $excludeFile) {
$excludeSig = $true
break
}
}
if (-not $excludeSig) {
$projectFilesSigned += $item
}
}

# Get only the name of the binaries from the SQLNexus project
# Filter project files to include only those in the SourceFiles array
$nexusProjectBinFiles = $projectFilesUnsigned | Where-Object { $_.Name -in $SourceFiles }
$projectFilesName = $nexusProjectBinFiles.Name


# Check for files that are in the SourceFiles array but not in the project directory
# and files that are in the project directory but not in the SourceFiles array
$missingInSourceFiles = $projectFilesName | Where-Object { $_ -notin $SourceFiles }
$missingInProjectFiles = $SourceFiles | Where-Object { -not (Test-Path (Join-Path -Path $releaseBinaries -ChildPath $_)) }

if ($missingInSourceFiles -or $missingInProjectFiles) {
if ($missingInSourceFiles) {
Write-Host "Files missing in SourceFiles array:`r`n $($missingInSourceFiles -join "`r`n ")" -ForegroundColor Red
}
if ($missingInProjectFiles) {
Write-Host "Files missing in project directory:`r`n $($missingInProjectFiles -join "`r`n ")" -ForegroundColor Red
}
exit 1
}



$beforeCopy = $(Get-Date)
Write-Host "Before Copy-Item in FilesToSign: $beforeCopy"

# Copy each of the SQLNexus project binaries that need signing to the FilesToSign folder
$nexusProjectBinFiles | ForEach-Object { Copy-Item -Path $_.FullName -Destination $FilesToSignFolder }

Write-Host "`r`nTotal files copied to the 'FilesToSign' folder: $($nexusProjectBinFiles.Count)"

Write-Host "`r`nStarting to copy files to the 'Release_Unsigned' folders..."
Write-Host "`----------------------------------------------------------------"

Write-Host "Before Copy-Item in Signed and Unsigned folders: $(Get-Date)"
$copiedFilesCount = 0
# Copy all files to the Release_Unsigned folder, preserving the folder structure
$projectFilesUnsigned | ForEach-Object {

# extract the relative path from the parent directory to the destination folder
# and create the corresponding destination path for Release_Signed_Prep and Release_Unsigned folders
$relativePath = $_.FullName.Substring($Nexus_RootDir.TrimEnd('\').Length + 1)
$destReleaseUnsignedPath = Join-Path -Path $ReleaseUnsignedFolder -ChildPath $relativePath

# copy to Release_Unsigned folder as well
Write-Host "Copying file: '$($_.FullName)' to '$destReleaseUnsignedPath'"
Copy-Item -Path $_.FullName -Destination $destReleaseUnsignedPath -Force

# Increment the copied files count for each file copied
$copiedFilesCount++
}

Write-Host "`r`nTotal files copied to the 'Release_Unsigned' folder': $copiedFilesCount"

Write-Host "`r`nStarting to copy files to the 'Release_Signed_Prep' folders..."
Write-Host "`----------------------------------------------------------------"

# reset the copied files count for the next copy operation
$copiedSignedFilesCount = 0

# Copy all files to the Release_Signed_Prep folder, preserving the folder structure
$projectFilesSigned | ForEach-Object {

# extract the relative path from the parent directory to the destination folder
# and create the corresponding destination path for Release_Signed_Prep and Release_Unsigned folders
$relativePath = $_.FullName.Substring($Nexus_RootDir.Length + 1)
$destReleaseSignedPrepPath = Join-Path -Path $ReleaseSignedFolder -ChildPath $relativePath

# copy to Release_Signed_Prep folder, preserving the folder structure
Write-Host "Copying file: '$($_.FullName)' to '$destReleaseSignedPrepPath'"
Copy-Item -Path $_.FullName -Destination $destReleaseSignedPrepPath -Force

# Increment the copied files count for each file copied
$copiedSignedFilesCount++
}

Write-Host "`r`nTotal files copied to the 'Release_Signed_Prep' folder: $copiedFilesCount"


Write-Host "After Copy-Item: $(Get-Date). It took $((New-TimeSpan -Start $beforeCopy -End (Get-Date)).TotalSeconds) seconds to copy files."
Write-Host "`r`nList of files in the '$FilesToSignFolder' folder:"
Get-ChildItem -Path $FilesToSignFolder | Select-Object -Property Name, LastWriteTime, @{Name="LengthKB";Expression={[math]::Round($_.Length / 1KB, 2)}} | Format-Table -AutoSize

}
catch {
Write-Host "An error occurred: $($_.Exception.Message)" -ForegroundColor Red
Write-Host "Script line number: $($_.InvocationInfo.ScriptLineNumber)" -ForegroundColor Red

exit 1
}
finally {
Write-Host "`nSummary:"
Write-Host "=========="
Write-Host "Total files from source folder: $($allItems.Count)"
Write-Host "Total files copied to 'FilesToSign': $($nexusProjectBinFiles.Count)"
Write-Host "Total files copied to 'Release_Unsigned': $copiedFilesCount"
Write-Host "Total files copied to 'Release_Signed': $copiedSignedFilesCount"
Write-Host "`r`nScript execution completed."
}
4 changes: 2 additions & 2 deletions RowsetImportEngine/RowsetImportEngine.csproj
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@
<DefineConstants>TRACE</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>false</DebugSymbols>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
@@ -93,7 +93,7 @@
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>none</DebugType>
<DebugType>pdbonly</DebugType>
<ErrorReport>prompt</ErrorReport>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>