Private/Packager/Write-S3PackageArtifact.ps1
function Write-S3PackageArtifact { <# .PARAMETER CredentialArguments Credential arguments passed to public function. .OUTPUTS [bool] $True if a file was uploaded; else $false .NOTES MD5 hash is compared with S3 object ETag value. This works for files up to 5GB, but then nobody would upload a 5GB lambda! #> param ( [string]$Path, [string]$Bucket, [string]$Key, [hashtable]$CredentialArguments, [hashtable]$Metadata, [string]$KmsKeyId, [switch]$Force ) function Get-MD5Hash { param ( [string]$Path ) if ($null -ne (Get-Command -Name Get-FileHash -ErrorAction SilentlyContinue)) { return (Get-FileHash -Path $Path -Algorithm MD5).Hash } [System.IO.Stream] $file = $null; [System.Security.Cryptography.MD5] $md5 = $null; try { $md5 = [System.Security.Cryptography.MD5]::Create() $file = [System.IO.File]::OpenRead($filePath) return [System.BitConverter]::ToString($md5.ComputeHash($file)).Replace('-', [string]::Empty) } finally { ($file, $md5) | Where-Object { $null -ne $_ } | ForEach-Object { $_.Dispose() } } } # AWS quotes the ETag (MD5 hash value) $hash = '"' + (Get-MD5Hash $Path) + '"' # To support localstack testing, we have to fudge EndpointURL if present $s3Arguments = Update-EndpointValue -CredentialArguments $CredentialArguments -Service S3 if (-not $Force) { try { $s3Object = Get-S3Object -BucketName $Bucket -Key $Key @s3Arguments if ($null -ne $s3Object -and $s3Object.ETag -ieq $hash) { # Hashes match - nothing to do return $false } } catch { # Not found or some other error - proceed to upload } } # Upload the file if (-not (Get-S3Bucket -BucketName $Bucket)) { Write-Verbose "Creating bucket: $Bucket" New-S3Bucket -BucketName $Bucket @s3Arguments } $additionalArguments = @{} if ($Metadata -and $Metadata.Keys.Length -gt 0) { $additionalArguments.Add('Metadata', $Metadata) } if (-not [string]::IsNullOrEmpty($KmsKeyId)) { $additionalArguments.Add('ServerSideEncryptionKeyManagementServiceKeyId ', $KmsKeyId) } Write-S3Object -BucketName $Bucket -Key $Key -File $Path @s3Arguments @additionalArguments | Out-Null return $true } |