From 2fb0d51a83869312afcac9802fd9fa899b194b10 Mon Sep 17 00:00:00 2001 From: Dane Walton Date: Mon, 16 Nov 2020 11:05:23 -0800 Subject: [PATCH] Merge master into feature/iot_pnp (#1520) * Make sure we always log in as app or provisioner (#1480) This also adds previously-required parameters back into @PSBoundParameters to pass down to pre- and post-scripts. Co-authored-by: Heath Stewart * update changelog for beta 2 (#1484) * Sync eng/common directory with azure-sdk-tools for PR 1163 (#1483) * Update subscription configuration schema to include new parameters * Support platform specific arm template parameters and legacy hashtable format * Update arm template parameter comment to include top level key * Restore AdditionalParameters. Merge ArmTemplateParameters from stringified hash literal * Handle duplicate keys more explicitly for arm and env vars * Regenerate New-TestResources.ps1 markdown * revert variable name to environmentVariables to fix post-scripts * Handle empty arm template parameters better * Remove arm template parameter merge logic from deploy template * Add merge hashes function to New-TestResources.ps1 * Add merge hashes function to New-TestResources.ps1 * Add env variable overwrite warning. Use ContainsKey checks * Temporarily manually fix invalid generated markdown links Co-authored-by: Ben Broderick Phillips * Sync eng/common directory with azure-sdk-tools for PR 1178 (#1487) * Refactor eng/common/README.md * Add doc directory Co-authored-by: Chidozie Ononiwu * Fix broken eng/common doc link (#1489) Co-authored-by: Chidozie Ononiwu * Explicitly ignore return of _az_span_token on c2d parsing (#1482) (#1490) * add latest static analyzer fix to changelog (#1491) * Sync eng/common directory with azure-sdk-tools for PR 1188 (#1502) * Add debug flag to arm deployment command * Only set debug preference when $CI is true Co-authored-by: Ben Broderick Phillips * Remove invalid characters in basename sourced from username (#1503) Co-authored-by: Ben Broderick Phillips * Sync eng/common directory with azure-sdk-tools for PR 1170 (#1481) * Added the preprocess scripts. * string array to string Co-authored-by: Sima Zhu * Reorganization of samples readme (#1505) * Completion of Sample Readme update (#1508) * Add Invoke-DevOpsAPI.ps1, Add functions for Canceling and Listing Builds (#1474) Co-authored-by: Chidozie Ononiwu * Change live test resource DeleteAfterHours tag to 8 hours (#1509) Co-authored-by: Ben Broderick Phillips * adding notes about security on readme file (#1498) * adding notes about security on readme file * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Mollie Munoz * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Ahson Khan * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Ahson Khan * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Mollie Munoz * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Ahson Khan * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Mollie Munoz * Update how_to_iot_hub_esp8266_nodemcu.md * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Eric Wolz * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Eric Wolz * Update sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md Co-authored-by: Eric Wolz Co-authored-by: Mollie Munoz Co-authored-by: Ahson Khan Co-authored-by: Eric Wolz * Sync eng/common directory with azure-sdk-tools for PR 1202 (#1510) * Add debugging link on resource deployment failures to log output * Update aka link for live test help docs. Use here string and empty throw. Co-authored-by: Ben Broderick Phillips * Sync eng/common directory with azure-sdk-tools for PR 1153 (#1513) * Improve Update-ChangeLog Logic * Updates to ChangeLog-Operations.ps1, copy-docs-to-blobstorage.ps1, Invoke-GitHubAPI.ps1 and Package-Properties.ps1 * More changeLog Logic Improvements * Update date parsing Co-authored-by: Chidozie Ononiwu * Revert "Places where we have const* arguments in source, optionally mark the value as const as well. (#1261)" (#1517) This reverts commit 57236783862b85660559478c37a7ac92a6b97472. * Update AddAzureSDKforC.cmake to reference the latest tagged release of the SDK (#1495) * Update AddAzureSDKforC.cmake to reference the latest release of the SDK * Remove pnp from the tag being referenced. * Incrementing master CL and version to be above the next release from the feature branch (#1506) * Update LanguageSetting.ps1 (#1518) Co-authored-by: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com> Co-authored-by: Heath Stewart Co-authored-by: Ben Broderick Phillips Co-authored-by: Chidozie Ononiwu Co-authored-by: ewertons Co-authored-by: Sima Zhu Co-authored-by: Mollie Munoz Co-authored-by: Wellington Duraes Co-authored-by: Ahson Khan Co-authored-by: Eric Wolz Co-authored-by: Chidozie Ononiwu <31145988+chidozieononiwu@users.noreply.github.com> --- CHANGELOG.md | 14 +- cmake-modules/AddAzureSDKforC.cmake | 2 +- .../TestResources/New-TestResources.ps1 | 22 +- .../TestResources/deploy-test-resources.yml | 2 +- eng/common/scripts/ChangeLog-Operations.ps1 | 117 +++++++- eng/common/scripts/Get-PullRequestCreator.ps1 | 8 +- eng/common/scripts/Invoke-DevOpsAPI.ps1 | 92 ++++++ eng/common/scripts/Invoke-GitHubAPI.ps1 | 200 ++++--------- eng/common/scripts/Package-Properties.ps1 | 10 +- eng/common/scripts/Queue-Pipeline.ps1 | 36 ++- eng/common/scripts/SemVer.ps1 | 9 +- eng/common/scripts/Submit-PullRequest.ps1 | 8 +- eng/common/scripts/Update-ChangeLog.ps1 | 119 ++++++++ eng/common/scripts/Verify-Links.ps1 | 1 + .../get-markdown-files-from-changed-files.ps1 | 49 +++ eng/scripts/Language-Settings.ps1 | 10 +- sdk/inc/azure/core/az_version.h | 4 +- sdk/samples/iot/README.md | 280 +++++++++++++++++- .../docs/how_to_iot_hub_esp8266_nodemcu.md | 14 +- sdk/src/azure/core/az_context.c | 12 +- sdk/src/azure/core/az_http_policy_logging.c | 10 +- sdk/src/azure/core/az_http_request.c | 12 +- sdk/src/azure/core/az_http_response.c | 2 +- sdk/src/azure/core/az_json_reader.c | 4 +- sdk/src/azure/core/az_json_token.c | 24 +- sdk/src/azure/core/az_json_writer.c | 11 +- sdk/src/azure/iot/az_iot_hub_client.c | 6 +- sdk/src/azure/iot/az_iot_hub_client_c2d.c | 2 +- sdk/src/azure/iot/az_iot_hub_client_methods.c | 4 +- sdk/src/azure/iot/az_iot_hub_client_sas.c | 4 +- .../azure/iot/az_iot_hub_client_telemetry.c | 4 +- sdk/src/azure/iot/az_iot_hub_client_twin.c | 6 +- .../azure/iot/az_iot_provisioning_client.c | 12 +- .../iot/az_iot_provisioning_client_sas.c | 4 +- sdk/src/azure/platform/az_curl.c | 19 +- sdk/src/azure/platform/az_nohttp.c | 2 +- 36 files changed, 863 insertions(+), 272 deletions(-) create mode 100644 eng/common/scripts/Invoke-DevOpsAPI.ps1 create mode 100644 eng/common/scripts/Update-ChangeLog.ps1 create mode 100644 eng/common/scripts/get-markdown-files-from-changed-files.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 329e9ec277..511c26f760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,19 @@ # Release History -## 1.1.0-beta.3 (Unreleased) +## 1.1.0-beta.4 (Unreleased) +### New Features + + +### Bug Fixes + +- [[#1472]](https://github.com/Azure/azure-sdk-for-c/pull/1472) Fix `az_iot_message_properties_next()` when the buffer in which the properties were kept was bigger than the length of characters in the buffer. + +### Other Changes and Improvements + +- [[#1473]](https://github.com/Azure/azure-sdk-for-c/pull/1473) Add remove server certificate validation on paho and ESP8266 samples. +- [[#1449]](https://github.com/Azure/azure-sdk-for-c/pull/1449) Add basic reconnection capability for the ESP8266 sample. +- [[#1490]](https://github.com/Azure/azure-sdk-for-c/pull/1490) Fix static analyzer flagging of non-checked return value in `az_iot_hub_client_c2d_parse_received_topic()`. ## 1.1.0-beta.2 (2020-11-11) diff --git a/cmake-modules/AddAzureSDKforC.cmake b/cmake-modules/AddAzureSDKforC.cmake index e7809bd19d..d6ec493785 100644 --- a/cmake-modules/AddAzureSDKforC.cmake +++ b/cmake-modules/AddAzureSDKforC.cmake @@ -17,7 +17,7 @@ include(FetchContent) FetchContent_Declare(azuresdkforc GIT_REPOSITORY https://github.com/Azure/azure-sdk-for-c.git - GIT_TAG 1.1.0-beta.1) + GIT_TAG 1.1.0-beta.2) FetchContent_GetProperties(azuresdkforc) if(NOT azuresdkforc_POPULATED) FetchContent_Populate(azuresdkforc) diff --git a/eng/common/TestResources/New-TestResources.ps1 b/eng/common/TestResources/New-TestResources.ps1 index 4c03816c12..7af197ef9d 100644 --- a/eng/common/TestResources/New-TestResources.ps1 +++ b/eng/common/TestResources/New-TestResources.ps1 @@ -152,6 +152,8 @@ if (!$templateFiles) { } $UserName = if ($env:USER) { $env:USER } else { "${env:USERNAME}" } +# Remove spaces, etc. that may be in $UserName +$UserName = $UserName -replace '\W' # If no base name is specified use current user name if (!$BaseName) { @@ -308,7 +310,7 @@ if ($CI) { if ($EnvironmentVariables.ContainsKey('AZURE_RESOURCEGROUP_NAME') -and ` $EnvironmentVariables['AZURE_RESOURCEGROUP_NAME'] -ne $ResourceGroupName) { - Write-Warning ("Overwriting 'EnvironmentVariables.AZURE_RESOURCEGROUP_NAME' with value " + + Write-Warning ("Overwriting 'EnvironmentVariables.AZURE_RESOURCEGROUP_NAME' with value " + "'$($EnvironmentVariables['AZURE_RESOURCEGROUP_NAME'])' " + "to new value '$($ResourceGroupName)'") } $EnvironmentVariables['AZURE_RESOURCEGROUP_NAME'] = $ResourceGroupName @@ -385,7 +387,23 @@ foreach ($templateFile in $templateFiles) { Log "Deploying template '$templateFile' to resource group '$($resourceGroup.ResourceGroupName)'" $deployment = Retry { - New-AzResourceGroupDeployment -Name $BaseName -ResourceGroupName $resourceGroup.ResourceGroupName -TemplateFile $templateFile -TemplateParameterObject $templateFileParameters + $lastDebugPreference = $DebugPreference + try { + if ($CI) { + $DebugPreference = "Continue" + } + New-AzResourceGroupDeployment -Name $BaseName -ResourceGroupName $resourceGroup.ResourceGroupName -TemplateFile $templateFile -TemplateParameterObject $templateFileParameters + } catch { + Write-Output @" +================================================== +For help debugging live test provisioning issues, +see http://aka.ms/azsdk/engsys/live-test-help, +================================================== +"@ + throw + } finally { + $DebugPreference = $lastDebugPreference + } } if ($deployment.ProvisioningState -eq 'Succeeded') { diff --git a/eng/common/TestResources/deploy-test-resources.yml b/eng/common/TestResources/deploy-test-resources.yml index 031c4b37cc..a9d693b994 100644 --- a/eng/common/TestResources/deploy-test-resources.yml +++ b/eng/common/TestResources/deploy-test-resources.yml @@ -1,7 +1,7 @@ parameters: ServiceDirectory: not-set ArmTemplateParameters: '@{}' - DeleteAfterHours: 24 + DeleteAfterHours: 8 Location: '' SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources) diff --git a/eng/common/scripts/ChangeLog-Operations.ps1 b/eng/common/scripts/ChangeLog-Operations.ps1 index d644d02265..43dba5d74e 100644 --- a/eng/common/scripts/ChangeLog-Operations.ps1 +++ b/eng/common/scripts/ChangeLog-Operations.ps1 @@ -1,6 +1,10 @@ # Common Changelog Operations +. "${PSScriptRoot}\logging.ps1" +. "${PSScriptRoot}\SemVer.ps1" -$RELEASE_TITLE_REGEX = "(?^\#+.*(?\b\d+\.\d+\.\d+([^0-9\s][^\s:]+)?)(\s(?\(Unreleased\)|\(\d{4}-\d{2}-\d{2}\)))?)" +$RELEASE_TITLE_REGEX = "(?^\#+.*(?\b\d+\.\d+\.\d+([^0-9\s][^\s:]+)?)(\s+(?\(Unreleased\)|\(\d{4}-\d{2}-\d{2}\)))?)" +$CHANGELOG_UNRELEASED_STATUS = "(Unreleased)" +$CHANGELOG_DATE_FORMAT = "yyyy-MM-dd" # Returns a Collection of changeLogEntry object containing changelog info for all version present in the gived CHANGELOG function Get-ChangeLogEntries { @@ -11,7 +15,7 @@ function Get-ChangeLogEntries { $changeLogEntries = @{} if (!(Test-Path $ChangeLogLocation)) { - Write-Error "ChangeLog[${ChangeLogLocation}] does not exist" + LogError "ChangeLog[${ChangeLogLocation}] does not exist" return $null } @@ -23,9 +27,9 @@ function Get-ChangeLogEntries { if ($line -match $RELEASE_TITLE_REGEX) { $changeLogEntry = [pscustomobject]@{ ReleaseVersion = $matches["version"] - ReleaseStatus = $matches["releaseStatus"] - ReleaseTitle = $line - ReleaseContent = @() # Release content without the version title + ReleaseStatus = $matches["releaseStatus"] + ReleaseTitle = "## {0} {1}" -f $matches["version"], $matches["releaseStatus"] + ReleaseContent = @() } $changeLogEntries[$changeLogEntry.ReleaseVersion] = $changeLogEntry } @@ -72,6 +76,7 @@ function Get-ChangeLogEntryAsString { return ChangeLogEntryAsString $changeLogEntry } + function ChangeLogEntryAsString($changeLogEntry) { if (!$changeLogEntry) { return "[Missing change log entry]" @@ -93,7 +98,7 @@ function Confirm-ChangeLogEntry { $changeLogEntry = Get-ChangeLogEntry -ChangeLogLocation $ChangeLogLocation -VersionString $VersionString if (!$changeLogEntry) { - Write-Error "ChangeLog[${ChangeLogLocation}] does not have an entry for version ${VersionString}." + LogError "ChangeLog[${ChangeLogLocation}] does not have an entry for version ${VersionString}." return $false } @@ -103,28 +108,108 @@ function Confirm-ChangeLogEntry { Write-Host "-----" if ([System.String]::IsNullOrEmpty($changeLogEntry.ReleaseStatus)) { - Write-Error "Entry does not have a correct release status. Please ensure the status is set to a date '(yyyy-MM-dd)' or '(Unreleased)' if not yet released." + LogError "Entry does not have a correct release status. Please ensure the status is set to a date '($CHANGELOG_DATE_FORMAT)' or '$CHANGELOG_UNRELEASED_STATUS' if not yet released." return $false } if ($ForRelease -eq $True) { - if ($changeLogEntry.ReleaseStatus -eq "(Unreleased)") { - Write-Error "Entry has no release date set. Please ensure to set a release date with format 'yyyy-MM-dd'." + if ($changeLogEntry.ReleaseStatus -eq $CHANGELOG_UNRELEASED_STATUS) { + LogError "Entry has no release date set. Please ensure to set a release date with format '$CHANGELOG_DATE_FORMAT'." return $false } + else { + $status = $changeLogEntry.ReleaseStatus.Trim().Trim("()") + try { + [DateTime]$status + } + catch { + LogError "Invalid date [ $status ] passed as status for Version [$($changeLogEntry.ReleaseVersion)]." + return $false + } + } if ([System.String]::IsNullOrWhiteSpace($changeLogEntry.ReleaseContent)) { - Write-Error "Entry has no content. Please ensure to provide some content of what changed in this version." + LogError "Entry has no content. Please ensure to provide some content of what changed in this version." return $false } } return $true } -function Set-TestChangeLog($TestVersion, $changeLogFile, $ReleaseEntry) { - Set-Content -Path $changeLogFile -Value @" -# Release History -## $TestVersion ($(Get-Date -f "yyyy-MM-dd")) -- $ReleaseEntry -"@ +function New-ChangeLogEntry { + param ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [String]$Version, + [String]$Status=$CHANGELOG_UNRELEASED_STATUS, + [String[]]$Content + ) + + # Validate RelaseStatus + $Status = $Status.Trim().Trim("()") + if ($Status -ne "Unreleased") { + try { + $Status = ([DateTime]$Status).ToString($CHANGELOG_DATE_FORMAT) + } + catch { + LogWarning "Invalid date [ $Status ] passed as status for Version [$Version]. Please use a valid date in the format '$CHANGELOG_DATE_FORMAT' or use '$CHANGELOG_UNRELEASED_STATUS'" + return $null + } + } + $Status = "($Status)" + + # Validate Version + try { + $Version = ([AzureEngSemanticVersion]::ParseVersionString($Version)).ToString() + } + catch { + LogWarning "Invalid version [ $Version ]." + return $null + } + + if (!$Content) { $Content = @() } + + $newChangeLogEntry = [pscustomobject]@{ + ReleaseVersion = $Version + ReleaseStatus = $Status + ReleaseTitle = "## $Version $Status" + ReleaseContent = $Content + } + + return $newChangeLogEntry +} + +function Set-ChangeLogContent { + param ( + [Parameter(Mandatory = $true)] + [String]$ChangeLogLocation, + [Parameter(Mandatory = $true)] + $ChangeLogEntries + ) + + $changeLogContent = @() + $changeLogContent += "# Release History" + $changeLogContent += "" + + try + { + $VersionsSorted = [AzureEngSemanticVersion]::SortVersionStrings($ChangeLogEntries.Keys) + } + catch { + LogError "Problem sorting version in ChangeLogEntries" + return + } + + foreach ($version in $VersionsSorted) { + $changeLogEntry = $ChangeLogEntries[$version] + $changeLogContent += $changeLogEntry.ReleaseTitle + if ($changeLogEntry.ReleaseContent.Count -eq 0) { + $changeLogContent += @("","") + } + else { + $changeLogContent += $changeLogEntry.ReleaseContent + } + } + + Set-Content -Path $ChangeLogLocation -Value $changeLogContent } \ No newline at end of file diff --git a/eng/common/scripts/Get-PullRequestCreator.ps1 b/eng/common/scripts/Get-PullRequestCreator.ps1 index 1b531ad5ee..e9ed824c91 100644 --- a/eng/common/scripts/Get-PullRequestCreator.ps1 +++ b/eng/common/scripts/Get-PullRequestCreator.ps1 @@ -6,14 +6,18 @@ param ( [string]$RepoName, [Parameter(Mandatory = $true)] - $PullRequestNumber + $PullRequestNumber, + + [Parameter(Mandatory = $true)] + [string]$AuthToken ) . "${PSScriptRoot}\common.ps1" try { - $pullRequest = Get-GithubPullRequest -RepoOwner $RepoOwner -RepoName $RepoName -PullRequestNumber $PullRequestNumber + $pullRequest = Get-GithubPullRequest -RepoOwner $RepoOwner -RepoName $RepoName ` + -PullRequestNumber $PullRequestNumber -AuthToken $AuthToken Write-Host "##vso[task.setvariable variable=System.PullRequest.Creator;]$($pullRequest.user.login)" } catch diff --git a/eng/common/scripts/Invoke-DevOpsAPI.ps1 b/eng/common/scripts/Invoke-DevOpsAPI.ps1 new file mode 100644 index 0000000000..024594785a --- /dev/null +++ b/eng/common/scripts/Invoke-DevOpsAPI.ps1 @@ -0,0 +1,92 @@ +. "${PSScriptRoot}\logging.ps1" + +$DevOpsAPIBaseURI = "https://dev.azure.com/{0}/{1}/_apis/{2}/{3}?{4}api-version=6.0" + +function Get-DevOpsApiHeaders ($Base64EncodedToken) { + $headers = @{ + Authorization = "Basic $Base64EncodedToken" + } + return $headers +} + +function Start-DevOpsBuild { + param ( + $Organization="azure-sdk", + $Project="internal", + [Parameter(Mandatory = $true)] + $SourceBranch, + [Parameter(Mandatory = $true)] + $DefinitionId, + [ValidateNotNullOrEmpty()] + [Parameter(Mandatory = $true)] + $Base64EncodedAuthToken + ) + + $uri = "$DevOpsAPIBaseURI" -F $Organization, $Project , "build" , "builds", "" + + $parameters = @{ + sourceBranch = $SourceBranch + definition = @{ id = $DefinitionId } + } + + return Invoke-RestMethod ` + -Method POST ` + -Body ($parameters | ConvertTo-Json) ` + -Uri $uri ` + -Headers (Get-DevOpsApiHeaders -Base64EncodedToken $Base64EncodedAuthToken) ` + -MaximumRetryCount 3 ` + -ContentType "application/json" +} + +function Update-DevOpsBuild { + param ( + $Organization="azure-sdk", + $Project="internal", + [ValidateNotNullOrEmpty()] + [Parameter(Mandatory = $true)] + $BuildId, + $Status, # pass canceling to cancel build + [ValidateNotNullOrEmpty()] + [Parameter(Mandatory = $true)] + $Base64EncodedAuthToken + ) + + $uri = "$DevOpsAPIBaseURI" -F $Organization, $Project, "build", "builds/$BuildId", "" + $parameters = @{} + + if ($Status) { $parameters["status"] = $Status} + + return Invoke-RestMethod ` + -Method PATCH ` + -Body ($parameters | ConvertTo-Json) ` + -Uri $uri ` + -Headers (Get-DevOpsApiHeaders -Base64EncodedToken $Base64EncodedAuthToken) ` + -MaximumRetryCount 3 ` + -ContentType "application/json" +} + +function Get-DevOpsBuilds { + param ( + $Organization="azure-sdk", + $Project="internal", + $BranchName, #Should start with 'refs/heads/' + $Definitions, # Comma seperated string of definition IDs + $StatusFilter, # Comma seperated string 'cancelling, completed, inProgress, notStarted' + [ValidateNotNullOrEmpty()] + [Parameter(Mandatory = $true)] + $Base64EncodedAuthToken + ) + + $query = "" + + if ($BranchName) { $query += "branchName=$BranchName&" } + if ($Definitions) { $query += "definitions=$Definitions&" } + if ($StatusFilter) { $query += "statusFilter=$StatusFilter&" } + $uri = "$DevOpsAPIBaseURI" -F $Organization, $Project , "build" , "builds", $query + + return Invoke-RestMethod ` + -Method GET ` + -Uri $uri ` + -Headers (Get-DevOpsApiHeaders -Base64EncodedToken $Base64EncodedAuthToken) ` + -MaximumRetryCount 3 +} diff --git a/eng/common/scripts/Invoke-GitHubAPI.ps1 b/eng/common/scripts/Invoke-GitHubAPI.ps1 index b4a3d89715..46a76251c5 100644 --- a/eng/common/scripts/Invoke-GitHubAPI.ps1 +++ b/eng/common/scripts/Invoke-GitHubAPI.ps1 @@ -1,140 +1,14 @@ -if ((Get-ChildItem -Path Function: | ? { $_.Name -eq "LogWarning" }).Count -eq 0) { - . "${PSScriptRoot}\logging.ps1" -} +. "${PSScriptRoot}\logging.ps1" $GithubAPIBaseURI = "https://api.github.com/repos" -function Get-GitHubHeaders ($token) { +function Get-GitHubApiHeaders ($token) { $headers = @{ Authorization = "bearer $token" } return $headers } -function Invoke-GitHubAPIPost { - param ( - [Parameter(Mandatory = $true)] - $apiURI, - [Parameter(Mandatory = $true)] - $body, - [Parameter(Mandatory = $true)] - $token - ) - - try { - if ($body.Count -gt 0) { - $resp = Invoke-RestMethod ` - -Method POST ` - -Body ($body | ConvertTo-Json) ` - -Uri $apiURI ` - -Headers (Get-GitHubHeaders -token $token) ` - -MaximumRetryCount 3 - - return $resp - } - else { - $warning = "{0} with Uri [ $apiURI ] did not fire request because of empty body." -f (Get-PSCallStack)[1].FunctionName - LogWarning $warning - return $null - } - } - catch { - $warning = "{0} with Uri [ $apiURI ] failed. `nBody: [ {1} ]" -f (Get-PSCallStack)[1].FunctionName , ($body | Out-String) - LogWarning $warning - throw - } -} - -function Invoke-GitHubAPIPatch { - param ( - [Parameter(Mandatory = $true)] - $apiURI, - [Parameter(Mandatory = $true)] - $body, - [Parameter(Mandatory = $true)] - $token - ) - - try { - if ($body.Count -gt 0) { - $resp = Invoke-RestMethod ` - -Method PATCH ` - -Body ($body | ConvertTo-Json) ` - -Uri $apiURI ` - -Headers (Get-GitHubHeaders -token $token) ` - -MaximumRetryCount 3 - - return $resp - } - else { - $warning = "{0} with Uri [ $apiURI ] did not fire request because of empty body." -f (Get-PSCallStack)[1].FunctionName - LogWarning $warning - return $null - } - } - catch { - $warning = "{0} with Uri [ $apiURI ] failed. `nBody: [ {1} ]" -f (Get-PSCallStack)[1].FunctionName , ($body | Out-String) - LogWarning $warning - throw - } -} - -function Invoke-GitHubAPIDelete { - param ( - [Parameter(Mandatory = $true)] - $apiURI, - [Parameter(Mandatory = $true)] - $token - ) - - try { - $resp = Invoke-RestMethod ` - -Method DELETE ` - -Uri $apiURI ` - -Headers (Get-GitHubHeaders -token $token) ` - -MaximumRetryCount 3 - - return $resp - } - catch { - $warning = "{0} with Uri [ $apiURI ] failed." -f (Get-PSCallStack)[1].FunctionName - LogWarning $warning - throw - } -} - - -function Invoke-GitHubAPIGet { - param ( - [Parameter(Mandatory = $true)] - $apiURI, - $token - ) - - try { - if ($token) - { - $resp = Invoke-RestMethod ` - -Method GET ` - -Uri $apiURI ` - -Headers (Get-GitHubHeaders -token $token) ` - -MaximumRetryCount 3 - } - else { - $resp = Invoke-RestMethod ` - -Method GET ` - -Uri $apiURI ` - -MaximumRetryCount 3 - } - return $resp - } - catch { - $warning = "{0} with Uri [ $apiURI ] failed." -f (Get-PSCallStack)[1].FunctionName - LogWarning $warning - throw - } -} - function Set-GitHubAPIParameters ($members, $parameterName, $parameters, $allowEmptyMembers=$false) { if ($null -ne $members) { if ($members -is [array]) @@ -166,6 +40,7 @@ function Get-GitHubPullRequests { $Sort, [ValidateSet("asc","desc")] $Direction, + [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] $AuthToken ) @@ -178,7 +53,11 @@ function Get-GitHubPullRequests { if ($Sort) { $uri += "sort=$Sort&" } if ($Direction){ $uri += "direction=$Direction&" } - return Invoke-GitHubAPIGet -apiURI $uri -token $AuthToken + return Invoke-RestMethod ` + -Method GET ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } # @@ -195,13 +74,18 @@ function Get-GitHubSourceReferences { $RepoName, $Ref, [ValidateNotNullOrEmpty()] + [Parameter(Mandatory = $true)] $AuthToken ) $uri = "$GithubAPIBaseURI/$RepoOwner/$RepoName/git/matching-refs/" if ($Ref) { $uri += "$Ref" } - return Invoke-GitHubAPIGet -apiURI $uri -token $AuthToken + return Invoke-RestMethod ` + -Method GET ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } function Get-GitHubPullRequest { @@ -213,11 +97,17 @@ function Get-GitHubPullRequest { [Parameter(Mandatory = $true)] $PullRequestNumber, [ValidateNotNullOrEmpty()] + [Parameter(Mandatory = $true)] $AuthToken ) $uri = "$GithubAPIBaseURI/$RepoOwner/$RepoName/pulls/$PullRequestNumber" - return Invoke-GitHubAPIGet -apiURI $uri -token $AuthToken + + return Invoke-RestMethod ` + -Method GET ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } function New-GitHubPullRequest { @@ -250,7 +140,12 @@ function New-GitHubPullRequest { } $uri = "$GithubAPIBaseURI/$RepoOwner/$RepoName/pulls" - return Invoke-GitHubAPIPost -apiURI $uri -body $parameters -token $AuthToken + return Invoke-RestMethod ` + -Method POST ` + -Body ($parameters | ConvertTo-Json) ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } function Add-GitHubIssueComment { @@ -274,7 +169,12 @@ function Add-GitHubIssueComment { body = $Comment } - return Invoke-GitHubAPIPost -apiURI $uri -body $parameters -token $AuthToken + return Invoke-RestMethod ` + -Method POST ` + -Body ($parameters | ConvertTo-Json) ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } # Will add labels to existing labels on the issue @@ -305,7 +205,12 @@ function Add-GitHubIssueLabels { $parameters = Set-GitHubAPIParameters -members $Labels -parameterName "labels" ` -parameters $parameters - return Invoke-GitHubAPIPost -apiURI $uri -body $parameters -token $AuthToken + return Invoke-RestMethod ` + -Method POST ` + -Body ($parameters | ConvertTo-Json) ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } # Will add assignees to existing assignees on the issue @@ -336,7 +241,12 @@ function Add-GitHubIssueAssignees { $parameters = Set-GitHubAPIParameters -members $Assignees -parameterName "assignees" ` -parameters $parameters - return Invoke-GitHubAPIPost -apiURI $uri -body $parameters -token $AuthToken + return Invoke-RestMethod ` + -Method POST ` + -Body ($parameters | ConvertTo-Json) ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } function Add-GitHubPullRequestReviewers { @@ -363,7 +273,12 @@ function Add-GitHubPullRequestReviewers { $parameters = Set-GitHubAPIParameters -members $Teams -parameterName "team_reviewers" ` -parameters $parameters - return Invoke-GitHubAPIPost -apiURI $uri -body $parameters -token $AuthToken + return Invoke-RestMethod ` + -Method POST ` + -Body ($parameters | ConvertTo-Json) ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } # For labels and assignee pass comma delimited string, to replace existing labels or assignees. @@ -401,7 +316,12 @@ function Update-GitHubIssue { $parameters = Set-GitHubAPIParameters -members $Assignees -parameterName "assignees" ` -parameters $parameters -allowEmptyMembers $true - return Invoke-GitHubAPIPatch -apiURI $uri -body $parameters -token $AuthToken + return Invoke-RestMethod ` + -Method PATCH ` + -Body ($parameters | ConvertTo-Json) ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } function Remove-GitHubSourceReferences { @@ -425,5 +345,9 @@ function Remove-GitHubSourceReferences { $uri = "$GithubAPIBaseURI/$RepoOwner/$RepoName/git/refs/$Ref" - return Invoke-GitHubAPIDelete -apiURI $uri -token $AuthToken + return Invoke-RestMethod ` + -Method DELETE ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 } \ No newline at end of file diff --git a/eng/common/scripts/Package-Properties.ps1 b/eng/common/scripts/Package-Properties.ps1 index f17b244f3f..d75b897f28 100644 --- a/eng/common/scripts/Package-Properties.ps1 +++ b/eng/common/scripts/Package-Properties.ps1 @@ -1,4 +1,6 @@ # Helper functions for retireving useful information from azure-sdk-for-* repo +. "${PSScriptRoot}\logging.ps1" + class PackageProps { [string]$Name @@ -81,7 +83,7 @@ function Get-PkgProperties $serviceDirectoryPath = Join-Path $RepoRoot "sdk" $ServiceDirectory if (!(Test-Path $serviceDirectoryPath)) { - Write-Error "Service Directory $ServiceDirectory does not exist" + LogError "Service Directory $ServiceDirectory does not exist" exit 1 } @@ -97,7 +99,7 @@ function Get-PkgProperties } else { - Write-Error "The function '$GetPackageInfoFromRepoFn' was not found." + LogError "The function '$GetPackageInfoFromRepoFn' was not found." } if ($pkgProps -ne $null) @@ -105,7 +107,7 @@ function Get-PkgProperties return $pkgProps } } - Write-Error "Failed to retrive Properties for $PackageName" + LogError "Failed to retrive Properties for $PackageName" } # Takes ServiceName and Repo Root Directory @@ -175,7 +177,7 @@ function Get-PkgListFromYml ($ciYmlPath) } if ($artifactsInCI -eq $null) { - Write-Error "Failed to retrive package names in ci $ciYmlPath" + LogError "Failed to retrive package names in ci $ciYmlPath" } return $artifactsInCI } \ No newline at end of file diff --git a/eng/common/scripts/Queue-Pipeline.ps1 b/eng/common/scripts/Queue-Pipeline.ps1 index 4e0122ca92..d3c135e7ba 100644 --- a/eng/common/scripts/Queue-Pipeline.ps1 +++ b/eng/common/scripts/Queue-Pipeline.ps1 @@ -12,33 +12,45 @@ param( [Parameter(Mandatory = $true)] [int]$DefinitionId, + [boolean]$CancelPreviousBuilds=$false, + [Parameter(Mandatory = $false)] [string]$VsoQueuedPipelines, [Parameter(Mandatory = $true)] - [string]$AuthToken + [string]$Base64EncodedAuthToken ) . "${PSScriptRoot}\logging.ps1" +. "${PSScriptRoot}\Invoke-DevOpsAPI.ps1" -$headers = @{ - Authorization = "Basic $AuthToken" -} +if ($CancelPreviousBuilds) +{ + try { + $queuedBuilds = Get-DevOpsBuilds -BranchName "refs/heads/$SourceBranch" -Definitions $DefinitionId ` + -StatusFilter "inProgress, notStarted" -Base64EncodedAuthToken $Base64EncodedAuthToken -$apiUrl = "https://dev.azure.com/$Organization/$Project/_apis/build/builds?api-version=6.0" + if ($queuedBuilds.count -eq 0) { + LogDebug "There is no previous build still inprogress or about to start." + } -$body = @{ - sourceBranch = $SourceBranch - definition = @{ id = $DefinitionId } + foreach ($build in $queuedBuilds.Value) { + $buildID = $build.id + LogDebug "Canceling build [ $($build._links.web.href) ]" + Update-DevOpsBuild -BuildId $buildID -Status "cancelling" -Base64EncodedAuthToken $Base64EncodedAuthToken + } + } + catch { + LogError "Call to DevOps API failed with exception:`n$_" + exit 1 + } } -Write-Verbose ($body | ConvertTo-Json) - try { - $resp = Invoke-RestMethod -Method POST -Headers $headers $apiUrl -Body ($body | ConvertTo-Json) -ContentType application/json + $resp = Start-DevOpsBuild -SourceBranch $SourceBranch -DefinitionId $DefinitionId -Base64EncodedAuthToken $Base64EncodedAuthToken } catch { - LogError "Invoke-RestMethod [ $apiUrl ] failed with exception:`n$_" + LogError "Start-DevOpsBuild failed with exception:`n$_" exit 1 } diff --git a/eng/common/scripts/SemVer.ps1 b/eng/common/scripts/SemVer.ps1 index 0efdfae9cd..ab4eef3805 100644 --- a/eng/common/scripts/SemVer.ps1 +++ b/eng/common/scripts/SemVer.ps1 @@ -22,8 +22,10 @@ class AzureEngSemanticVersion { [string] $RawVersion [bool] $IsSemVerFormat [string] $DefaultPrereleaseLabel + # Regex inspired but simplified from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string static [string] $SEMVER_REGEX = "(?0|[1-9]\d*)\.(?0|[1-9]\d*)\.(?0|[1-9]\d*)(?:(?-?)(?[a-zA-Z-]*)(?\.?)(?0|[1-9]\d*))?" + static [string] $ParseLanguage = $Language static [AzureEngSemanticVersion] ParseVersionString([string] $versionString) { @@ -57,7 +59,12 @@ class AzureEngSemanticVersion { $this.Minor = [int]$matches.Minor $this.Patch = [int]$matches.Patch - $this.SetupDefaultConventions() + if ([AzureEngSemanticVersion]::ParseLanguage -eq "python") { + $this.SetupPythonConventions() + } + else { + $this.SetupDefaultConventions() + } if ($null -eq $matches['prelabel']) { diff --git a/eng/common/scripts/Submit-PullRequest.ps1 b/eng/common/scripts/Submit-PullRequest.ps1 index bbb9c2e8ac..32422e7f51 100644 --- a/eng/common/scripts/Submit-PullRequest.ps1 +++ b/eng/common/scripts/Submit-PullRequest.ps1 @@ -63,7 +63,7 @@ param( try { $resp = Get-GitHubPullRequests -RepoOwner $RepoOwner -RepoName $RepoName ` - -Head "${PROwner}:${PRBranch}" -Base $BaseBranch + -Head "${PROwner}:${PRBranch}" -Base $BaseBranch -AuthToken $AuthToken } catch { LogError "Get-GitHubPullRequests failed with exception:`n$_" @@ -89,8 +89,10 @@ else { # setting variable to reference the pull request by number Write-Host "##vso[task.setvariable variable=Submitted.PullRequest.Number]$($resp.number)" - Add-GitHubPullRequestReviewers -RepoOwner $RepoOwner -RepoName $RepoName -PrNumber $resp.number ` - -Users $UserReviewers -Teams $TeamReviewers -AuthToken $AuthToken + if ($UserReviewers -or $TeamReviewers) { + Add-GitHubPullRequestReviewers -RepoOwner $RepoOwner -RepoName $RepoName -PrNumber $resp.number ` + -Users $UserReviewers -Teams $TeamReviewers -AuthToken $AuthToken + } if ($CloseAfterOpenForTesting) { $prState = "closed" diff --git a/eng/common/scripts/Update-ChangeLog.ps1 b/eng/common/scripts/Update-ChangeLog.ps1 new file mode 100644 index 0000000000..eb506076c6 --- /dev/null +++ b/eng/common/scripts/Update-ChangeLog.ps1 @@ -0,0 +1,119 @@ +# Note: This script will add or replace version title in change log + +# Parameter description +# Version : Version to add or replace in change log +# Unreleased: Default is true. If it is set to false, then today's date will be set in verion title. If it is True then title will show "Unreleased" +# ReplaceLatestEntry: Replaces the latest changelog entry, including its content. + +param ( + [Parameter(Mandatory = $true)] + [String]$Version, + [Parameter(Mandatory = $true)] + [String]$ServiceDirectory, + [Parameter(Mandatory = $true)] + [String]$PackageName, + [boolean]$Unreleased=$True, + [boolean]$ReplaceLatestEntry = $False, + [String]$ReleaseDate +) + +if ($ReleaseDate -and ($Unreleased -eq $True)) { + LogError "Do not pass 'ReleaseDate' arguement when 'Unreleased' is true" + exit 1 +} + +. "${PSScriptRoot}\common.ps1" + +if ($ReleaseDate) +{ + try { + $ReleaseStatus = ([DateTime]$ReleaseDate).ToString($CHANGELOG_DATE_FORMAT) + $ReleaseStatus = "($ReleaseStatus)" + } + catch { + LogError "Invalid 'ReleaseDate'. Please use a valid date in the format '$CHANGELOG_DATE_FORMAT'" + exit 1 + } +} +elseif ($Unreleased) { + $ReleaseStatus = $CHANGELOG_UNRELEASED_STATUS +} +else { + $ReleaseStatus = "$(Get-Date -Format $CHANGELOG_DATE_FORMAT)" + $ReleaseStatus = "($ReleaseStatus)" +} + +if ($null -eq [AzureEngSemanticVersion]::ParseVersionString($Version)) +{ + LogError "Version [$Version] is invalid. Please use a valid SemVer" + exit(0) +} + +$PkgProperties = Get-PkgProperties -PackageName $PackageName -ServiceDirectory $ServiceDirectory +$ChangeLogEntries = Get-ChangeLogEntries -ChangeLogLocation $PkgProperties.ChangeLogPath + + +if ($ChangeLogEntries.Contains($Version)) +{ + if ($ChangeLogEntries[$Version].ReleaseStatus -eq $ReleaseStatus) + { + LogWarning "Version is already present in change log with specificed ReleaseStatus [$ReleaseStatus]" + exit(0) + } + + if ($Unreleased -and ($ChangeLogEntries[$Version].ReleaseStatus -ne $ReleaseStatus)) + { + LogWarning "Version is already present in change log with a release date. Please review [$($PkgProperties.ChangeLogPath)]" + exit(0) + } + + if (!$Unreleased -and ($ChangeLogEntries[$Version].ReleaseStatus -ne $CHANGELOG_UNRELEASED_STATUS)) + { + if ((Get-Date ($ChangeLogEntries[$Version].ReleaseStatus).Trim("()")) -gt (Get-Date $ReleaseStatus.Trim("()"))) + { + LogWarning "New ReleaseDate for version [$Version] is older than existing release date in changelog. Please review [$($PkgProperties.ChangeLogPath)]" + exit(0) + } + } +} + +$PresentVersionsSorted = [AzureEngSemanticVersion]::SortVersionStrings($ChangeLogEntries.Keys) +$LatestVersion = $PresentVersionsSorted[0] + +$LatestsSorted = [AzureEngSemanticVersion]::SortVersionStrings(@($LatestVersion, $Version)) +if ($LatestsSorted[0] -ne $Version) { + LogWarning "Passed Version [$Version] is older than the latestversion [$LatestVersion] in the changelog. Please use a more recent version." + exit(0) +} + +if ($ReplaceLatestEntry) +{ + $ChangeLogEntries.Remove($LatestVersion) + $newChangeLogEntry = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus + if ($newChangeLogEntry) { + $ChangeLogEntries[$Version] = $newChangeLogEntry + } + else { + LogError "Failed to create new changelog entry" + } +} +elseif ($ChangeLogEntries.Contains($Version)) +{ + $ChangeLogEntries[$Version].ReleaseVersion = $Version + $ChangeLogEntries[$Version].ReleaseStatus = $ReleaseStatus + $ChangeLogEntries[$Version].ReleaseTitle = "## $Version $ReleaseStatus" +} +else +{ + $newChangeLogEntry = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus + if ($newChangeLogEntry) { + $ChangeLogEntries[$Version] = $newChangeLogEntry + } + else { + LogError "Failed to create new changelog entry" + } +} + +Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $ChangeLogEntries + + diff --git a/eng/common/scripts/Verify-Links.ps1 b/eng/common/scripts/Verify-Links.ps1 index c9991a0588..60065c9808 100644 --- a/eng/common/scripts/Verify-Links.ps1 +++ b/eng/common/scripts/Verify-Links.ps1 @@ -30,6 +30,7 @@ function NormalizeUrl([string]$url){ $url = "file://" + (Resolve-Path $url).ToString(); } + Write-Verbose "The url to check against: $url." $uri = [System.Uri]$url; if ($script:baseUrl -eq "") { diff --git a/eng/common/scripts/get-markdown-files-from-changed-files.ps1 b/eng/common/scripts/get-markdown-files-from-changed-files.ps1 new file mode 100644 index 0000000000..6316fd1ce2 --- /dev/null +++ b/eng/common/scripts/get-markdown-files-from-changed-files.ps1 @@ -0,0 +1,49 @@ +param ( + # The root repo we scaned with. + [string] $RootRepo = '$PSScriptRoot/../../..', + # The target branch to compare with. + [string] $targetBranch = "origin/${env:SYSTEM_PULLREQUEST_TARGETBRANCH}" +) +$deletedFiles = (git diff $targetBranch HEAD --name-only --diff-filter=D) +$renamedFiles = (git diff $targetBranch HEAD --diff-filter=R) +$changedMarkdowns = (git diff $targetBranch HEAD --name-only -- '*.md') + +$beforeRenameFiles = @() +# Retrieve the 'renamed from' files. Git command only returns back the files after rename. +# In order to have the files path before rename, it has to do some regex checking. +# It is better to be replaced by more reliable commands if any. +foreach ($file in $renamedFiles) { + if ($file -match "^rename from (.*)$") { + $beforeRenameFiles += $file -replace "^rename from (.*)$", '$1' + } +} +# A combined list of deleted and renamed files. +$relativePathLinks = ($deletedFiles + $beforeRenameFiles) +# Removed the deleted markdowns. +$changedMarkdowns = $changedMarkdowns | Where-Object { $deletedFiles -notcontains $_ } +# Scan all markdowns and find if it contains the deleted or renamed files. +$markdownContainLinks = @() +$allMarkdownFiles = Get-ChildItem -Path $RootRepo -Recurse -Include *.md +foreach ($f in $allMarkdownFiles) { + $filePath = $f.FullName + $content = Get-Content -Path $filePath -Raw + foreach ($l in $relativePathLinks) { + if ($content -match $l) { + $markdownContainLinks += $filePath + break + } + } +} + +# Convert markdowns path of the PR to absolute path. +$adjustedReadmes = $changedMarkdowns | Foreach-Object { Resolve-Path $_ } +$markdownContainLinks += $adjustedReadmes + +# Get rid of any duplicated ones. +$allMarkdowns = [string[]]($markdownContainLinks | Sort-Object | Get-Unique) + +Write-Host "Here are all markdown files we need to check based on the changed files:" +foreach ($file in $allMarkdowns) { + Write-Host " $file" +} +return $allMarkdowns diff --git a/eng/scripts/Language-Settings.ps1 b/eng/scripts/Language-Settings.ps1 index fb66486137..173d54b9e5 100644 --- a/eng/scripts/Language-Settings.ps1 +++ b/eng/scripts/Language-Settings.ps1 @@ -18,17 +18,17 @@ function Get-c-PackageInfoFromPackageFile ($pkg, $workingDirectory) { $releaseNotes = Get-ChangeLogEntryAsString -ChangeLogLocation $changeLogLoc -VersionString $pkgVersion } - + $readmeContentLoc = @(Get-ChildItem -Path $packageArtifactLocation -Recurse -Include "README.md")[0] - if ($readmeContentLoc) - { + if ($readmeContentLoc) { $readmeContent = Get-Content -Raw $readmeContentLoc } return New-Object PSObject -Property @{ - PackageId = 'azure-sdk-for-c' + PackageId = '' PackageVersion = $pkgVersion - # Artifact info is always considered deployable for C because it is not + ReleaseTag = $pkgVersion + # Artifact info is always considered deployable for C becasue it is not # deployed anywhere. Dealing with duplicate tags happens downstream in # CheckArtifactShaAgainstTagsList Deployable = $true diff --git a/sdk/inc/azure/core/az_version.h b/sdk/inc/azure/core/az_version.h index 4c3e98cb04..015f0b08bd 100644 --- a/sdk/inc/azure/core/az_version.h +++ b/sdk/inc/azure/core/az_version.h @@ -17,7 +17,7 @@ /// The version in string format used for telemetry following the `semver.org` standard /// (https://semver.org). -#define AZ_SDK_VERSION_STRING "1.1.0-beta.3" +#define AZ_SDK_VERSION_STRING "1.1.0-beta.4" /// Major numeric identifier. #define AZ_SDK_VERSION_MAJOR 1 @@ -29,6 +29,6 @@ #define AZ_SDK_VERSION_PATCH 0 /// Optional pre-release identifier. SDK is in a pre-release state when present. -#define AZ_SDK_VERSION_PRERELEASE "beta.3" +#define AZ_SDK_VERSION_PRERELEASE "beta.4" #endif //_az_VERSION_H diff --git a/sdk/samples/iot/README.md b/sdk/samples/iot/README.md index 0a2218acd3..237d9411f6 100644 --- a/sdk/samples/iot/README.md +++ b/sdk/samples/iot/README.md @@ -6,6 +6,16 @@ - [Table of Contents](#table-of-contents) - [Introduction](#introduction) - [Prerequisites](#prerequisites) + - [Getting Started](#getting-started) + - [Create a Device Using X.509 Self-Signed Certificate Authentication](#create-a-device-using-x509-self-signed-certificate-authentication) + - [Create a Device Using Symmetric Key Authentication](#create-a-device-using-symmetric-key-authentication) + - [Set Environment Variables](#set-environment-variables) + - [All-Samples](#all-samples) + - [IoT Hub X.509 Certificate Samples](#iot-hub-x509-certificate-samples) + - [IoT Provisioning X.509 Certificate Sample](#iot-provisioning-x509-certificate-sample) + - [IoT Hub Symetric Key (SAS) Sample](#iot-hub-symetric-key-sas-sample) + - [IoT Provisioning Symmetric Key (SAS) Sample](#iot-provisioning-symmetric-key-sas-sample) + - [Build and Run the Sample](#build-and-run-the-sample) - [Sample Descriptions](#sample-descriptions) - [IoT Hub C2D Sample](#iot-hub-c2d-sample) - [IoT Hub Methods Sample](#iot-hub-methods-sample) @@ -17,15 +27,15 @@ - [IoT Plug and Play Multiple Component Sample](#iot-plug-and-play-multiple-component-sample) - [IoT Provisioning Certificate Sample](#iot-provisioning-certificate-sample) - [IoT Provisioning SAS Sample](#iot-provisioning-sas-sample) - - [Getting Started](#getting-started) - - [Set Environment Variables](#set-environment-variables) + - [Getting Started](#getting-started-1) + - [Set Environment Variables](#set-environment-variables-1) - [Generate Device Certificate](#generate-device-certificate) - [Sample Instructions](#sample-instructions) - [IoT Hub Certificate Samples](#iot-hub-certificate-samples) - [IoT Hub SAS Sample](#iot-hub-sas-sample) - [IoT Provisioning Certificate Sample](#iot-provisioning-certificate-sample-1) - [IoT Provisioning SAS Sample](#iot-provisioning-sas-sample-1) - - [Build and Run the Sample](#build-and-run-the-sample) + - [Build and Run the Sample](#build-and-run-the-sample-1) - [Next Steps and Additional Documentation](#next-steps-and-additional-documentation) - [Troubleshooting](#troubleshooting) - [Contributing](#contributing) @@ -55,13 +65,9 @@ To run the samples, ensure you have the following programs and tools installed o - Have an [Azure account](https://azure.microsoft.com/) created. - Have an [Azure IoT Hub](https://docs.microsoft.com/azure/iot-hub/iot-hub-create-through-portal) created. -- Have an [Azure IoT Hub Device Provisioning Service (DPS)](https://docs.microsoft.com/azure/iot-dps/quick-setup-auto-provision) created if running a DPS sample: - - *Executables:* `paho_iot_provisioning_sample`, `paho_iot_provisioning_sas_sample`, `paho_iot_pnp_with_provisioning_sample` - -- Have the most recent version of [Azure IoT Explorer](https://github.com/Azure/azure-iot-explorer/releases) installed (more instructions can be found [here](https://docs.microsoft.com/azure/iot-pnp/howto-use-iot-explorer)) and connected to your Azure IoT Hub if running a Plug and Play sample: +- Have an [Azure IoT Hub Device Provisioning Service (DPS)](https://docs.microsoft.com/azure/iot-dps/quick-setup-auto-provision) created if running a DPS sample: `paho_iot_provisioning_sample`, `paho_iot_provisioning_sas_sample`, `paho_iot_pnp_with_provisioning_sample` - *Executables:* `paho_iot_pnp_sample`, `paho_iot_pnp_component_sample` +- Have the most recent version of [Azure IoT Explorer](https://github.com/Azure/azure-iot-explorer/releases) installed and connected to your Azure IoT Hub if running a Plug and Play sample: `paho_iot_hub_pnp_sample`, `paho_iot_hub_pnp_component_sample`, `paho_iot_pnp_with_provisioning_sample`. More instructions on can be found [here](https://docs.microsoft.com/azure/iot-pnp/howto-use-iot-explorer). - Have the following build environment setup: @@ -170,6 +176,262 @@ To run the samples, ensure you have the following programs and tools installed o git clone https://github.com/Azure/azure-sdk-for-c.git ``` +## Getting Started + +Next you must create and connect a device. You can do this in one of two ways: via Azure IoT Hub or via Azure IoT Hub Device Provisioning Service (DPS). You also must choose how to authenticate the device, either via X.509 Self-Signed Certificate Authentication or Symmetric Key (SAS). + +### Create a Device Using X.509 Self-Signed Certificate Authentication + +This approach must be used for the following samples: `paho_iot_hub_c2d_sample`, `paho_iot_hub_methods_sample`, `paho_iot_hub_telemetry_sample`, `paho_iot_hub_twin_sample`, `paho_iot_hub_pnp_sample`, `paho_iot_hub_pnp_component_sample`, `paho_iot_provisioning_sample` + +1. Generate a certificate + + As a convenience, we provide a series of commands below for you to create a temporary certificate in order to run the samples. These certificates expire after 30 days and are provided ONLY to help you easily understand CA Certificates. When productizing against CA Certificates, you will need to use your own security best practices for certificate creation and lifetime management. + + **WARNING: Certificates created by these commands MUST NOT be used in production-level code.** + +
Certificate Generation Commands: +

+ +

Linux: +

+ + 1. Enter the directory `azure-sdk-for-c/sdk/samples/iot/`. + 2. Run the following commands: + + ```bash + openssl ecparam -out device_ec_key.pem -name prime256v1 -genkey + openssl req -new -days 30 -nodes -x509 -key device_ec_key.pem -out device_ec_cert.pem -config x509_config.cfg -subj "/CN=paho-sample-device1" + openssl x509 -noout -text -in device_ec_cert.pem + + rm -f device_cert_store.pem + cat device_ec_cert.pem device_ec_key.pem > device_cert_store.pem + + openssl x509 -noout -fingerprint -in device_ec_cert.pem | sed 's/://g'| sed 's/\(SHA1 Fingerprint=\)//g' | tee fingerprint.txt + + export AZ_IOT_DEVICE_X509_CERT_PEM_FILE_PATH=$(pwd)/device_cert_store.pem + ``` + + 3. The resulting thumbprint will be placed in `fingerprint.txt` and the generated pem file is named `device_ec_cert.pem`. + +

+
+ +
Windows (PowerShell): +

+ + 1. Enter the directory `azure-sdk-for-c\sdk\samples\iot\`. + 2. Run the following commands: + + ```powershell + openssl ecparam -out device_ec_key.pem -name prime256v1 -genkey + openssl req -new -days 30 -nodes -x509 -key device_ec_key.pem -out device_ec_cert.pem -config x509_config.cfg -subj "/CN=paho-sample-device1" + openssl x509 -noout -text -in device_ec_cert.pem + + Get-Content device_ec_cert.pem, device_ec_key.pem | Set-Content device_cert_store.pem + + openssl x509 -noout -fingerprint -in device_ec_cert.pem | % {$_.replace(":", "")} | % {$_.replace("SHA1 Fingerprint=", "")} | Tee-Object fingerprint.txt + + $env:AZ_IOT_DEVICE_X509_CERT_PEM_FILE_PATH=$(Resolve-Path device_cert_store.pem) + ``` + 3. The resulting thumbprint will be placed in `fingerprint.txt` and the generated pem file is named `device_ec_cert.pem`. + +

+
+ +

+
+ +2. Create a device + + - To add a new device via Azure IoT Hub, see instructions [here](https://docs.microsoft.com/azure/iot-hub/iot-hub-security-x509-get-started#create-an-x509-device-for-your-iot-hub). However, **DO NOT** select X.509 CA Signed as the authentication type. Select **X.509 Self-Signed**. For the Thumbprint, use the recently generated fingerprint, which has been placed in the file `fingerprint.txt`. + - To add a new individual device enrollment via Azure IoT Hub DPS, see instructions [here](https://docs.microsoft.com/azure/iot-dps/quick-create-simulated-device-x509#create-a-device-enrollment-entry-in-the-portal). You will use the recently generated `device_ec_cert.pem` file. After creation, the Registration ID of your device should appear as `paho-sample-device1` in the Individual Enrollments tab. + +### Create a Device Using Symmetric Key Authentication + +This approach must be used for the following samples: `paho_iot_hub_sas_telemetry_sample`, `paho_iot_provisioning_sas_sample`, + +- To add a new device via Azure IoT Hub, see instructions [here](https://docs.microsoft.com/azure/iot-hub/iot-hub-create-through-portal#register-a-new-device-in-the-iot-hub). +- To add a new individual device enrollment via Azure IoT Hub DPS, see instructions [here](https://docs.microsoft.com/azure/iot-dps/quick-create-simulated-device-symm-key#create-a-device-enrollment-entry-in-the-portal). After creation, the Registration ID of your device will appear in the Individual Enrollments tab. + +## Set Environment Variables + +Samples use environment variables for a variety of purposes, including filepaths and connection parameters. Please keep in mind, **every time a new terminal is opened, the environment variables will have to be reset**. Setting a variable will take the following form: + +**Linux:** + +```bash +export ENV_VARIABLE_NAME=VALUE +``` + +**Windows (PowerShell):** + +```powershell +$env:ENV_VARIABLE_NAME='VALUE' +``` + +### All-Samples + +Set the following environment variables for all samples: + + 1. Set the vcpkg environment variables. + + Refer to these [directions](https://github.com/Azure/azure-sdk-for-c#development-environment) for more detail. + + Linux: + + ```bash + export VCPKG_DEFAULT_TRIPLET=x64-linux + export VCPKG_ROOT= + ``` + + Windows (PowerShell): + + ```powershell + $env:VCPKG_DEFAULT_TRIPLET='x64-windows-static' # Update triplet to match what was used during vcpkg install. + $env:VCPKG_ROOT='' + ``` + + 2. Set the trust pem filepath. **Only for Windows or if required by OS.** + + Download [BaltimoreCyberTrustRoot.crt.pem](https://cacerts.digicert.com/BaltimoreCyberTrustRoot.crt.pem) to `\sdk\samples\iot\`. Confirm the downloaded certificate uses the correct file name and file extension. + + Windows (PowerShell): + + ```powershell + $env:AZ_IOT_DEVICE_X509_TRUST_PEM_FILE_PATH='\sdk\samples\iot\BaltimoreCyberTrustRoot.crt.pem' + ``` + +### IoT Hub X.509 Certificate Samples + +Set the following environment variables if running any of these samples: `paho_iot_hub_c2d_sample`, `paho_iot_hub_methods_sample`, `paho_iot_hub_telemetry_sample`, `paho_iot_hub_twin_sample`, `paho_iot_hub_pnp_sample`, `paho_iot_hub_pnp_component_sample` + +Access your Azure IoT Hub from either your Azure Portal or Azure IoT Explorer. + + - `AZ_IOT_HUB_DEVICE_ID`: From the IoT devices tab, select your device. Copy its Device Id. + - `AZ_IOT_HUB_HOSTNAME`: From the Overiview tab, copy your Azure IoT hub Hostname. + + Linux: + + ```bash + export AZ_IOT_HUB_DEVICE_ID= + export AZ_IOT_HUB_HOSTNAME= + ``` + + Windows (PowerShell): + + ```powershell + $env:AZ_IOT_HUB_DEVICE_ID='' + $env:AZ_IOT_HUB_HOSTNAME='' + ``` + +### IoT Provisioning X.509 Certificate Sample + +Set the following environment variables if running the sample: `paho_iot_provisioning_sample` + +Access your Azure IoT Hub Device Provisioning Service from your Azure Portal. + + - `AZ_IOT_PROVISIONING_REGISTRATION_ID`: Set this to `paho-sample-device1`. + - `AZ_IOT_PROVISIONING_ID_SCOPE`: From the Overview tab, copy the Id Scope. + + Linux: + + ```bash + export AZ_IOT_PROVISIONING_REGISTRATION_ID= + export AZ_IOT_PROVISIONING_ID_SCOPE= + ``` + + Windows (PowerShell): + + ```powershell + $env:AZ_IOT_PROVISIONING_REGISTRATION_ID='' + $env:AZ_IOT_PROVISIONING_ID_SCOPE='' + ``` + +### IoT Hub Symetric Key (SAS) Sample + +Set the following environment variables if running the sample: `paho_iot_hub_sas_telemetry_sample` + +Access your Azure IoT Hub from either your Azure Portal or Azure IoT Explorer. + + - `AZ_IOT_HUB_SAS_DEVICE_ID`: From the IoT devices tab, select your device. Copy its Device Id. + - `AZ_IOT_HUB_SAS_KEY`: From the same page, copy its Primary Key. + - `AZ_IOT_HUB_HOSTNAME`: From the Overiview tab, copy your Azure IoT hub Hostname. + + Linux: + + ```bash + export AZ_IOT_HUB_SAS_DEVICE_ID= + export AZ_IOT_HUB_SAS_KEY= + export AZ_IOT_HUB_HOSTNAME= + ``` + + Windows (PowerShell): + + ```powershell + $env:AZ_IOT_HUB_SAS_DEVICE_ID='' + $env:AZ_IOT_HUB_SAS_KEY='' + $env:AZ_IOT_HUB_HOSTNAME='' + ``` + +### IoT Provisioning Symmetric Key (SAS) Sample + +Set the following environment variables if running the sample: `paho_iot_provisioning_sas_sample` + +Access your Azure IoT Hub Device Provisioning Service from your Azure Portal. + + - `AZ_IOT_PROVISIONING_SAS_REGISTRATION_ID`: From the Manage enrollments tab, under Individual Enrollments, copy the Registration Id of your SAS device. + - `AZ_IOT_PROVISIONING_SAS_KEY`: Under Individual Enrollments, select your SAS device. Copy its Primary Key. + - `AZ_IOT_PROVISIONING_ID_SCOPE`: From the Overview tab, copy the Id Scope. + + Linux: + + ```bash + export AZ_IOT_PROVISIONING_SAS_REGISTRATION_ID= + export AZ_IOT_PROVISIONING_SAS_KEY= + export AZ_IOT_PROVISIONING_ID_SCOPE= + ``` + + Windows (PowerShell): + + ```powershell + $env:AZ_IOT_PROVISIONING_SAS_REGISTRATION_ID='' + $env:AZ_IOT_PROVISIONING_SAS_KEY='' + $env:AZ_IOT_PROVISIONING_ID_SCOPE='' + ``` + +## Build and Run the Sample + +1. Build the Azure SDK for Embedded C directory structure. + + From the root of the SDK directory `azure-sdk-for-c`: + + ```bash + mkdir build + cd build + cmake -DTRANSPORT_PAHO=ON .. + ``` + +2. Compile and run the sample. + + Linux: + + ```bash + cmake --build . + ./sdk/samples/iot/ + ``` + + Windows (PowerShell): + + ```powershell + .\az.sln + ``` + + Once the Windows solution opens in Visual Studio: + - Navigate to the "Solution Explorer" panel and find the sample project you would like to run. + - Right-click on the sample project, then click on "Set as Startup Project". (This makes it the default startup project.) + - Build and run the project (`F5` on most installations). + ## Sample Descriptions This section provides an overview of the different samples available to run and what to expect from each. diff --git a/sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md b/sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md index 3ca86bfd1c..3969587563 100644 --- a/sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md +++ b/sdk/samples/iot/docs/how_to_iot_hub_esp8266_nodemcu.md @@ -91,7 +91,7 @@ _The following was run on Windows 10 and Ubuntu Desktop 20.04 environments, with This will create a local file named `azure-sdk-for-c.zip` containing the entire [Azure SDK for Embedded C](https://github.com/Azure/azure-sdk-for-c) repository as an Arduino library. - NOTE: If you are using WSL, do not run these commands from the Windows system drive (e.g. `/mnt/c/`). + NOTE: If you are using WSL, do not run these commands from the Windows system drive (e.g. `/mnt/c/`). 2. Run the Arduino IDE. @@ -265,6 +265,18 @@ _The following was run on Windows 10 and Ubuntu Desktop 20.04 environments, with

+## Certificates - Important to know + +The Azure IoT service certificates presented during TLS negotiation shall be always validated, on the device, using the appropriate trusted root CA certificate(s). + +For the Node MCU ESP8266 sample, our script `generate_arduino_zip_library.sh` automatically downloads the root certificate used in the United States regions (Baltimore CA certificate) and adds it to the Arduino sketch project. + +For other regions (and private cloud environments), please use the appropriate root CA certificate. + +### Additional Information + +For important information and additional guidance about certificates, please refer to [this blog post](https://techcommunity.microsoft.com/t5/internet-of-things/azure-iot-tls-changes-are-coming-and-why-you-should-care/ba-p/1658456) from the security team. + ## Troubleshooting - The error policy for the Embedded C SDK client library is documented [here](https://github.com/Azure/azure-sdk-for-c/blob/master/sdk/docs/iot/mqtt_state_machine.md#error-policy). diff --git a/sdk/src/azure/core/az_context.c b/sdk/src/azure/core/az_context.c index d5a89710ae..09e4ddd0eb 100644 --- a/sdk/src/azure/core/az_context.c +++ b/sdk/src/azure/core/az_context.c @@ -36,7 +36,7 @@ AZ_NODISCARD int64_t az_context_get_expiration(az_context const* context) // and return the corresponding value. Returns AZ_ERROR_ITEM_NOT_FOUND is there are no nodes // matching the specified key. AZ_NODISCARD az_result -az_context_get_value(az_context const* context, void const* const key, void const** out_value) +az_context_get_value(az_context const* context, void const* key, void const** out_value) { _az_PRECONDITION_NOT_NULL(context); _az_PRECONDITION_NOT_NULL(out_value); @@ -55,7 +55,7 @@ az_context_get_value(az_context const* context, void const* const key, void cons } AZ_NODISCARD az_context -az_context_create_with_expiration(az_context const* const parent, int64_t expiration) +az_context_create_with_expiration(az_context const* parent, int64_t expiration) { _az_PRECONDITION_NOT_NULL(parent); _az_PRECONDITION(expiration >= 0); @@ -63,10 +63,8 @@ az_context_create_with_expiration(az_context const* const parent, int64_t expira return (az_context){ ._internal = { .parent = parent, .expiration = expiration } }; } -AZ_NODISCARD az_context az_context_create_with_value( - az_context const* const parent, - void const* const key, - void const* const value) +AZ_NODISCARD az_context +az_context_create_with_value(az_context const* parent, void const* key, void const* value) { _az_PRECONDITION_NOT_NULL(parent); _az_PRECONDITION_NOT_NULL(key); @@ -84,7 +82,7 @@ void az_context_cancel(az_context* ref_context) ref_context->_internal.expiration = 0; // The beginning of time } -AZ_NODISCARD bool az_context_has_expired(az_context const* const context, int64_t current_time) +AZ_NODISCARD bool az_context_has_expired(az_context const* context, int64_t current_time) { _az_PRECONDITION_NOT_NULL(context); _az_PRECONDITION(current_time >= 0); diff --git a/sdk/src/azure/core/az_http_policy_logging.c b/sdk/src/azure/core/az_http_policy_logging.c index eca4991c9f..1bf5e79cec 100644 --- a/sdk/src/azure/core/az_http_policy_logging.c +++ b/sdk/src/azure/core/az_http_policy_logging.c @@ -55,7 +55,7 @@ static az_span _az_http_policy_logging_copy_lengthy_value(az_span ref_log_msg, a } static az_result _az_http_policy_logging_append_http_request_msg( - az_http_request const* const request, + az_http_request const* request, az_span* ref_log_msg) { static az_span const auth_header_name = AZ_SPAN_LITERAL_FROM_STR("authorization"); @@ -124,7 +124,7 @@ static az_result _az_http_policy_logging_append_http_request_msg( static az_result _az_http_policy_logging_append_http_response_msg( az_http_response* ref_response, int64_t duration_msec, - az_http_request const* const request, + az_http_request const* request, az_span* ref_log_msg) { az_span http_response_string = AZ_SPAN_FROM_STR("HTTP Response ("); @@ -207,7 +207,7 @@ static az_result _az_http_policy_logging_append_http_response_msg( return AZ_OK; } -void _az_http_policy_logging_log_http_request(az_http_request const* const request) +void _az_http_policy_logging_log_http_request(az_http_request const* request) { uint8_t log_msg_buf[AZ_LOG_MESSAGE_BUFFER_SIZE] = { 0 }; az_span log_msg = AZ_SPAN_FROM_BUFFER(log_msg_buf); @@ -218,9 +218,9 @@ void _az_http_policy_logging_log_http_request(az_http_request const* const reque } void _az_http_policy_logging_log_http_response( - az_http_response const* const response, + az_http_response const* response, int64_t duration_msec, - az_http_request const* const request) + az_http_request const* request) { uint8_t log_msg_buf[AZ_LOG_MESSAGE_BUFFER_SIZE] = { 0 }; az_span log_msg = AZ_SPAN_FROM_BUFFER(log_msg_buf); diff --git a/sdk/src/azure/core/az_http_request.c b/sdk/src/azure/core/az_http_request.c index 8b64d01861..5288971448 100644 --- a/sdk/src/azure/core/az_http_request.c +++ b/sdk/src/azure/core/az_http_request.c @@ -149,7 +149,7 @@ az_http_request_append_header(az_http_request* ref_request, az_span name, az_spa } AZ_NODISCARD az_result az_http_request_get_header( - az_http_request const* const request, + az_http_request const* request, int32_t index, az_span* out_name, az_span* out_value) @@ -173,7 +173,7 @@ AZ_NODISCARD az_result az_http_request_get_header( } AZ_NODISCARD az_result -az_http_request_get_method(az_http_request const* const request, az_http_method* out_method) +az_http_request_get_method(az_http_request const* request, az_http_method* out_method) { _az_PRECONDITION_NOT_NULL(request); _az_PRECONDITION_NOT_NULL(out_method); @@ -183,8 +183,7 @@ az_http_request_get_method(az_http_request const* const request, az_http_method* return AZ_OK; } -AZ_NODISCARD az_result -az_http_request_get_url(az_http_request const* const request, az_span* out_url) +AZ_NODISCARD az_result az_http_request_get_url(az_http_request const* request, az_span* out_url) { _az_PRECONDITION_NOT_NULL(request); _az_PRECONDITION_NOT_NULL(out_url); @@ -194,8 +193,7 @@ az_http_request_get_url(az_http_request const* const request, az_span* out_url) return AZ_OK; } -AZ_NODISCARD az_result -az_http_request_get_body(az_http_request const* const request, az_span* out_body) +AZ_NODISCARD az_result az_http_request_get_body(az_http_request const* request, az_span* out_body) { _az_PRECONDITION_NOT_NULL(request); _az_PRECONDITION_NOT_NULL(out_body); @@ -204,7 +202,7 @@ az_http_request_get_body(az_http_request const* const request, az_span* out_body return AZ_OK; } -AZ_NODISCARD int32_t az_http_request_headers_count(az_http_request const* const request) +AZ_NODISCARD int32_t az_http_request_headers_count(az_http_request const* request) { return request->_internal.headers_length; } diff --git a/sdk/src/azure/core/az_http_response.c b/sdk/src/azure/core/az_http_response.c index 2c69bb4581..4f28200966 100644 --- a/sdk/src/azure/core/az_http_response.c +++ b/sdk/src/azure/core/az_http_response.c @@ -327,7 +327,7 @@ void _az_http_response_reset(az_http_response* ref_response) } // internal function to get az_http_response remainder -static az_span _az_http_response_get_remaining(az_http_response const* const response) +static az_span _az_http_response_get_remaining(az_http_response const* response) { return az_span_slice_to_end(response->_internal.http_response, response->_internal.written); } diff --git a/sdk/src/azure/core/az_json_reader.c b/sdk/src/azure/core/az_json_reader.c index 817b6e08a5..084abb4884 100644 --- a/sdk/src/azure/core/az_json_reader.c +++ b/sdk/src/azure/core/az_json_reader.c @@ -14,7 +14,7 @@ AZ_NODISCARD az_result az_json_reader_init( az_json_reader* out_json_reader, az_span json_buffer, - az_json_reader_options const* const options) + az_json_reader_options const* options) { _az_PRECONDITION(az_span_size(json_buffer) >= 1); @@ -52,7 +52,7 @@ AZ_NODISCARD az_result az_json_reader_chunked_init( az_json_reader* out_json_reader, az_span json_buffers[], int32_t number_of_buffers, - az_json_reader_options const* const options) + az_json_reader_options const* options) { _az_PRECONDITION(number_of_buffers >= 1); _az_PRECONDITION(az_span_size(json_buffers[0]) >= 1); diff --git a/sdk/src/azure/core/az_json_token.c b/sdk/src/azure/core/az_json_token.c index 087da8aaed..f4852f6dbd 100644 --- a/sdk/src/azure/core/az_json_token.c +++ b/sdk/src/azure/core/az_json_token.c @@ -11,7 +11,7 @@ #include static az_span _az_json_token_copy_into_span_helper( - az_json_token const* const json_token, + az_json_token const* json_token, az_span destination) { _az_PRECONDITION(json_token->_internal.is_multisegment); @@ -40,7 +40,7 @@ static az_span _az_json_token_copy_into_span_helper( return destination; } -az_span az_json_token_copy_into_span(az_json_token const* const json_token, az_span destination) +az_span az_json_token_copy_into_span(az_json_token const* json_token, az_span destination) { _az_PRECONDITION_VALID_SPAN(destination, json_token->size, false); @@ -149,7 +149,7 @@ AZ_NODISCARD static bool _az_json_token_is_text_equal_helper( } AZ_NODISCARD bool az_json_token_is_text_equal( - az_json_token const* const json_token, + az_json_token const* json_token, az_span expected_text) { _az_PRECONDITION_NOT_NULL(json_token); @@ -243,8 +243,7 @@ AZ_NODISCARD bool az_json_token_is_text_equal( return az_span_size(expected_text) == 0; } -AZ_NODISCARD az_result -az_json_token_get_boolean(az_json_token const* const json_token, bool* out_value) +AZ_NODISCARD az_result az_json_token_get_boolean(az_json_token const* json_token, bool* out_value) { _az_PRECONDITION_NOT_NULL(json_token); _az_PRECONDITION_NOT_NULL(out_value); @@ -327,7 +326,7 @@ AZ_NODISCARD static az_result _az_json_token_get_string_helper( } AZ_NODISCARD az_result az_json_token_get_string( - az_json_token const* const json_token, + az_json_token const* json_token, char* destination, int32_t destination_max_size, int32_t* out_string_length) @@ -430,7 +429,7 @@ AZ_NODISCARD az_result az_json_token_get_string( } AZ_NODISCARD az_result -az_json_token_get_uint64(az_json_token const* const json_token, uint64_t* out_value) +az_json_token_get_uint64(az_json_token const* json_token, uint64_t* out_value) { _az_PRECONDITION_NOT_NULL(json_token); _az_PRECONDITION_NOT_NULL(out_value); @@ -465,7 +464,7 @@ az_json_token_get_uint64(az_json_token const* const json_token, uint64_t* out_va } AZ_NODISCARD az_result -az_json_token_get_uint32(az_json_token const* const json_token, uint32_t* out_value) +az_json_token_get_uint32(az_json_token const* json_token, uint32_t* out_value) { _az_PRECONDITION_NOT_NULL(json_token); _az_PRECONDITION_NOT_NULL(out_value); @@ -499,8 +498,7 @@ az_json_token_get_uint32(az_json_token const* const json_token, uint32_t* out_va return az_span_atou32(az_span_slice(scratch, 0, _az_span_diff(remainder, scratch)), out_value); } -AZ_NODISCARD az_result -az_json_token_get_int64(az_json_token const* const json_token, int64_t* out_value) +AZ_NODISCARD az_result az_json_token_get_int64(az_json_token const* json_token, int64_t* out_value) { _az_PRECONDITION_NOT_NULL(json_token); _az_PRECONDITION_NOT_NULL(out_value); @@ -534,8 +532,7 @@ az_json_token_get_int64(az_json_token const* const json_token, int64_t* out_valu return az_span_atoi64(az_span_slice(scratch, 0, _az_span_diff(remainder, scratch)), out_value); } -AZ_NODISCARD az_result -az_json_token_get_int32(az_json_token const* const json_token, int32_t* out_value) +AZ_NODISCARD az_result az_json_token_get_int32(az_json_token const* json_token, int32_t* out_value) { _az_PRECONDITION_NOT_NULL(json_token); _az_PRECONDITION_NOT_NULL(out_value); @@ -569,8 +566,7 @@ az_json_token_get_int32(az_json_token const* const json_token, int32_t* out_valu return az_span_atoi32(az_span_slice(scratch, 0, _az_span_diff(remainder, scratch)), out_value); } -AZ_NODISCARD az_result -az_json_token_get_double(az_json_token const* const json_token, double* out_value) +AZ_NODISCARD az_result az_json_token_get_double(az_json_token const* json_token, double* out_value) { _az_PRECONDITION_NOT_NULL(json_token); _az_PRECONDITION_NOT_NULL(out_value); diff --git a/sdk/src/azure/core/az_json_writer.c b/sdk/src/azure/core/az_json_writer.c index b59d7b3307..65b9d35a12 100644 --- a/sdk/src/azure/core/az_json_writer.c +++ b/sdk/src/azure/core/az_json_writer.c @@ -15,7 +15,7 @@ AZ_NODISCARD az_result az_json_writer_init( az_json_writer* out_json_writer, az_span destination_buffer, - az_json_writer_options const* const options) + az_json_writer_options const* options) { _az_PRECONDITION_NOT_NULL(out_json_writer); @@ -40,7 +40,7 @@ AZ_NODISCARD az_result az_json_writer_chunked_init( az_span first_destination_buffer, az_span_allocator_fn allocator_callback, void* user_context, - az_json_writer_options const* const options) + az_json_writer_options const* options) { _az_PRECONDITION_NOT_NULL(out_json_writer); _az_PRECONDITION_NOT_NULL(allocator_callback); @@ -93,7 +93,7 @@ _get_remaining_span(az_json_writer* ref_json_writer, int32_t required_size) // This validation method is used outside of just preconditions, within // az_json_writer_append_json_text. -static AZ_NODISCARD bool _az_is_appending_value_valid(az_json_writer const* const json_writer) +static AZ_NODISCARD bool _az_is_appending_value_valid(az_json_writer const* json_writer) { _az_PRECONDITION_NOT_NULL(json_writer); @@ -136,8 +136,7 @@ static AZ_NODISCARD bool _az_is_appending_value_valid(az_json_writer const* cons } #ifndef AZ_NO_PRECONDITION_CHECKING -static AZ_NODISCARD bool _az_is_appending_property_name_valid( - az_json_writer const* const json_writer) +static AZ_NODISCARD bool _az_is_appending_property_name_valid(az_json_writer const* json_writer) { _az_PRECONDITION_NOT_NULL(json_writer); @@ -157,7 +156,7 @@ static AZ_NODISCARD bool _az_is_appending_property_name_valid( } static AZ_NODISCARD bool _az_is_appending_container_end_valid( - az_json_writer const* const json_writer, + az_json_writer const* json_writer, uint8_t byte) { _az_PRECONDITION_NOT_NULL(json_writer); diff --git a/sdk/src/azure/iot/az_iot_hub_client.c b/sdk/src/azure/iot/az_iot_hub_client.c index 810020f363..b5b87f7f37 100644 --- a/sdk/src/azure/iot/az_iot_hub_client.c +++ b/sdk/src/azure/iot/az_iot_hub_client.c @@ -35,7 +35,7 @@ AZ_NODISCARD az_result az_iot_hub_client_init( az_iot_hub_client* client, az_span iot_hub_hostname, az_span device_id, - az_iot_hub_client_options const* const options) + az_iot_hub_client_options const* options) { _az_PRECONDITION_NOT_NULL(client); _az_PRECONDITION_VALID_SPAN(iot_hub_hostname, 1, false); @@ -49,7 +49,7 @@ AZ_NODISCARD az_result az_iot_hub_client_init( } AZ_NODISCARD az_result az_iot_hub_client_get_user_name( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, char* mqtt_user_name, size_t mqtt_user_name_size, size_t* out_mqtt_user_name_length) @@ -132,7 +132,7 @@ AZ_NODISCARD az_result az_iot_hub_client_get_user_name( } AZ_NODISCARD az_result az_iot_hub_client_get_client_id( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, char* mqtt_client_id, size_t mqtt_client_id_size, size_t* out_mqtt_client_id_length) diff --git a/sdk/src/azure/iot/az_iot_hub_client_c2d.c b/sdk/src/azure/iot/az_iot_hub_client_c2d.c index 76905c4279..ea97917210 100644 --- a/sdk/src/azure/iot/az_iot_hub_client_c2d.c +++ b/sdk/src/azure/iot/az_iot_hub_client_c2d.c @@ -17,7 +17,7 @@ static const az_span c2d_topic_suffix = AZ_SPAN_LITERAL_FROM_STR("/messages/devicebound/"); AZ_NODISCARD az_result az_iot_hub_client_c2d_parse_received_topic( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, az_span received_topic, az_iot_hub_client_c2d_request* out_request) { diff --git a/sdk/src/azure/iot/az_iot_hub_client_methods.c b/sdk/src/azure/iot/az_iot_hub_client_methods.c index 36071a2f0f..6afe42590e 100644 --- a/sdk/src/azure/iot/az_iot_hub_client_methods.c +++ b/sdk/src/azure/iot/az_iot_hub_client_methods.c @@ -22,7 +22,7 @@ static const az_span methods_response_topic_result = AZ_SPAN_LITERAL_FROM_STR("r static const az_span methods_response_topic_properties = AZ_SPAN_LITERAL_FROM_STR("/?$rid="); AZ_NODISCARD az_result az_iot_hub_client_methods_parse_received_topic( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, az_span received_topic, az_iot_hub_client_method_request* out_request) { @@ -77,7 +77,7 @@ AZ_NODISCARD az_result az_iot_hub_client_methods_parse_received_topic( } AZ_NODISCARD az_result az_iot_hub_client_methods_response_get_publish_topic( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, az_span request_id, uint16_t status, char* mqtt_topic, diff --git a/sdk/src/azure/iot/az_iot_hub_client_sas.c b/sdk/src/azure/iot/az_iot_hub_client_sas.c index 80fcfdce4a..2dc341a59a 100644 --- a/sdk/src/azure/iot/az_iot_hub_client_sas.c +++ b/sdk/src/azure/iot/az_iot_hub_client_sas.c @@ -34,7 +34,7 @@ static const az_span sig_string = AZ_SPAN_LITERAL_FROM_STR(SAS_TOKEN_SIG); static const az_span se_string = AZ_SPAN_LITERAL_FROM_STR(SAS_TOKEN_SE); AZ_NODISCARD az_result az_iot_hub_client_sas_get_signature( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, uint64_t token_expiration_epoch_time, az_span signature, az_span* out_signature) @@ -81,7 +81,7 @@ AZ_NODISCARD az_result az_iot_hub_client_sas_get_signature( } AZ_NODISCARD az_result az_iot_hub_client_sas_get_password( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, uint64_t token_expiration_epoch_time, az_span base64_hmac_sha256_signature, az_span key_name, diff --git a/sdk/src/azure/iot/az_iot_hub_client_telemetry.c b/sdk/src/azure/iot/az_iot_hub_client_telemetry.c index e8770efa31..c628cd86cf 100644 --- a/sdk/src/azure/iot/az_iot_hub_client_telemetry.c +++ b/sdk/src/azure/iot/az_iot_hub_client_telemetry.c @@ -18,8 +18,8 @@ static const az_span telemetry_topic_modules_mid = AZ_SPAN_LITERAL_FROM_STR("/mo static const az_span telemetry_topic_suffix = AZ_SPAN_LITERAL_FROM_STR("/messages/events/"); AZ_NODISCARD az_result az_iot_hub_client_telemetry_get_publish_topic( - az_iot_hub_client const* const client, - az_iot_message_properties const* const properties, + az_iot_hub_client const* client, + az_iot_message_properties const* properties, char* mqtt_topic, size_t mqtt_topic_size, size_t* out_mqtt_topic_length) diff --git a/sdk/src/azure/iot/az_iot_hub_client_twin.c b/sdk/src/azure/iot/az_iot_hub_client_twin.c index 322dbf4081..1e0f3423a6 100644 --- a/sdk/src/azure/iot/az_iot_hub_client_twin.c +++ b/sdk/src/azure/iot/az_iot_hub_client_twin.c @@ -28,7 +28,7 @@ static const az_span az_iot_hub_twin_patch_sub_topic = AZ_SPAN_LITERAL_FROM_STR("PATCH/properties/desired/"); AZ_NODISCARD az_result az_iot_hub_client_twin_document_get_publish_topic( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, az_span request_id, char* mqtt_topic, size_t mqtt_topic_size, @@ -68,7 +68,7 @@ AZ_NODISCARD az_result az_iot_hub_client_twin_document_get_publish_topic( } AZ_NODISCARD az_result az_iot_hub_client_twin_patch_get_publish_topic( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, az_span request_id, char* mqtt_topic, size_t mqtt_topic_size, @@ -108,7 +108,7 @@ AZ_NODISCARD az_result az_iot_hub_client_twin_patch_get_publish_topic( } AZ_NODISCARD az_result az_iot_hub_client_twin_parse_received_topic( - az_iot_hub_client const* const client, + az_iot_hub_client const* client, az_span received_topic, az_iot_hub_client_twin_response* out_response) { diff --git a/sdk/src/azure/iot/az_iot_provisioning_client.c b/sdk/src/azure/iot/az_iot_provisioning_client.c index 67fc4fa7f4..483c335659 100644 --- a/sdk/src/azure/iot/az_iot_provisioning_client.c +++ b/sdk/src/azure/iot/az_iot_provisioning_client.c @@ -51,7 +51,7 @@ AZ_NODISCARD az_result az_iot_provisioning_client_init( az_span global_device_hostname, az_span id_scope, az_span registration_id, - az_iot_provisioning_client_options const* const options) + az_iot_provisioning_client_options const* options) { _az_PRECONDITION_NOT_NULL(client); _az_PRECONDITION_VALID_SPAN(global_device_hostname, 1, false); @@ -70,7 +70,7 @@ AZ_NODISCARD az_result az_iot_provisioning_client_init( // /registrations//api-version= AZ_NODISCARD az_result az_iot_provisioning_client_get_user_name( - az_iot_provisioning_client const* const client, + az_iot_provisioning_client const* client, char* mqtt_user_name, size_t mqtt_user_name_size, size_t* out_mqtt_user_name_length) @@ -123,7 +123,7 @@ AZ_NODISCARD az_result az_iot_provisioning_client_get_user_name( // AZ_NODISCARD az_result az_iot_provisioning_client_get_client_id( - az_iot_provisioning_client const* const client, + az_iot_provisioning_client const* client, char* mqtt_client_id, size_t mqtt_client_id_size, size_t* out_mqtt_client_id_length) @@ -153,7 +153,7 @@ AZ_NODISCARD az_result az_iot_provisioning_client_get_client_id( // $dps/registrations/PUT/iotdps-register/?$rid=%s AZ_NODISCARD az_result az_iot_provisioning_client_register_get_publish_topic( - az_iot_provisioning_client const* const client, + az_iot_provisioning_client const* client, char* mqtt_topic, size_t mqtt_topic_size, size_t* out_mqtt_topic_length) @@ -187,7 +187,7 @@ AZ_NODISCARD az_result az_iot_provisioning_client_register_get_publish_topic( // Topic: $dps/registrations/GET/iotdps-get-operationstatus/?$rid=%s&operationId=%s AZ_NODISCARD az_result az_iot_provisioning_client_query_status_get_publish_topic( - az_iot_provisioning_client const* const client, + az_iot_provisioning_client const* client, az_span operation_id, char* mqtt_topic, size_t mqtt_topic_size, @@ -509,7 +509,7 @@ Stage 3: certificate.","timestampUtc":"2020-04-10T05:24:22.4718526Z"} */ AZ_NODISCARD az_result az_iot_provisioning_client_parse_received_topic_and_payload( - az_iot_provisioning_client const* const client, + az_iot_provisioning_client const* client, az_span received_topic, az_span received_payload, az_iot_provisioning_client_register_response* out_response) diff --git a/sdk/src/azure/iot/az_iot_provisioning_client_sas.c b/sdk/src/azure/iot/az_iot_provisioning_client_sas.c index a95070a903..a076c8a830 100644 --- a/sdk/src/azure/iot/az_iot_provisioning_client_sas.c +++ b/sdk/src/azure/iot/az_iot_provisioning_client_sas.c @@ -31,7 +31,7 @@ static const az_span skn_string = AZ_SPAN_LITERAL_FROM_STR(SAS_TOKEN_SKN); static const az_span se_string = AZ_SPAN_LITERAL_FROM_STR(SAS_TOKEN_SE); AZ_NODISCARD az_result az_iot_provisioning_client_sas_get_signature( - az_iot_provisioning_client const* const client, + az_iot_provisioning_client const* client, uint64_t token_expiration_epoch_time, az_span signature, az_span* out_signature) @@ -69,7 +69,7 @@ AZ_NODISCARD az_result az_iot_provisioning_client_sas_get_signature( } AZ_NODISCARD az_result az_iot_provisioning_client_sas_get_password( - az_iot_provisioning_client const* const client, + az_iot_provisioning_client const* client, az_span base64_hmac_sha256_signature, uint64_t token_expiration_epoch_time, az_span key_name, diff --git a/sdk/src/azure/platform/az_curl.c b/sdk/src/azure/platform/az_curl.c index df36148654..fff9e50ce3 100644 --- a/sdk/src/azure/platform/az_curl.c +++ b/sdk/src/azure/platform/az_curl.c @@ -108,7 +108,7 @@ static AZ_NODISCARD az_result _az_span_append_header_to_buffer( } static AZ_NODISCARD az_result -_az_http_client_curl_slist_append(struct curl_slist** ref_list, char const* const str) +_az_http_client_curl_slist_append(struct curl_slist** ref_list, char const* str) { _az_PRECONDITION_NOT_NULL(ref_list); _az_PRECONDITION_NOT_NULL(str); @@ -215,9 +215,8 @@ _az_http_client_curl_add_expect_header(CURL* ref_curl, struct curl_slist** ref_l * @param ref_headers list of headers in curl specific list * @return az_result */ -static AZ_NODISCARD az_result _az_http_client_curl_build_headers( - az_http_request const* const request, - struct curl_slist** ref_headers) +static AZ_NODISCARD az_result +_az_http_client_curl_build_headers(az_http_request const* request, struct curl_slist** ref_headers) { _az_PRECONDITION_NOT_NULL(request); @@ -317,7 +316,7 @@ static AZ_NODISCARD az_result _az_http_client_curl_send_delete_request(CURL* ref * handles POST request. It handles seting up a body for request */ static AZ_NODISCARD az_result -_az_http_client_curl_send_post_request(CURL* ref_curl, az_http_request const* const request) +_az_http_client_curl_send_post_request(CURL* ref_curl, az_http_request const* request) { _az_PRECONDITION_NOT_NULL(ref_curl); _az_PRECONDITION_NOT_NULL(request); @@ -407,7 +406,7 @@ static int32_t _az_http_client_curl_upload_read_callback( * As of CURL 7.12.1 CURLOPT_PUT is deprecated. PUT requests should be made using CURLOPT_UPLOAD */ static AZ_NODISCARD az_result -_az_http_client_curl_send_upload_request(CURL* ref_curl, az_http_request const* const request) +_az_http_client_curl_send_upload_request(CURL* ref_curl, az_http_request const* request) { _az_PRECONDITION_NOT_NULL(ref_curl); _az_PRECONDITION_NOT_NULL(request); @@ -445,7 +444,7 @@ _az_http_client_curl_send_upload_request(CURL* ref_curl, az_http_request const* static AZ_NODISCARD az_result _az_http_client_curl_setup_headers( CURL* ref_curl, struct curl_slist** ref_list, - az_http_request const* const request) + az_http_request const* request) { _az_PRECONDITION_NOT_NULL(ref_curl); _az_PRECONDITION_NOT_NULL(request); @@ -472,7 +471,7 @@ static AZ_NODISCARD az_result _az_http_client_curl_setup_headers( * @return az_result */ static AZ_NODISCARD az_result -_az_http_client_curl_setup_url(CURL* ref_curl, az_http_request const* const request) +_az_http_client_curl_setup_url(CURL* ref_curl, az_http_request const* request) { _az_PRECONDITION_NOT_NULL(ref_curl); _az_PRECONDITION_NOT_NULL(request); @@ -548,7 +547,7 @@ _az_http_client_curl_setup_response_redirect(CURL* ref_curl, az_http_response* r */ static AZ_NODISCARD az_result _az_http_client_curl_send_request_impl_process( CURL* ref_curl, - az_http_request const* const request, + az_http_request const* request, az_http_response* ref_response) { _az_PRECONDITION_NOT_NULL(ref_curl); @@ -598,7 +597,7 @@ static AZ_NODISCARD az_result _az_http_client_curl_send_request_impl_process( } AZ_NODISCARD az_result -az_http_client_send_request(az_http_request const* const request, az_http_response* ref_response) +az_http_client_send_request(az_http_request const* request, az_http_response* ref_response) { _az_PRECONDITION_NOT_NULL(request); _az_PRECONDITION_NOT_NULL(ref_response); diff --git a/sdk/src/azure/platform/az_nohttp.c b/sdk/src/azure/platform/az_nohttp.c index e3fb2caf8b..0e83785db5 100644 --- a/sdk/src/azure/platform/az_nohttp.c +++ b/sdk/src/azure/platform/az_nohttp.c @@ -6,7 +6,7 @@ #include AZ_NODISCARD az_result -az_http_client_send_request(az_http_request const* const request, az_http_response* ref_response) +az_http_client_send_request(az_http_request const* request, az_http_response* ref_response) { (void)request; (void)ref_response;