From 658b19f46b4c8325cdad0a218dfd33d7a373a9bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 03:18:56 +0000 Subject: [PATCH 1/7] chore(deps): bump Microsoft.NET.Test.Sdk from 17.9.0 to 17.12.0 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.9.0 to 17.12.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.9.0...v17.12.0) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .../GraphODataTemplateWriter.Test.csproj | 2 +- test/Typewriter.Test/Typewriter.Test.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GraphODataTemplateWriter.Test/GraphODataTemplateWriter.Test.csproj b/GraphODataTemplateWriter.Test/GraphODataTemplateWriter.Test.csproj index 5ab1c034e..bd65ad134 100644 --- a/GraphODataTemplateWriter.Test/GraphODataTemplateWriter.Test.csproj +++ b/GraphODataTemplateWriter.Test/GraphODataTemplateWriter.Test.csproj @@ -16,7 +16,7 @@ - + 3.7.1 diff --git a/test/Typewriter.Test/Typewriter.Test.csproj b/test/Typewriter.Test/Typewriter.Test.csproj index ce7f26e29..34018ae7b 100644 --- a/test/Typewriter.Test/Typewriter.Test.csproj +++ b/test/Typewriter.Test/Typewriter.Test.csproj @@ -37,7 +37,7 @@ - + 4.2.2 From 9f748d826014a3848b76017d463ad0037678ebc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 10:22:35 +0300 Subject: [PATCH 2/7] chore(deps): bump NUnit from 4.2.2 to 4.3.2 (#1321) Bumps [NUnit](https://github.com/nunit/nunit) from 4.2.2 to 4.3.2. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/4.2.2...4.3.2) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- test/Typewriter.Test/Typewriter.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Typewriter.Test/Typewriter.Test.csproj b/test/Typewriter.Test/Typewriter.Test.csproj index 34018ae7b..e125ea93f 100644 --- a/test/Typewriter.Test/Typewriter.Test.csproj +++ b/test/Typewriter.Test/Typewriter.Test.csproj @@ -39,7 +39,7 @@ - 4.2.2 + 4.3.2 4.6.0 From 76628e75ea0c4c053f2230a63cc5dd553a57a191 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 03:51:05 +0000 Subject: [PATCH 3/7] chore(deps): bump Microsoft.CodeAnalysis.CSharp from 4.11.0 to 4.12.0 Bumps [Microsoft.CodeAnalysis.CSharp](https://github.com/dotnet/roslyn) from 4.11.0 to 4.12.0. - [Release notes](https://github.com/dotnet/roslyn/releases) - [Changelog](https://github.com/dotnet/roslyn/blob/main/docs/Breaking%20API%20Changes.md) - [Commits](https://github.com/dotnet/roslyn/commits) --- updated-dependencies: - dependency-name: Microsoft.CodeAnalysis.CSharp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/GraphODataTemplateWriter/GraphODataTemplateWriter.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GraphODataTemplateWriter/GraphODataTemplateWriter.csproj b/src/GraphODataTemplateWriter/GraphODataTemplateWriter.csproj index b7f7e684c..7d1e23bab 100644 --- a/src/GraphODataTemplateWriter/GraphODataTemplateWriter.csproj +++ b/src/GraphODataTemplateWriter/GraphODataTemplateWriter.csproj @@ -36,7 +36,7 @@ - + 3.0.0 From 388bb06c6848c8a33e7f18e313a39e0f935a4873 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 03:44:27 +0000 Subject: [PATCH 4/7] chore(deps): bump actions/setup-dotnet from 4.2.0 to 4.3.0 Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 4.2.0 to 4.3.0. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v4.2.0...v4.3.0) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b2b2f7bcb..224d4f7d3 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,7 +16,7 @@ jobs: with: submodules: recursive - name: Setup .NET - uses: actions/setup-dotnet@v4.2.0 + uses: actions/setup-dotnet@v4.3.0 with: dotnet-version: 8.0.x - name: Restore dependencies From f31f67acdfe988900ce974984e066a903856cfc6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2025 03:05:33 +0000 Subject: [PATCH 5/7] chore(deps): bump submodules/vipr from `6c62ff0` to `834d1a8` Bumps [submodules/vipr](https://github.com/microsoft/vipr) from `6c62ff0` to `834d1a8`. - [Release notes](https://github.com/microsoft/vipr/releases) - [Commits](https://github.com/microsoft/vipr/compare/6c62ff0ea3147062bb12888ee7dded395e867c69...834d1a8af3375f5ef98990e47c26a369666e87f5) --- updated-dependencies: - dependency-name: submodules/vipr dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- submodules/vipr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/vipr b/submodules/vipr index 6c62ff0ea..834d1a8af 160000 --- a/submodules/vipr +++ b/submodules/vipr @@ -1 +1 @@ -Subproject commit 6c62ff0ea3147062bb12888ee7dded395e867c69 +Subproject commit 834d1a8af3375f5ef98990e47c26a369666e87f5 From 8255fc956c04796a679b942dccf0bde0bfa6ca6a Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Wed, 5 Feb 2025 09:56:05 +0300 Subject: [PATCH 6/7] ci: generate pull requests using Github application --- .azure-pipelines/generation-pipeline.yml | 23 -- .../language-generation-kiota.yml | 18 +- .../language-generation.yml | 18 +- scripts/Generate-Github-Token.ps1 | 201 ++++++++++++++++++ scripts/create-pull-request.ps1 | 9 +- 5 files changed, 236 insertions(+), 33 deletions(-) create mode 100644 scripts/Generate-Github-Token.ps1 diff --git a/.azure-pipelines/generation-pipeline.yml b/.azure-pipelines/generation-pipeline.yml index 9857e7b82..0ec8a4b0f 100644 --- a/.azure-pipelines/generation-pipeline.yml +++ b/.azure-pipelines/generation-pipeline.yml @@ -805,26 +805,3 @@ stages: repoName: msgraph-beta-cli projectFile: src/msgraph-beta-cli.csproj -# - stage: stage_objc_v1 -# dependsOn: -# - stage_build_and_publish_typewriter -# - stage_v1_metadata -# condition: | -# and -# ( -# eq(dependencies.stage_build_and_publish_typewriter.result, 'Succeeded'), -# in(dependencies.stage_v1_metadata.result, 'Succeeded', 'Skipped') -# ) -# jobs: -# - job: objc_v1 -# steps: -# - template: generation-templates/language-generation.yml -# parameters: -# language: 'ObjC' -# version: '' -# repoName: 'msgraph-sdk-objc-models' -# branchName: $(v1Branch) -# cleanMetadataFile: $(cleanMetadataFileV1) -# cleanMetadataFolder: $(cleanMetadataFolderV1) -# languageSpecificSteps: -# - template: generation-templates/objc.yml diff --git a/.azure-pipelines/generation-templates/language-generation-kiota.yml b/.azure-pipelines/generation-templates/language-generation-kiota.yml index ed89366e5..47c4fe8a7 100644 --- a/.azure-pipelines/generation-templates/language-generation-kiota.yml +++ b/.azure-pipelines/generation-templates/language-generation-kiota.yml @@ -102,12 +102,22 @@ steps: CommitMessagePrefix: ${{ parameters.commitMessagePrefix }} workingDirectory: ${{ parameters.repoName }} +- task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: "Federated AKV Managed Identity Connection" + KeyVaultName: akv-prod-eastus + SecretsFilter: "microsoft-graph-devx-bot-appid,microsoft-graph-devx-bot-privatekey" + - pwsh: '$(scriptsDirectory)/create-pull-request.ps1' - displayName: 'Create Pull Request for the generated build' + displayName: 'Create Pull Request for the generated build for ${{ parameters.repoName }}' env: - Version: ${{ parameters.version }} BaseBranch: ${{ parameters.baseBranchName}} - OverrideSkipCI: $(overrideSkipCI) - GITHUB_TOKEN: $(GithubAuthToken) GeneratePullRequest: ${{ parameters.generatePullRequest}} + GhAppId: $(microsoft-graph-devx-bot-appid) + GhAppKey: $(microsoft-graph-devx-bot-privatekey) + OverrideSkipCI: $(overrideSkipCI) + RepoName: ${{ parameters.repoName }} + ScriptsDirectory: $(scriptsDirectory) + Version: ${{ parameters.version }} workingDirectory: ${{ parameters.repoName }} diff --git a/.azure-pipelines/generation-templates/language-generation.yml b/.azure-pipelines/generation-templates/language-generation.yml index b184420f2..f46bf0ff9 100644 --- a/.azure-pipelines/generation-templates/language-generation.yml +++ b/.azure-pipelines/generation-templates/language-generation.yml @@ -80,12 +80,22 @@ steps: OverrideSkipCI: $(overrideSkipCI) workingDirectory: ${{ parameters.repoName }} +- task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: "Federated AKV Managed Identity Connection" + KeyVaultName: akv-prod-eastus + SecretsFilter: "microsoft-graph-devx-bot-appid,microsoft-graph-devx-bot-privatekey" + - pwsh: '$(scriptsDirectory)/create-pull-request.ps1' - displayName: 'Create Pull Request for the generated build' + displayName: 'Create Pull Request for the generated build for ${{ parameters.repoName }}' env: - Version: ${{ parameters.version }} BaseBranch: ${{ parameters.baseBranchName}} - OverrideSkipCI: $(overrideSkipCI) - GITHUB_TOKEN: $(GithubAuthToken) GeneratePullRequest: ${{ parameters.generatePullRequest}} + GhAppId: $(microsoft-graph-devx-bot-appid) + GhAppKey: $(microsoft-graph-devx-bot-privatekey) + OverrideSkipCI: $(overrideSkipCI) + RepoName: ${{ parameters.repoName }} + ScriptsDirectory: $(scriptsDirectory) + Version: ${{ parameters.version }} workingDirectory: ${{ parameters.repoName }} diff --git a/scripts/Generate-Github-Token.ps1 b/scripts/Generate-Github-Token.ps1 new file mode 100644 index 000000000..0b1c04160 --- /dev/null +++ b/scripts/Generate-Github-Token.ps1 @@ -0,0 +1,201 @@ +[CmdletBinding()] +param ( + [Parameter(Mandatory = $true)] + [string] + $AppClientId, + [Parameter(Mandatory = $true)] + [string] + $AppPrivateKeyContents, + [Parameter(Mandatory = $true)] + [ValidatePattern('^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$', ErrorMessage = "Repository must be in the format 'owner/repo' (e.g. 'octocat/hello-world')")] + [string] + $Repository +) + +$ErrorActionPreference = "Stop" + +function Generate-AppToken { + param ( + [string] + $ClientId, + [string] + $PrivateKeyContents + ) + + $header = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json -InputObject @{ + alg = "RS256" + typ = "JWT" + }))).TrimEnd('=').Replace('+', '-').Replace('/', '_'); + + $payload = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json -InputObject @{ + iat = [System.DateTimeOffset]::UtcNow.AddSeconds(-10).ToUnixTimeSeconds() + exp = [System.DateTimeOffset]::UtcNow.AddMinutes(1).ToUnixTimeSeconds() + iss = $ClientId + }))).TrimEnd('=').Replace('+', '-').Replace('/', '_'); + + $rsa = [System.Security.Cryptography.RSA]::Create() + $rsa.ImportFromPem($PrivateKeyContents) + + $signature = [Convert]::ToBase64String($rsa.SignData([System.Text.Encoding]::UTF8.GetBytes("$header.$payload"), [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)).TrimEnd('=').Replace('+', '-').Replace('/', '_') + $jwt = "$header.$payload.$signature" + + return $jwt +} + +function Generate-InstallationToken { + param ( + [string] + $AppToken, + [string] + $InstallationId, + [string] + $Repository + ) + + $uri = "https://api.github.com/app/installations/$InstallationId/access_tokens" + $headers = @{ + Authorization = "Bearer $AppToken" + Accept = "application/vnd.github+json" + "X-GitHub-Api-Version" = "2022-11-28" + } + + $body = @{ + repositories = @($Repository) + } + + $response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body (ConvertTo-Json -InputObject $body -Compress -Depth 10) + + return $response.token +} + + +function Get-OrganizationInstallationId { + param ( + [string] + $AppToken, + [string] + $Organization + ) + + $uri = "https://api.github.com/orgs/$Organization/installation" + $headers = @{ + Authorization = "Bearer $AppToken" + Accept = "application/vnd.github+json" + "X-GitHub-Api-Version" = "2022-11-28" + } + + try { + $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers + + return $response.id + } + catch [Microsoft.PowerShell.Commands.HttpResponseException] { + if ($_.Exception.Response.StatusCode -eq [System.Net.HttpStatusCode]::UnprocessableContent -or $_.Exception.Response.StatusCode -eq [System.Net.HttpStatusCode]::NotFound) { + return $null + } + + throw + } +} + +function Get-RepositoryInstallationId { + param ( + [string] + $AppToken, + [string] + $Repository + ) + + $uri = "https://api.github.com/repos/$Repository/installation" + $headers = @{ + Authorization = "Bearer $AppToken" + Accept = "application/vnd.github+json" + "X-GitHub-Api-Version" = "2022-11-28" + } + + try { + $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers + + return $response.id + } + catch [Microsoft.PowerShell.Commands.HttpResponseException] { + if ($_.Exception.Response.StatusCode -eq [System.Net.HttpStatusCode]::UnprocessableContent -or $_.Exception.Response.StatusCode -eq [System.Net.HttpStatusCode]::NotFound) { + return $null + } + + throw + } +} + +function Get-UserInstallationId { + param ( + [string] + $AppToken, + [string] + $Username + ) + + $uri = "https://api.github.com/users/$Username/installation" + $headers = @{ + Authorization = "Bearer $AppToken" + Accept = "application/vnd.github+json" + "X-GitHub-Api-Version" = "2022-11-28" + } + + try { + $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers + + return $response.id + } + catch [Microsoft.PowerShell.Commands.HttpResponseException] { + if ($_.Exception.Response.StatusCode -eq [System.Net.HttpStatusCode]::UnprocessableContent -or $_.Exception.Response.StatusCode -eq [System.Net.HttpStatusCode]::NotFound) { + return $null + } + + throw + } +} + +function Get-InstallationId { + param ( + [string] + $AppToken, + [string] + $Owner, + [string] + $Repo + ) + + $orgInstallationId = Get-OrganizationInstallationId -AppToken $AppToken -Organization $Owner + + if ($null -eq $orgInstallationId) { + $repoInstallationId = Get-RepositoryInstallationId -AppToken $AppToken -Repository "$Owner/$Repo" + } + else { + return $orgInstallationId + } + + if ($null -eq $repoInstallationId) { + $userInstallationId = Get-UserInstallationId -AppToken $AppToken -Username $Owner + } + else { + return $repoInstallationId + } + + if ($null -eq $userInstallationId) { + throw "Installation not found for repository '$Repo'" + } + else { + return $userInstallationId + } +} + +$owner, $repo = $Repository -split '/' + +$AppToken = Generate-AppToken -ClientId $AppClientId -PrivateKeyContents $AppPrivateKeyContents + +$InstallationId = Get-InstallationId -AppToken $AppToken -Owner $owner -Repo $repo + +$InstallationToken = Generate-InstallationToken -AppToken $AppToken -InstallationId $InstallationId -Repository $repo + +Write-Output $InstallationToken \ No newline at end of file diff --git a/scripts/create-pull-request.ps1 b/scripts/create-pull-request.ps1 index e8af62fbc..3478a084a 100644 --- a/scripts/create-pull-request.ps1 +++ b/scripts/create-pull-request.ps1 @@ -11,7 +11,7 @@ if (($env:GeneratePullRequest -eq $False)) { # Skip CI if manually running this $version = $env:Version $title = "Generated $version models and request builders" -$body = "This pull request was automatically created by Azure Pipelines. **Important** Check for unexpected deletions or changes in this PR." +$body = ":bangbang:**_Important_**:bangbang:
Check for unexpected deletions or changes in this PR and ensure relevant CI checks are passing.

**Note:** This pull request was automatically created by Azure pipelines." $baseBranchParameter = "" if (![string]::IsNullOrEmpty($env:BaseBranch)) @@ -19,7 +19,12 @@ if (![string]::IsNullOrEmpty($env:BaseBranch)) $baseBranchParameter = "-B $env:BaseBranch" # optionally pass the base branch if provided as the PR will target the default branch otherwise } - # No need to specify reviewers as code owners should be added automatically. +# The installed application is required to have the following permissions: read/write on pull requests/ +$tokenGenerationScript = "$env:ScriptsDirectory\Generate-Github-Token.ps1" +$env:GITHUB_TOKEN = & $tokenGenerationScript -AppClientId $env:GhAppId -AppPrivateKeyContents $env:GhAppKey -Repository $env:RepoName +Write-Host "Fetched Github Token for PR generation and set as environment variable." -ForegroundColor Green + +# No need to specify reviewers as code owners should be added automatically. Invoke-Expression "gh auth login" # login to GitHub Invoke-Expression "gh pr create -t ""$title"" -b ""$body"" $baseBranchParameter | Write-Host" From 426d73ce4d32242f412f798efb8f9b1e294305fa Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Wed, 5 Feb 2025 11:21:54 +0300 Subject: [PATCH 7/7] chore: fix repo name parameter on refactor --- .../generation-templates/language-generation-kiota.yml | 2 +- .azure-pipelines/generation-templates/language-generation.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/generation-templates/language-generation-kiota.yml b/.azure-pipelines/generation-templates/language-generation-kiota.yml index 47c4fe8a7..23af8f8e9 100644 --- a/.azure-pipelines/generation-templates/language-generation-kiota.yml +++ b/.azure-pipelines/generation-templates/language-generation-kiota.yml @@ -117,7 +117,7 @@ steps: GhAppId: $(microsoft-graph-devx-bot-appid) GhAppKey: $(microsoft-graph-devx-bot-privatekey) OverrideSkipCI: $(overrideSkipCI) - RepoName: ${{ parameters.repoName }} + RepoName: 'microsoftgraph/${{ parameters.repoName}}' # the assumption is that repo in the microsoftgraph org ScriptsDirectory: $(scriptsDirectory) Version: ${{ parameters.version }} workingDirectory: ${{ parameters.repoName }} diff --git a/.azure-pipelines/generation-templates/language-generation.yml b/.azure-pipelines/generation-templates/language-generation.yml index f46bf0ff9..0d7aa4757 100644 --- a/.azure-pipelines/generation-templates/language-generation.yml +++ b/.azure-pipelines/generation-templates/language-generation.yml @@ -95,7 +95,7 @@ steps: GhAppId: $(microsoft-graph-devx-bot-appid) GhAppKey: $(microsoft-graph-devx-bot-privatekey) OverrideSkipCI: $(overrideSkipCI) - RepoName: ${{ parameters.repoName }} + RepoName: 'microsoftgraph/${{ parameters.repoName}}' # the assumption is that repo in the microsoftgraph org ScriptsDirectory: $(scriptsDirectory) Version: ${{ parameters.version }} workingDirectory: ${{ parameters.repoName }}