diff --git a/eng/ci/build-core-tools-host-artifacts-windows.yml b/eng/ci/build-core-tools-host-artifacts-windows.yml index 7503fa499..cd369a7b9 100644 --- a/eng/ci/build-core-tools-host-artifacts-windows.yml +++ b/eng/ci/build-core-tools-host-artifacts-windows.yml @@ -1,89 +1,40 @@ -trigger: - branches: - include: - - feature/oop-host - paths: - include: - - ./host/src/** +pr: none -pr: +trigger: branches: include: - feature/oop-host paths: include: - - ./host/src/** + - /host/src/** resources: repositories: + - repository: 1es + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release - repository: eng type: git name: engineering ref: refs/tags/release -jobs: -- job: BuildCoreToolsHostWindows - displayName: '[Windows] Build CoreToolsHost' - pool: - vmImage: 'windows-latest' - - variables: +variables: - template: /ci/variables/cfs.yml@eng - templateContext: - outputParentDirectory: $(Build.ArtifactStagingDirectory) - outputs: - - output: pipelineArtifact - displayName: Publish CoreToolsHost packages - path: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows - artifact: _coreToolsHostPackagesWindows - - steps: - - pwsh: | - Import-Module "./pipelineUtilities.psm1" -Force - Install-Dotnet - displayName: 'Install .NET 9' - - task: DotnetCoreCLI@2 - displayName: Dotnet Publish (win-x64) - inputs: - command: publish - publishWebProjects: false - zipAfterPublish: false - arguments: -c Release -r win-x64 -o $(Build.SourcesDirectory)/pkg_output/windows/win-x64 - workingDirectory: $(Build.SourcesDirectory)/host/src/CoreToolsHost - - - task: DotnetCoreCLI@2 - displayName: Dotnet Publish (win-arm64) - inputs: - command: publish - publishWebProjects: false - zipAfterPublish: false - arguments: -c Release -r win-arm64 -o $(Build.SourcesDirectory)/pkg_output/windows/win-arm64 - workingDirectory: $(Build.SourcesDirectory)/host/src/CoreToolsHost - - - task: CopyFiles@2 - displayName: Copy files (win-x64) - inputs: - SourceFolder: $(Build.SourcesDirectory)/pkg_output/windows/win-x64 - # Publish output will include many other files. We only need func.exe & nethost.dll - Contents: | - func.exe - nethost.dll - TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows/win-x64 - - - task: CopyFiles@2 - displayName: Copy files (win-arm64) - inputs: - SourceFolder: $(Build.SourcesDirectory)/pkg_output/windows/win-arm64 - # Publish output will include many other files. We only need func.exe & nethost.dll - Contents: | - func.exe - nethost.dll - TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows/win-arm64 - - - task: PublishPipelineArtifact@1 - displayName: 'Publish CoreToolsHost packages artifact' - inputs: - targetPath: '$(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows' - artifact: 'drop-coretools-host-windows' - publishLocation: 'pipeline' \ No newline at end of file +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1es + parameters: + pool: + name: 1es-pool-azfunc + image: 1es-windows-2022 + os: windows + sdl: + codeql: + compiled: + enabled: true + runSourceLanguagesInSourceAnalysis: true + stages: + - stage: BuildCoreToolsHost + jobs: + - template: /eng/ci/templates/official/jobs/build-core-tools-host.yml@self \ No newline at end of file diff --git a/eng/ci/templates/official/jobs/build-core-tools-host.yml b/eng/ci/templates/official/jobs/build-core-tools-host.yml new file mode 100644 index 000000000..3ceb3bad9 --- /dev/null +++ b/eng/ci/templates/official/jobs/build-core-tools-host.yml @@ -0,0 +1,123 @@ +jobs: +- job: BuildCoreToolsHostWindows + displayName: '[Windows] Build CoreToolsHost' + pool: + name: 1es-pool-azfunc + image: 1es-windows-2022 + os: windows + + steps: + - task: UseDotNet@2 + inputs: + version: 9.x + includePreviewVersions: true + displayName: Install .NET 9 + - task: UseDotNet@2 + inputs: + version: 6.x + displayName: Install .NET 6 + + - task: DotnetCoreCLI@2 + displayName: Dotnet Publish (win-x64) + inputs: + command: publish + publishWebProjects: false + zipAfterPublish: false + arguments: -c Release -r win-x64 -o $(Build.SourcesDirectory)/pkg_output/windows/win-x64 --self-contained + workingDirectory: $(Build.SourcesDirectory)/host/src/CoreToolsHost + + - task: DotnetCoreCLI@2 + displayName: Dotnet Publish (win-arm64) + inputs: + command: publish + publishWebProjects: false + zipAfterPublish: false + arguments: -c Release -r win-arm64 -o $(Build.SourcesDirectory)/pkg_output/windows/win-arm64 --self-contained + workingDirectory: $(Build.SourcesDirectory)/host/src/CoreToolsHost + + - template: ci/sign-files.yml@eng + parameters: + displayName: 'Authenticode signing (dll) (win-arm64)' + folderPath: '$(Build.SourcesDirectory)/pkg_output/windows/win-arm64' + pattern: '*.dll, *.exe' + signType: inline + inlineOperation: | + [ + { + "KeyCode": "CP-230012", + "OperationCode": "SigntoolSign", + "Parameters": { + "OpusName": "Microsoft", + "OpusInfo": "http://www.microsoft.com", + "FileDigest": "/fd \"SHA256\"", + "PageHash": "/NPH", + "TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" + }, + "ToolName": "sign", + "ToolVersion": "1.0" + }, + { + "KeyCode": "CP-230012", + "OperationCode": "SigntoolVerify", + "Parameters": {}, + "ToolName": "sign", + "ToolVersion": "1.0" + } + ] + + - template: ci/sign-files.yml@eng + parameters: + displayName: 'Authenticode signing (dll) (win-x64)' + folderPath: '$(Build.SourcesDirectory)/pkg_output/windows/win-x64' + pattern: '*.dll, *.exe' + signType: inline + inlineOperation: | + [ + { + "KeyCode": "CP-230012", + "OperationCode": "SigntoolSign", + "Parameters": { + "OpusName": "Microsoft", + "OpusInfo": "http://www.microsoft.com", + "FileDigest": "/fd \"SHA256\"", + "PageHash": "/NPH", + "TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" + }, + "ToolName": "sign", + "ToolVersion": "1.0" + }, + { + "KeyCode": "CP-230012", + "OperationCode": "SigntoolVerify", + "Parameters": {}, + "ToolName": "sign", + "ToolVersion": "1.0" + } + ] + + - task: CopyFiles@2 + displayName: Copy files (win-x64) + inputs: + SourceFolder: $(Build.SourcesDirectory)/pkg_output/windows/win-x64 + # Publish output will include many other files. We only need func.exe & nethost.dll + Contents: | + func.exe + nethost.dll + TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows/win-x64 + + - task: CopyFiles@2 + displayName: Copy files (win-arm64) + inputs: + SourceFolder: $(Build.SourcesDirectory)/pkg_output/windows/win-arm64 + # Publish output will include many other files. We only need func.exe & nethost.dll + Contents: | + func.exe + nethost.dll + TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows/win-arm64 + + templateContext: + outputParentDirectory: $(Build.ArtifactStagingDirectory) + outputs: + - output: pipelineArtifact + path: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows + artifact: drop-coretools-host-windows \ No newline at end of file diff --git a/publish-scripts/chocolatey/buildNUPKG.py b/publish-scripts/chocolatey/buildNUPKG.py index 8d8f56bad..6589bd9bc 100644 --- a/publish-scripts/chocolatey/buildNUPKG.py +++ b/publish-scripts/chocolatey/buildNUPKG.py @@ -45,7 +45,7 @@ def preparePackage(): for arch in archList: fileName = f"Azure.Functions.Cli.win-{arch.lower()}.{constants.VERSION}.zip" - url = f'https://functionscdn.azureedge.net/public/{constants.VERSION}/{fileName}' + url = f'https://functionscdn.azureedge.net/public/4.0.{constants.CONSOLIDATED_BUILD_ID}/{fileName}' substitutionMapping[f"ZIPURL_{arch}"] = url # download the zip diff --git a/publish-scripts/driver.py b/publish-scripts/driver.py index d0516a65b..8590b4a51 100644 --- a/publish-scripts/driver.py +++ b/publish-scripts/driver.py @@ -12,11 +12,15 @@ def main(*args): packageNamePostfix = "" print(f"args: {args} {len(args)}") - if (len(args) >= 3): + if (len(args) >= 4): packageNamePostfix = "-" + args[2] constants.PACKAGENAME = constants.PACKAGENAME + packageNamePostfix print(f"constants.PACKAGENAME: {constants.PACKAGENAME}") + + constants.CONSOLIDATED_BUILD_ID = args[2] # New argument for consolidatedBuildId + print(f"Consolidated Build ID: {constants.CONSOLIDATED_BUILD_ID}") # Print the new argument + constants.VERSION = args[1] constants.DRIVERROOTDIR = os.path.dirname(os.path.abspath(__file__)) platformSystem = platform.system() diff --git a/src/Azure.Functions.ArtifactAssembler/ArtifactAssembler.cs b/src/Azure.Functions.ArtifactAssembler/ArtifactAssembler.cs index 74f222a8b..b510107ad 100644 --- a/src/Azure.Functions.ArtifactAssembler/ArtifactAssembler.cs +++ b/src/Azure.Functions.ArtifactAssembler/ArtifactAssembler.cs @@ -7,17 +7,6 @@ namespace Azure.Functions.ArtifactAssembler { internal sealed class ArtifactAssembler { - private const string StagingDirName = "staging"; - private const string InProc8DirectoryName = "in-proc8"; - private const string InProc6DirectoryName = "in-proc6"; - private const string CoreToolsHostDirectoryName = "host"; - private const string VisualStudioOutputArtifactDirectoryName = "coretools-visualstudio"; - private const string _InProcOutputArtifactNameSuffix = "_inproc"; - private const string _coreToolsProductVersionPattern = @"(\d+\.\d+\.\d+)$"; - private const string _artifactNameRegexPattern = @"^(.*?)(\d+\.\d+\.\d+)$"; - private const string OutOfProcDirectoryName = "default"; - private const string CliOutputArtifactDirectoryName = "coretools-cli"; - /// /// The artifacts for which we want to pack a custom host with it. /// This dictionary contains the artifact name and the corresponding runtime identifier value. @@ -30,7 +19,6 @@ internal sealed class ArtifactAssembler /// /// The artifacts for which we want to pack out-of-proc core tools with it (along with inproc6 and inproc8 directories). - /// This dictionary contains the artifact name and the corresponding runtime identifier value. /// private readonly string[] _cliArtifacts = { @@ -104,15 +92,15 @@ private async Task ExtractDownloadedArtifactsAsync() EnsureArtifactDirectoryExist(coreToolsHostArtifactDirPath); EnsureArtifactDirectoryExist(outOfProcArtifactDirPath); - _inProc6ExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(inProc6ArtifactDirPath, Path.Combine(_stagingDirectory, InProc6DirectoryName)); - _inProc8ExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(inProc8ArtifactDirPath, Path.Combine(_stagingDirectory, InProc8DirectoryName)); + _inProc6ExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(inProc6ArtifactDirPath, Path.Combine(_stagingDirectory, Constants.InProc6DirectoryName)); + _inProc8ExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(inProc8ArtifactDirPath, Path.Combine(_stagingDirectory, Constants.InProc8DirectoryName)); Directory.Delete(inProcArtifactDownloadDir, true); - _coreToolsHostExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(coreToolsHostArtifactDirPath, Path.Combine(_stagingDirectory, CoreToolsHostDirectoryName)); + _coreToolsHostExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(coreToolsHostArtifactDirPath, Path.Combine(_stagingDirectory, Constants.CoreToolsHostDirectoryName)); Directory.Delete(coreToolsHostArtifactDownloadDir, true); - _outOfProcExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(outOfProcArtifactDirPath, Path.Combine(_stagingDirectory, OutOfProcDirectoryName)); + _outOfProcExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(outOfProcArtifactDirPath, Path.Combine(_stagingDirectory, Constants.OutOfProcDirectoryName)); Directory.Delete(outOfProcArtifactDownloadDir, true); } @@ -126,7 +114,7 @@ private static void EnsureArtifactDirectoryExist(string directoryExist) private static string CreateStagingDirectory(string rootWorkingDirectory) { - var stagingDirectory = Path.Combine(rootWorkingDirectory, StagingDirName); + var stagingDirectory = Path.Combine(rootWorkingDirectory, Constants.StagingDirName); if (Directory.Exists(stagingDirectory)) { @@ -152,7 +140,7 @@ private static async Task MoveArtifactsToStagingDirectoryAndExtractIfNee // Example output: 4.0.6353 private static string GetCoreToolsProductVersion(string artifactDirectoryName) { - var match = Regex.Match(artifactDirectoryName, _coreToolsProductVersionPattern); + var match = Regex.Match(artifactDirectoryName, Constants.CoreToolsProductVersionPattern); if (match.Success) { return match.Value; @@ -165,7 +153,7 @@ private async Task CreateVisualStudioCoreToolsAsync() { Console.WriteLine("Starting to assemble Visual Studio Core Tools artifacts"); // Create a directory to store the assembled artifacts. - var customHostTargetArtifactDir = Path.Combine(_stagingDirectory, VisualStudioOutputArtifactDirectoryName); + var customHostTargetArtifactDir = Path.Combine(_stagingDirectory, Constants.VisualStudioOutputArtifactDirectoryName); Directory.CreateDirectory(customHostTargetArtifactDir); var packTasks = _customHostArtifacts.Keys.Select(async artifactName => @@ -179,17 +167,17 @@ private async Task CreateVisualStudioCoreToolsAsync() // Create a new directory to store the custom host with in-proc8 and in-proc6 files. var artifactDirName = Path.GetFileName(inProc8ArtifactDirPath); - var consolidatedArtifactDirName = $"{artifactName}{_InProcOutputArtifactNameSuffix}.{GetCoreToolsProductVersion(artifactDirName)}"; + var consolidatedArtifactDirName = $"{artifactName}{Constants.InProcOutputArtifactNameSuffix}.{GetCoreToolsProductVersion(artifactDirName)}"; var consolidatedArtifactDirPath = Path.Combine(customHostTargetArtifactDir, consolidatedArtifactDirName); Directory.CreateDirectory(consolidatedArtifactDirPath); // Copy in-proc8 files - var inProc8CopyTask = Task.Run(() => FileUtilities.CopyDirectory(inProc8ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, InProc8DirectoryName))); + var inProc8CopyTask = Task.Run(() => FileUtilities.CopyDirectory(inProc8ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc8DirectoryName))); // Copy in-proc6 files var inProc6ArtifactDirPath = Path.Combine(_inProc6ExtractedRootDir, artifactDirName); EnsureArtifactDirectoryExist(inProc6ArtifactDirPath); - var inProc6CopyTask = Task.Run(() => FileUtilities.CopyDirectory(inProc6ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, InProc6DirectoryName))); + var inProc6CopyTask = Task.Run(() => FileUtilities.CopyDirectory(inProc6ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc6DirectoryName))); // Copy core-tools-host files var rid = GetRuntimeIdentifierForArtifactName(artifactName); @@ -216,7 +204,7 @@ private async Task CreateCliCoreToolsAsync() Console.WriteLine("Starting to assemble CLI Core Tools artifacts"); // Create a directory to store the assembled artifacts. - var cliCoreToolsTargetArtifactDir = Path.Combine(_stagingDirectory, CliOutputArtifactDirectoryName); + var cliCoreToolsTargetArtifactDir = Path.Combine(_stagingDirectory, Constants.CliOutputArtifactDirectoryName); Directory.CreateDirectory(cliCoreToolsTargetArtifactDir); string outOfProcVersion = string.Empty, inProcVersion = string.Empty, @@ -248,6 +236,12 @@ private async Task CreateCliCoreToolsAsync() await Task.Run(() => FileUtilities.CopyDirectory(outOfProcArtifactDirPath, consolidatedArtifactDirPath)); Directory.Delete(outOfProcArtifactDirPath, true); + // If we are currently on the minified version of the artifacts, we do not want the inproc6/inproc8 subfolders + if (artifactName.Contains("min.win")) + { + continue; + } + // If we are running this for the first time, extract the directory path and out of proc version if (String.IsNullOrEmpty(inProc8ArtifactDirPath)) { @@ -266,7 +260,7 @@ private async Task CreateCliCoreToolsAsync() string newInProc8ArtifactDirPath = RenameInProcDirectory(inProc8ArtifactDirPath, outOfProcVersion); // Copy in-proc8 files and delete old directory - await Task.Run(() => FileUtilities.CopyDirectory(newInProc8ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, InProc8DirectoryName))); + await Task.Run(() => FileUtilities.CopyDirectory(newInProc8ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc8DirectoryName))); Directory.Delete(newInProc8ArtifactDirPath, true); // Rename inproc6 directory to have the same version as the out-of-proc artifact before copying @@ -276,7 +270,7 @@ private async Task CreateCliCoreToolsAsync() string newInProc6ArtifactDirPath = RenameInProcDirectory(inProc6ArtifactDirPath, outOfProcVersion); // Copy in-proc6 files and delete old directory - await Task.Run(() => FileUtilities.CopyDirectory(newInProc6ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, InProc6DirectoryName))); + await Task.Run(() => FileUtilities.CopyDirectory(newInProc6ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc6DirectoryName))); Directory.Delete(newInProc6ArtifactDirPath, true); } @@ -304,7 +298,7 @@ private async Task CreateCliCoreToolsAsync() private string RenameInProcDirectory(string oldArtifactDirPath, string newVersion) { - Match match = Regex.Match(oldArtifactDirPath, _artifactNameRegexPattern); + Match match = Regex.Match(oldArtifactDirPath, Constants.ArtifactNameRegexPattern); if (!match.Success) { diff --git a/src/Azure.Functions.ArtifactAssembler/CliArtifactZipper.cs b/src/Azure.Functions.ArtifactAssembler/CliArtifactZipper.cs new file mode 100644 index 000000000..f6ebe79f7 --- /dev/null +++ b/src/Azure.Functions.ArtifactAssembler/CliArtifactZipper.cs @@ -0,0 +1,79 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System.IO.Compression; + +namespace Azure.Functions.ArtifactAssembler +{ + internal sealed class CliArtifactZipper + { + private readonly string _rootWorkingDirectory; + public CliArtifactZipper(string rootWorkingDirectory) + { + _rootWorkingDirectory = rootWorkingDirectory; + } + + internal void ZipCliArtifacts() + { + string stagingDirectory = Path.Combine(_rootWorkingDirectory, Constants.StagingDirName, Constants.CliOutputArtifactDirectoryName); + + // Get all directories in the staging directory + var directories = Directory.EnumerateDirectories(stagingDirectory); + + foreach (var dir in directories) + { + // Create worker directory if it doesn't already exist + CreateWorkerDirectoryIfDoesNotExist(dir); + + // Define zip file path and name + string zipFileName = $"{new DirectoryInfo(dir).Name}.zip"; + string zipFilePath = Path.Combine(stagingDirectory, zipFileName); + + // Compress directory into zip file + ZipFile.CreateFromDirectory(dir, zipFilePath, CompressionLevel.Optimal, includeBaseDirectory: false); + Console.WriteLine($"Zipped: {dir} -> {zipFilePath}"); + + // Verify zip creation and delete original directory to free up space + if (File.Exists(zipFilePath)) + { + Console.WriteLine($"Successfully created zip: {zipFilePath}"); + Directory.Delete(dir, true); + Console.WriteLine($"Deleted original directory: {dir}"); + } + else + { + Console.WriteLine($"Failed to create zip for: {dir}"); + } + } + + Console.WriteLine("All directories zipped successfully!"); + } + + internal void CreateWorkerDirectoryIfDoesNotExist(string dir) + { + string workersPath = Path.Combine(dir, "workers"); + + // Ensure 'workers' directory exists + if (!Directory.Exists(workersPath)) + { + Directory.CreateDirectory(workersPath); + Console.WriteLine($"Created missing 'workers' directory in {dir}"); + } + else + { + Console.WriteLine($"'workers' directory already exists in {dir}"); + } + + // Add placeholder file if 'workers' directory is empty + if (Directory.GetFiles(workersPath).Length == 0 && Directory.GetDirectories(workersPath).Length == 0) + { + File.WriteAllText(Path.Combine(workersPath, "placeholder.txt"), "Placeholder file"); + Console.WriteLine($"Created placeholder file in empty 'workers' directory in {dir}"); + } + else + { + Console.WriteLine($"'workers' directory is not empty in {dir}"); + } + } + } +} diff --git a/src/Azure.Functions.ArtifactAssembler/Constants.cs b/src/Azure.Functions.ArtifactAssembler/Constants.cs new file mode 100644 index 000000000..484e1f236 --- /dev/null +++ b/src/Azure.Functions.ArtifactAssembler/Constants.cs @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Azure.Functions.ArtifactAssembler +{ + internal static class Constants + { + internal const string StagingDirName = "staging"; + internal const string InProc8DirectoryName = "in-proc8"; + internal const string InProc6DirectoryName = "in-proc6"; + internal const string CoreToolsHostDirectoryName = "host"; + internal const string VisualStudioOutputArtifactDirectoryName = "coretools-visualstudio"; + internal const string InProcOutputArtifactNameSuffix = "_inproc"; + internal const string CoreToolsProductVersionPattern = @"(\d+\.\d+\.\d+)$"; + internal const string ArtifactNameRegexPattern = @"^(.*?)(\d+\.\d+\.\d+)$"; + internal const string OutOfProcDirectoryName = "default"; + internal const string CliOutputArtifactDirectoryName = "coretools-cli"; + } +} diff --git a/src/Azure.Functions.ArtifactAssembler/PipelineHelpers/generateMetadataFile.ps1 b/src/Azure.Functions.ArtifactAssembler/PipelineHelpers/generateMetadataFile.ps1 new file mode 100644 index 000000000..a43a28964 --- /dev/null +++ b/src/Azure.Functions.ArtifactAssembler/PipelineHelpers/generateMetadataFile.ps1 @@ -0,0 +1,41 @@ +param ( + [string]$StagingDirectory +) + +# Define paths using the provided StagingDirectory +$stagingCoreToolsCli = Join-Path $StagingDirectory "coretools-cli" +$stagingCoreToolsVisualStudio = Join-Path $StagingDirectory "coretools-visualstudio" + +# Get OOP Artifact Version +$oopVersion = (Get-ChildItem $stagingCoreToolsCli | Where-Object { $_.Name -match "^Azure\.Functions\.Cli\..*\.(\d+\.\d+\.\d+)$" } | Select-Object -First 1).Name -replace "^Azure\.Functions\.Cli\..*\.(\d+\.\d+\.\d+)$", '$1' + +# Get inProc Artifact Version +$inProcVersion = (Get-ChildItem $stagingCoreToolsVisualStudio -Filter "*.zip" | Where-Object { $_.Name -match "^Azure\.Functions\.Cli\.min\.win.*\.(\d+\.\d+\.\d+)\.zip$" } | Select-Object -First 1).Name -replace "^Azure\.Functions\.Cli\.min\.win.*\.(\d+\.\d+\.\d+)\.zip$", '$1' + +# Get the current release number from ADO +$releaseNumberFull = $env:RELEASE_RELEASENAME +$releaseNumber = ($releaseNumberFull -replace '\D', '') + +# Get commit id +$commitId = $env:BUILD_SOURCEVERSION + +# Create the JSON file +$metadata = @{ + defaultArtifactVersion = $oopVersion + inProcArtifactVersion = $inProcVersion + consolidatedBuildId = $releaseNumber + commitId = $commitId +} + +# Set the output path for the JSON file in the StagingDirectory +$jsonOutputPath = Join-Path $StagingDirectory "metadata.json" + +# Convert to JSON and save to file +$metadata | ConvertTo-Json | Set-Content -Path $jsonOutputPath + +Write-Host "Metadata file generated successfully at $jsonOutputPath" + +# Read and print the JSON content +$jsonContent = Get-Content -Path $jsonOutputPath +Write-Host "Contents of metadata.json:" +Write-Host $jsonContent \ No newline at end of file diff --git a/src/Azure.Functions.ArtifactAssembler/PipelineHelpers/zipCliArtifacts.ps1 b/src/Azure.Functions.ArtifactAssembler/PipelineHelpers/zipCliArtifacts.ps1 deleted file mode 100644 index 6f595fec5..000000000 --- a/src/Azure.Functions.ArtifactAssembler/PipelineHelpers/zipCliArtifacts.ps1 +++ /dev/null @@ -1,39 +0,0 @@ -param ( - [string]$StagingDirectory -) - -function GenerateSha([string]$filePath,[string]$artifactsPath, [string]$shaFileName) -{ - $sha = (Get-FileHash $filePath).Hash.ToLower() - $shaPath = Join-Path $artifactsPath "$shaFileName.sha2" - Out-File -InputObject $sha -Encoding ascii -FilePath $shaPath -NoNewline - Write-Host "Generated sha for $filePath at $shaFileName" -} - -# Get all directories in the staging directory -$directories = Get-ChildItem -Path $StagingDirectory -Directory - -# Iterate over each directory and create a zip file for each one -foreach ($dir in $directories) { - # Define the zip file name (same as directory name, but with .zip extension) - $zipFileName = "$($dir.Name).zip" - $zipFile = "$StagingDirectory\$zipFileName" - - # Compress the directory into the zip file - Compress-Archive -Path $dir.FullName -DestinationPath $zipFile -Force - - # Check if the zip file was successfully created - if (Test-Path -Path $zipFile) { - Write-Host "Zipped: $($dir.FullName) -> $zipFile" - - # Delete the original directory to free up space - Remove-Item -Path $dir.FullName -Recurse -Force - Write-Host "Deleted: $($dir.FullName) to free up space" - } else { - Write-Host "Failed to create zip for: $($dir.FullName)" - } - - GenerateSha $zipFile $StagingDirectory "$zipFileName.sha2" -} - -Write-Host "All directories zipped successfully!" \ No newline at end of file diff --git a/src/Azure.Functions.ArtifactAssembler/Program.cs b/src/Azure.Functions.ArtifactAssembler/Program.cs index aa8821895..9b51ceddc 100644 --- a/src/Azure.Functions.ArtifactAssembler/Program.cs +++ b/src/Azure.Functions.ArtifactAssembler/Program.cs @@ -10,8 +10,18 @@ static async Task Main(string[] args) try { var currentWorkingDirectory = Environment.CurrentDirectory; - var artifactAssembler = new ArtifactAssembler(currentWorkingDirectory); - await artifactAssembler.AssembleArtifactsAsync(); + + // Check if an argument for zipping is passed + if (args.Length > 0 && args[0].Equals("zip", StringComparison.OrdinalIgnoreCase)) + { + var zipCliArtifacts = new CliArtifactZipper(currentWorkingDirectory); + zipCliArtifacts.ZipCliArtifacts(); + } + else + { + var artifactAssembler = new ArtifactAssembler(currentWorkingDirectory); + await artifactAssembler.AssembleArtifactsAsync(); + } return 0; } diff --git a/src/Azure.Functions.Cli/npm/lib/install.js b/src/Azure.Functions.Cli/npm/lib/install.js index a99f3ecbf..7e8405950 100644 --- a/src/Azure.Functions.Cli/npm/lib/install.js +++ b/src/Azure.Functions.Cli/npm/lib/install.js @@ -5,6 +5,7 @@ const url = require('url'); const HttpsProxyAgent = require('https-proxy-agent'); const https = require('https'); const version = require('../package.json').version; +const consolidatedBuildId = "4.0." + require('../package.json').consolidatedBuildId; const chalk = require('chalk'); const path = require('path'); const fs = require('fs'); @@ -41,7 +42,7 @@ if (os.platform() === 'win32') { } const fileName = 'Azure.Functions.Cli.' + platform + '.' + version + '.zip'; -const endpoint = 'https://functionscdn.azureedge.net/public/' + version + '/' + fileName; +const endpoint = 'https://functionscdn.azureedge.net/public/' + consolidatedBuildId + '/' + fileName; console.log('attempting to GET %j', endpoint); const options = url.parse(endpoint); // npm config preceed system environment @@ -99,6 +100,7 @@ https.get(options, response => { fs.chmodSync(`${installPath}/func`, 0o755); fs.chmodSync(`${installPath}/gozip`, 0o755); fs.chmodSync(`${installPath}/in-proc8/func`, 0o755); + fs.chmodSync(`${installPath}/in-proc6/func`, 0o755); } }); }); diff --git a/src/Azure.Functions.Cli/npm/package.json b/src/Azure.Functions.Cli/npm/package.json index 48d27b2ba..72e7f7044 100644 --- a/src/Azure.Functions.Cli/npm/package.json +++ b/src/Azure.Functions.Cli/npm/package.json @@ -2,10 +2,11 @@ "name": "azure-functions-core-tools", "version": "3.0.2106", "description": "Azure Functions Core Tools", - "scripts": { - "postinstall": "node lib/install.js", - "prepublishOnly": "node lib/copy-metadata.js" - }, + "consolidatedBuildId": "123", + "scripts": { + "postinstall": "node lib/install.js", + "prepublishOnly": "node lib/copy-metadata.js" + }, "author": "Microsoft", "license": "MIT", "preferGlobal": true,