From deec322b41b11ea144b2341ceb4b29b0aa147a57 Mon Sep 17 00:00:00 2001 From: Mattias Karlsson Date: Wed, 11 Nov 2026 22:54:51 +0100 Subject: [PATCH] Use Cake 7 GitHub Actions OIDC workload identity for Azure instead of client secret --- .github/workflows/build.yml | 18 +++--------------- build/records.cs | 8 ++++++++ cake.cs | 23 +++++++++++++++++++---- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index caf4726..e30fe4f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,9 +22,6 @@ jobs: os: [windows-latest, ubuntu-latest, macos-latest] env: TRUSTED_INGEST: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') }} - AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} - AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} - AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} steps: - name: Get the sources uses: actions/checkout@v7 @@ -48,14 +45,6 @@ jobs: with: user: ${{ secrets.NUGET_USER }} - - name: Azure login - if: ${{ env.TRUSTED_INGEST == 'true' && env.AZURE_CLIENT_ID != '' && env.AZURE_TENANT_ID != '' && env.AZURE_SUBSCRIPTION_ID != '' }} - uses: azure/login@v3 - with: - client-id: ${{ env.AZURE_CLIENT_ID }} - tenant-id: ${{ env.AZURE_TENANT_ID }} - subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }} - - name: Run Cake script uses: cake-build/cake-action@v3 env: @@ -65,11 +54,10 @@ jobs: NUGET_SOURCE: ${{ secrets.NUGET_SOURCE }} NUGET_APIKEY: ${{ steps.login.outputs.NUGET_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} - AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} - AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} + AZURE_TENANT_ID: ${{ env.TRUSTED_INGEST == 'true' && secrets.AZURE_TENANT_ID || '' }} + AZURE_CLIENT_ID: ${{ env.TRUSTED_INGEST == 'true' && secrets.AZURE_CLIENT_ID || '' }} AZURE_AUTHORITY_HOST: "https://login.microsoftonline.com" - AZURE_STORAGE_ACCOUNT: ${{ secrets.AZURE_STORAGE_ACCOUNT }} + AZURE_STORAGE_ACCOUNT: ${{ env.TRUSTED_INGEST == 'true' && secrets.AZURE_STORAGE_ACCOUNT || '' }} AZURE_STORAGE_ACCOUNT_CONTAINER: ${{ secrets.AZURE_STORAGE_ACCOUNT_CONTAINER }}${{ matrix.os }} with: file-path: cake.cs diff --git a/build/records.cs b/build/records.cs index 62deada..71fb7c1 100644 --- a/build/records.cs +++ b/build/records.cs @@ -61,10 +61,14 @@ public bool ShouldReportDPI() => public string? AzureStorageAccountContainer { get; } = System.Environment.GetEnvironmentVariable("AZURE_STORAGE_ACCOUNT_CONTAINER"); + public bool ShouldPrepareAzureWorkloadIdentity() => GitHubActions.IsRunningOnGitHubActions && + AzureCredentials.WorkloadIdentitySpecified; + public bool ShouldRunIntegrationTests() => !string.IsNullOrWhiteSpace(AzureStorageAccount) && !string.IsNullOrWhiteSpace(AzureStorageAccountContainer) && ( AzureCredentials.AzureCredentialsSpecified || + ShouldPrepareAzureWorkloadIdentity() || IsLocalBuild ); } @@ -80,6 +84,10 @@ public record AzureCredentials( !string.IsNullOrWhiteSpace(ClientId) && !string.IsNullOrWhiteSpace(ClientSecret) && !string.IsNullOrWhiteSpace(AuthorityHost); + + public bool WorkloadIdentitySpecified { get; } = !string.IsNullOrWhiteSpace(TenantId) && + !string.IsNullOrWhiteSpace(ClientId) && + string.IsNullOrWhiteSpace(ClientSecret); } internal record ExtensionHelper(Func TaskCreate, Func Run); diff --git a/cake.cs b/cake.cs index 2ac6200..69437b4 100644 --- a/cake.cs +++ b/cake.cs @@ -85,8 +85,23 @@ ) .Then("DPI") .Does( - static (context, data) => Command( - ["dpi", "dpi.exe"], + static async (context, data) => { + var workload = data.ShouldReportDPI() && data.ShouldPrepareAzureWorkloadIdentity() + ? await GitHubActions.Commands.AzurePrepareWorkloadIdentity(data.AzureCredentials.TenantId!, data.AzureCredentials.ClientId!) + : null; + + Command( + new CommandSettings { + ToolName = "dpi", + ToolExecutableNames = ["dpi", "dpi.exe"], + EnvironmentVariables = workload is null + ? new Dictionary() + : new Dictionary { + ["AZURE_TENANT_ID"] = workload.TenantId, + ["AZURE_CLIENT_ID"] = workload.ClientId, + ["AZURE_FEDERATED_TOKEN_FILE"] = workload.FederatedTokenFile.FullPath + } + }, new ProcessArgumentBuilder() .Append("nuget") .Append("--silent") @@ -97,8 +112,8 @@ : "analyze" ) .AppendSwitchQuoted("--buildversion", data.Version) - - ) + ); + } ) .Then("Build") .Does(