diff --git a/.github/workflows/azure-devops-pipelines-cg.yml b/.github/workflows/azure-devops-pipelines-cg.yml
index 9cd8e190..086abdc3 100644
--- a/.github/workflows/azure-devops-pipelines-cg.yml
+++ b/.github/workflows/azure-devops-pipelines-cg.yml
@@ -1,7 +1,7 @@
# This pipeline will be triggered when either main branch is pushed or 2AM on workdays.
variables:
- name: tags
- value: "nonproduction"
+ value: "production"
readonly: true
trigger:
branches:
@@ -20,7 +20,7 @@ resources:
name: 1ESPipelineTemplates/OfficePipelineTemplates
ref: refs/tags/release
extends:
- template: v1/Office.Unofficial.PipelineTemplate.yml@CustomPipelineTemplates
+ template: v1/Office.Official.PipelineTemplate.yml@CustomPipelineTemplates
parameters:
pool:
name: Azure-Pipelines-1ESPT-ExDShared
diff --git a/.github/workflows/release-azure-pipelines.yml b/.github/workflows/release-azure-pipelines.yml
index 0767004c..2b393026 100644
--- a/.github/workflows/release-azure-pipelines.yml
+++ b/.github/workflows/release-azure-pipelines.yml
@@ -2,7 +2,6 @@
parameters:
- name: version
type: string
- default: 0.8.6
- name: prerelease
displayName: Prerelease?
type: boolean
@@ -31,24 +30,28 @@ parameters:
variables:
- name: tags
- value: "nonproduction"
+ value: "production"
readonly: true
- name: pythonVersion
value: 3.10
readonly: true
+- name: artifactsPath
+ value: $(Build.ArtifactStagingDirectory)/azureauth-${{ parameters.version }}
+ readonly: true
trigger: none
+
pr: none
resources:
repositories:
- - repository: CustomPipelineTemplates
+ - repository: OfficePipelineTemplates
type: git
name: 1ESPipelineTemplates/OfficePipelineTemplates
ref: refs/tags/release
extends:
- template: v1/Office.Unofficial.PipelineTemplate.yml@CustomPipelineTemplates
+ template: v1/Office.Official.PipelineTemplate.yml@OfficePipelineTemplates
parameters:
pool:
name: Azure-Pipelines-1ESPT-ExDShared
@@ -59,6 +62,9 @@ extends:
name: Azure-Pipelines-1ESPT-ExDShared
image: windows-latest
os: windows
+ # This prevents auto-injected Roslyn task from running the build again.
+ roslyn:
+ copyLogsOnly: true
stages:
- stage: validate
displayName: Validate
@@ -66,16 +72,16 @@ extends:
- job: validate
displayName: Validate
steps:
- - checkout: self
- - task: UsePythonVersion@0
- displayName: Use Python $(pythonVersion)
- inputs:
- versionSpec: $(pythonVersion)
- - task: Bash@3
- inputs:
- targetType: inline
- script: |
- echo ${{ parameters.version }} | python ./bin/version.py
+ - checkout: self
+ - task: UsePythonVersion@0
+ displayName: Use Python $(pythonVersion)
+ inputs:
+ versionSpec: $(pythonVersion)
+ - task: Bash@3
+ inputs:
+ targetType: inline
+ script: |
+ echo ${{ parameters.version }} | python ./bin/version.py
- stage: build
displayName: Build
@@ -93,40 +99,278 @@ extends:
targetPath: dist/${{ config.runtime }}
artifactName: azureauth-${{ parameters.version }}-${{ config.runtime }}
steps:
- - checkout: self
- - task: UseDotNet@2
- displayName: Use .NET Core sdk 6.x
- inputs:
- version: 6.x
+ - checkout: self
+ - task: UseDotNet@2
+ displayName: Use .NET Core sdk 6.x
+ inputs:
+ version: 6.x
+ - task: NuGetToolInstaller@0
+ displayName: Use NuGet 6.x
+ inputs:
+ versionSpec: 6.x
+ - task: DotNetCoreCLI@2
+ displayName: Install dependencies
+ inputs:
+ command: restore
+ feedsToUse: select
+ vstsFeed: $(VSTS_FEED_ID)
+ includeNuGetOrg: false
+ arguments: --runtime ${{ config.runtime }}
+ # 1ES PT requires explicit build task for Roslyn analysis. Auto-injected Roslyn task will use build logs from this build.
+ - task: DotNetCoreCLI@2
+ displayName: Build projects
+ inputs:
+ command: 'build'
+ projects: '**/*.csproj'
+ - task: DotNetCoreCLI@2
+ displayName: Test
+ inputs:
+ command: test
+ arguments: --configuration release --no-restore
+ - task: DotNetCoreCLI@2
+ displayName: Build artifacts
+ env:
+ ADO_TOKEN: $(System.AccessToken)
+ inputs:
+ command: publish
+ projects: src/AzureAuth/AzureAuth.csproj
+ arguments: -p:Version=${{ parameters.version }} --configuration release --self-contained true --runtime ${{ config.runtime }} --output dist/${{ config.runtime }}
+ publishWebProjects: false
+ zipAfterPublish: false
+ modifyOutputPath: true
- - task: NuGetToolInstaller@0
- displayName: Use NuGet 6.x
- inputs:
- versionSpec: 6.x
+ - stage: sign
+ displayName: Sign
+ dependsOn: build
+ jobs:
+ - ${{ each config in parameters.buildConfigs }}:
+ - job: sign_${{ replace(config.runtime,'-', '_') }}
+ displayName: Signing ${{ config.runtime }}
+ pool:
+ name: Azure-Pipelines-1ESPT-ExDShared
+ image: windows-latest
+ os: windows
+ templateContext:
+ inputs:
+ - input: pipelineArtifact
+ artifactName: azureauth-${{ parameters.version }}-${{ config.runtime }}
+ targetPath: $(artifactsPath)-${{ config.runtime }}
+ outputs:
+ - output: pipelineArtifact
+ artifactName: azureauth-${{ parameters.version }}-${{ config.runtime }}-signed
+ targetPath: $(artifactsPath)-${{ config.runtime }}-signed
+ steps:
+ - task: EsrpCodeSigning@5
+ displayName: Sign artifacts win10-x64
+ condition: eq('${{ config.runtime }}', 'win10-x64')
+ inputs:
+ ConnectedServiceName: $(ESRP_KV_SERVICE_CONNECTION)
+ AppRegistrationClientId: $(SIGNING_AAD_ID)
+ AppRegistrationTenantId: $(SIGNING_TENANT_ID)
+ AuthAKVName: $(AZURE_VAULT)
+ AuthCertName: $(AZURE_VAULT_ESRP_AAD_CERT_NAME)
+ AuthSignCertName: $(AZURE_VAULT_ESRP_REQ_CERT_NAME)
+ FolderPath: $(artifactsPath)-${{ config.runtime }}/AzureAuth
+ Pattern: '*.dll,*.exe'
+ signConfigType: 'inlineSignParams'
+ inlineOperation: |
+ [
+ {
+ "KeyCode": "$(SIGNING_KEY_CODE_AUTHENTICODE)",
+ "OperationCode": "SigntoolSign",
+ "ToolName": "sign",
+ "ToolVersion": "1.0",
+ "Parameters": {
+ "OpusName": "Microsoft",
+ "OpusInfo": "https://www.microsoft.com",
+ "FileDigest": "/fd SHA256",
+ "PageHash": "/NPH",
+ "TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
+ }
+ },
+ {
+ "KeyCode": "$(SIGNING_KEY_CODE_AUTHENTICODE)",
+ "OperationCode": "SigntoolVerify",
+ "ToolName": "sign",
+ "ToolVersion": "1.0",
+ "Parameters": {}
+ }
+ ]
+ SessionTimeout: '60'
+ MaxConcurrency: '50'
+ MaxRetryAttempts: '5'
+ PendingAnalysisWaitTimeoutMinutes: '5'
+ # We need to zip the artifacts for osx before sending to ESRP for signing.
+ - task: ArchiveFiles@2
+ displayName: Codesigning - zip artifacts to send to ESRP
+ condition: startsWith('${{ config.runtime }}', 'osx')
+ inputs:
+ rootFolderOrFile: $(artifactsPath)-${{ config.runtime }}
+ includeRootFolder: false
+ archiveType: zip
+ archiveFile: $(artifactsPath)-${{ config.runtime }}.zip
+ - task: EsrpCodeSigning@5
+ displayName: Sign artifacts osx
+ condition: startsWith('${{ config.runtime }}', 'osx')
+ inputs:
+ ConnectedServiceName: $(ESRP_KV_SERVICE_CONNECTION)
+ AppRegistrationClientId: $(SIGNING_AAD_ID)
+ AppRegistrationTenantId: $(SIGNING_TENANT_ID)
+ AuthAKVName: $(AZURE_VAULT)
+ AuthCertName: $(AZURE_VAULT_ESRP_AAD_CERT_NAME)
+ AuthSignCertName: $(AZURE_VAULT_ESRP_REQ_CERT_NAME)
+ FolderPath: $(Build.ArtifactStagingDirectory)
+ Pattern: 'azureauth-${{ parameters.version }}-${{ config.runtime }}.zip'
+ signConfigType: 'inlineSignParams'
+ inlineOperation: |
+ [
+ {
+ "KeyCode": "$(SIGNING_KEY_CODE_MAC)",
+ "OperationCode": "MacAppDeveloperSign",
+ "ToolName": "sign",
+ "ToolVersion": "1.0",
+ "Parameters": {}
+ },
+ {
+ "KeyCode": "$(SIGNING_KEY_CODE_MAC)",
+ "OperationCode": "SigntoolVerify",
+ "ToolName": "sign",
+ "ToolVersion": "1.0",
+ "Parameters": {}
+ }
+ ]
+ SessionTimeout: '60'
+ MaxConcurrency: '50'
+ MaxRetryAttempts: '5'
+ PendingAnalysisWaitTimeoutMinutes: '5'
+ - task: ExtractFiles@1
+ displayName: Extract signed artifacts osx
+ condition: startsWith('${{ config.runtime }}', 'osx')
+ inputs:
+ archiveFilePatterns: $(artifactsPath)-${{ config.runtime }}.zip
+ destinationFolder: $(artifactsPath)-${{ config.runtime }}
+ cleanDestinationFolder: true
+ overwriteExistingFiles: true
+ # We rename the signed artifacts to avoid conflicts with the unsigned pipeline artifacts from the previous stage.
+ - task: PowerShell@2
+ displayName: Rename signed artifacts
+ inputs:
+ workingDirectory: $(Build.ArtifactStagingDirectory)
+ targetType: 'inline'
+ script: |
+ mv "azureauth-${{ parameters.version }}-${{ config.runtime }}" "azureauth-${{ parameters.version }}-${{ config.runtime }}-signed"
- - task: DotNetCoreCLI@2
- displayName: Install dependencies
- inputs:
- command: restore
- feedsToUse: select
- vstsFeed: $(vstsFeedId)
- includeNuGetOrg: false
- arguments: --runtime ${{ config.runtime }}
+ # Currently we package artifacts into the most commonly accessible archive format for their respective platforms.
+ - stage: package
+ displayName: Package
+ dependsOn: sign
+ jobs:
+ - job: package
+ displayName: Package
+ pool:
+ name: Azure-Pipelines-1ESPT-ExDShared
+ image: ubuntu-latest
+ os: linux
+ templateContext:
+ inputs:
+ - ${{ each config in parameters.buildConfigs }}:
+ - input: pipelineArtifact
+ artifactName: azureauth-${{ parameters.version }}-${{ config.runtime }}-signed
+ targetPath: $(artifactsPath)-${{ config.runtime }}-signed
+ outputs:
+ - output: pipelineArtifact
+ artifactName: azureauth-${{ parameters.version }}-packaged
+ targetPath: $(artifactsPath)-packaged
+ steps:
+ - task: PowerShell@2
+ displayName: Create directory to place packaged artifacts
+ inputs:
+ workingDirectory: $(Build.ArtifactStagingDirectory)
+ targetType: 'inline'
+ script: |
+ mkdir azureauth-${{ parameters.version }}-packaged
+ - task: ArchiveFiles@2
+ displayName: Create win10-x64 archive
+ inputs:
+ rootFolderOrFile: $(artifactsPath)-win10-x64-signed/AzureAuth
+ includeRootFolder: false
+ archiveType: zip
+ archiveFile: $(artifactsPath)-packaged/azureauth-${{ parameters.version }}-win10-x64.zip
+ - task: Bash@3
+ displayName: Prepare osx-x64 executables
+ inputs:
+ targetType: inline
+ workingDirectory: $(Build.ArtifactStagingDirectory)
+ script: |
+ cd azureauth-${{ parameters.version }}-osx-x64-signed/AzureAuth
+ chmod +x azureauth createdump *.dylib
+ - task: ArchiveFiles@2
+ displayName: Create osx-x64 archive
+ inputs:
+ rootFolderOrFile: $(artifactsPath)-osx-x64-signed/AzureAuth
+ includeRootFolder: false
+ archiveType: tar
+ tarCompression: gz
+ archiveFile: $(artifactsPath)-packaged/azureauth-${{ parameters.version }}-osx-x64.tar.gz
+ - task: Bash@3
+ displayName: Prepare osx-arm64 executables
+ inputs:
+ workingDirectory: $(Build.ArtifactStagingDirectory)
+ targetType: inline
+ script: |
+ cd azureauth-${{ parameters.version }}-osx-arm64-signed/AzureAuth
+ chmod +x azureauth createdump *.dylib
+ - task: ArchiveFiles@2
+ displayName: Create osx-arm64 archive
+ inputs:
+ rootFolderOrFile: $(artifactsPath)-osx-arm64-signed/AzureAuth
+ includeRootFolder: false
+ archiveType: tar
+ tarCompression: gz
+ archiveFile: $(artifactsPath)-packaged/azureauth-${{ parameters.version }}-osx-arm64.tar.gz
- - task: DotNetCoreCLI@2
- displayName: Test
- inputs:
- command: test
- arguments: --configuration release --no-restore
-
- - task: DotNetCoreCLI@2
- displayName: Build artifacts
- env:
- ADO_TOKEN: $(System.AccessToken)
- inputs:
- command: publish
- projects: src/AzureAuth/AzureAuth.csproj
- arguments: -p:Version=${{ parameters.version }} --configuration release --self-contained true --runtime ${{ config.runtime }} --output dist/${{ config.runtime }}
- publishWebProjects: false
- zipAfterPublish: false
- modifyOutputPath: true
\ No newline at end of file
+ - stage: release
+ displayName: Release
+ dependsOn: package
+ jobs:
+ - job: approval
+ displayName: Manual Approval
+ pool: server
+ timeoutInMinutes: 5760 # job times out in 4 days
+ steps:
+ - task: ManualValidation@0
+ timeoutInMinutes: 4320 # task times out in 3 days
+ inputs:
+ notifyUsers: $(REVIEWER)
+ instructions: 'Review the AzureAuth GitHub Release.'
+ - job: release
+ displayName: Release
+ dependsOn: approval
+ pool:
+ name: Azure-Pipelines-1ESPT-ExDShared
+ image: ubuntu-latest
+ os: linux
+ templateContext:
+ inputs:
+ - input: pipelineArtifact
+ artifactName: azureauth-${{ parameters.version }}-packaged
+ targetPath: $(artifactsPath)-packaged
+ steps:
+ - task: GitHubRelease@1
+ displayName: Create AzureAuth GitHub Release
+ inputs:
+ gitHubConnection: $(GITHUB_RELEASE_SERVICE_CONNECTION)
+ repositoryName: 'AzureAD/microsoft-authentication-cli'
+ action: 'create'
+ target: $(Build.SourceVersion)
+ tagSource: 'userSpecifiedTag'
+ tag: ${{ parameters.version }}
+ isPrerelease: ${{ parameters.prerelease }}
+ isDraft: false
+ addChangeLog: false
+ releaseNotesSource: 'inline'
+ releaseNotesInline: "Release ${{ parameters.version }}. See [`CHANGELOG.md`](https://github.com/AzureAD/microsoft-authentication-cli/blob/${{ parameters.version }}/CHANGELOG.md) for updates."
+ assets: |
+ $(artifactsPath)-packaged/azureauth-${{ parameters.version }}-win10-x64.zip
+ $(artifactsPath)-packaged/azureauth-${{ parameters.version }}-osx-x64.tar.gz
+ $(artifactsPath)-packaged/azureauth-${{ parameters.version }}-osx-arm64.tar.gz
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index fd96d892..00000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,269 +0,0 @@
-name: Release
-
-on:
- workflow_dispatch:
- inputs:
- version:
- description: 'Version'
- required: true
- type: string
- # We use SemVer, anything before 1.0.0 is a pre-release, but this could also include versions like 1.1.0-beta.
- prerelease:
- description: 'Prerelease'
- required: true
- default: true
- type: boolean
-
-jobs:
- # Special request from @kyle-rader and @goagain, so no one can create an invalid release.
- validate:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Setup Python
- uses: actions/setup-python@v4
- with:
- python-version: '3.10'
- - name: Validate version
- run: echo ${{ github.event.inputs.version }} | python ./bin/version.py
-
- build:
- permissions:
- actions: read
- contents: read
- security-events: write
- statuses: write
- id-token: write
-
- runs-on: ${{ matrix.os }}
- needs: [validate]
- strategy:
- matrix:
- # We build on Linux, but don't yet ship Linux because we can't easily sign those releases.
- runtime: [osx-x64, osx-arm64, win10-x64]
- include:
- # macos-latest (currently 14) breaks this flow. Refer https://github.com/actions/runner-images/issues/9766.
- - runtime: osx-x64
- os: macos-13
- - runtime: osx-arm64
- os: macos-13
- - runtime: win10-x64
- os: windows-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Get Azure DevOps Access Token
- id: getToken
- uses: "./.github/actions/get-ado-token"
- with:
- client-id: ${{ secrets.AZURE_RELEASE_WORKFLOW_CLIENT_ID }}
- tenant-id: ${{ secrets.AZURE_RELEASE_WORKFLOW_TENANT_ID }}
- organization: ${{ secrets.ADO_ORGANIZATION }}
-
- - name: Setup .NET 6
- uses: actions/setup-dotnet@v4
- with:
- dotnet-version: 6.0.x
-
- - name: Install dependencies
- run: dotnet restore --runtime ${{ matrix.runtime }}
- env:
- ADO_TOKEN: ${{ steps.getToken.outputs.token }}
- - name: Test
- run: dotnet test --no-restore --configuration release
-
- - name: Build artifacts
- run: dotnet publish src/AzureAuth/AzureAuth.csproj -p:Version=${{ github.event.inputs.version }} --configuration release --self-contained true --runtime ${{ matrix.runtime }} --output dist/${{ matrix.runtime }}
- env:
- ADO_TOKEN: ${{ steps.getToken.outputs.token }}
-
- - name: Upload artifacts
- uses: actions/upload-artifact@v3
- with:
- name: azureauth-${{ github.event.inputs.version }}-${{ matrix.runtime }}
- path: dist/${{ matrix.runtime }}
-
- analyze:
- runs-on: ubuntu-latest
- permissions:
- security-events: write
- id-token: write
- needs: [validate]
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Get Azure DevOps Access Token
- id: getToken
- uses: "./.github/actions/get-ado-token"
- with:
- client-id: ${{ secrets.AZURE_RELEASE_WORKFLOW_CLIENT_ID }}
- tenant-id: ${{ secrets.AZURE_RELEASE_WORKFLOW_TENANT_ID }}
- organization: ${{ secrets.ADO_ORGANIZATION }}
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v3
- with:
- languages: csharp
-
- # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@v3
- env:
- ADO_TOKEN: ${{ steps.getToken.outputs.token }}
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
- with:
- category: "/language:csharp"
-
- sign:
- # This step has to run on Windows because ESRPClient.exe is currently only available for that platform.
- runs-on: windows-latest
- needs: [build, analyze]
- strategy:
- matrix:
- runtime: [osx-x64, osx-arm64, win10-x64]
- permissions:
- id-token: write
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Setup Python
- uses: actions/setup-python@v4
- with:
- python-version: '3.10'
- - name: Setup NuGet
- uses: NuGet/setup-nuget@v1
- with:
- nuget-version: '5.x'
- - name: Get Azure DevOps Access Token
- id: getToken
- uses: "./.github/actions/get-ado-token"
- with:
- client-id: ${{ secrets.AZURE_RELEASE_WORKFLOW_CLIENT_ID }}
- tenant-id: ${{ secrets.AZURE_RELEASE_WORKFLOW_TENANT_ID }}
- organization: ${{ secrets.ADO_ORGANIZATION }}
- - name: Download ESRPClient.exe
- env:
- ESRP_VERSION: ${{ secrets.ESRP_VERSION }}
- NUGET_CREDENTIALS: ${{ steps.getToken.outputs.token }}
- run: |
- nuget sources add -Name esrp -Username esrp-downloader -Password $env:NUGET_CREDENTIALS -Source https://pkgs.dev.azure.com/office/_packaging/Office/nuget/v3/index.json
- nuget install Microsoft.EsrpClient -Version "$env:ESRP_VERSION" -OutputDirectory .\esrp -Source https://pkgs.dev.azure.com/office/_packaging/Office/nuget/v3/index.json
- - name: Login to Azure
- uses: azure/login@v1
- with:
- creds: ${{ secrets.AZURE_CREDENTIALS }}
- # We need these certificates installed so that we can run ESRPClient.exe.
- - name: Install certificates
- env:
- AZURE_SUBSCRIPTION: ${{ secrets.AZURE_SUBSCRIPTION }}
- AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
- ESRP_AAD_CERT_NAME: ${{ secrets.AZURE_VAULT_ESRP_AAD_CERT_NAME }}
- ESRP_REQ_CERT_NAME: ${{ secrets.AZURE_VAULT_ESRP_REQ_CERT_NAME }}
- run: |
- az keyvault secret download --subscription "$env:AZURE_SUBSCRIPTION" --vault-name "$env:AZURE_VAULT" --name "$env:ESRP_AAD_CERT_NAME" -f cert.pfx
- certutil -f -importpfx cert.pfx
- Remove-Item cert.pfx
-
- az keyvault secret download --subscription "$env:AZURE_SUBSCRIPTION" --vault-name "$env:AZURE_VAULT" --name "$env:ESRP_REQ_CERT_NAME" -f cert.pfx
- certutil -f -importpfx cert.pfx
- Remove-Item cert.pfx
- # We download all artifacts and overwrite them with signed files, but only upload ones which we can properly sign.
- - name: Download all artifacts
- uses: actions/download-artifact@v3
- - name: Sign artifacts
- env:
- SIGNING_AAD_ID: ${{ secrets.SIGNING_AAD_ID }}
- SIGNING_TENANT_ID: ${{ secrets.SIGNING_TENANT_ID }}
- SIGNING_KEY_CODE_AUTHENTICODE: ${{ secrets.SIGNING_KEY_CODE_AUTHENTICODE }}
- SIGNING_KEY_CODE_MAC: ${{ secrets.SIGNING_KEY_CODE_MAC }}
- SIGNING_KEY_CODE_LINUX: ${{ secrets.SIGNING_KEY_CODE_LINUX }}
- SIGNING_CUSTOMER_CORRELATION_ID: ${{ secrets.SIGNING_CUSTOMER_CORRELATION_ID }}
- ESRP_CLIENT_EXE: ".\\esrp\\Microsoft.EsrpClient.${{ secrets.ESRP_VERSION }}\\tools\\EsrpClient.exe"
- run: python .\bin\sign.py "$env:ESRP_CLIENT_EXE" --runtime=${{ matrix.runtime }} --source=azureauth-${{ github.event.inputs.version }}-${{ matrix.runtime }}
- - name: Upload signed artifacts
- uses: actions/upload-artifact@v3
- with:
- name: azureauth-${{ github.event.inputs.version }}-${{ matrix.runtime }}
- path: azureauth-${{ github.event.inputs.version }}-${{ matrix.runtime }}
-
-
- # Currently we package artifacts into the most commonly accessible archive format for their respective platforms.
- package:
- runs-on: ubuntu-latest
- needs: [sign]
- steps:
- - name: Download all artifacts
- uses: actions/download-artifact@v3
- - name: Install Zip
- run: sudo apt install -y zip
- - name: Create win10-x64 archive
- run: |
- cd azureauth-${{ github.event.inputs.version }}-win10-x64
- zip ../azureauth-${{ github.event.inputs.version }}-win10-x64.zip *
- - name: Upload win10-x64 artifact
- uses: actions/upload-artifact@v3
- with:
- name: azureauth-${{ github.event.inputs.version }}-win10-x64.zip
- path: azureauth-${{ github.event.inputs.version }}-win10-x64.zip
- - name: Create osx-x64 archive
- run: |
- cd azureauth-${{ github.event.inputs.version }}-osx-x64
- chmod +x azureauth createdump *.dylib
- tar -czf ../azureauth-${{ github.event.inputs.version }}-osx-x64.tar.gz *
- - name: Upload osx-x64 artifact
- uses: actions/upload-artifact@v3
- with:
- name: azureauth-${{ github.event.inputs.version }}-osx-x64.tar.gz
- path: azureauth-${{ github.event.inputs.version }}-osx-x64.tar.gz
- - name: Create osx-arm64 archive
- run: |
- cd azureauth-${{ github.event.inputs.version }}-osx-arm64
- chmod +x azureauth createdump *.dylib
- tar -czf ../azureauth-${{ github.event.inputs.version }}-osx-arm64.tar.gz *
- - name: Upload osx-arm64 artifact
- uses: actions/upload-artifact@v3
- with:
- name: azureauth-${{ github.event.inputs.version }}-osx-arm64.tar.gz
- path: azureauth-${{ github.event.inputs.version }}-osx-arm64.tar.gz
-
- release:
- runs-on: ubuntu-latest
- needs: [package]
- # The 'release' environment is what requires reviews before creating the release.
- environment:
- name: release
- # These permissions are required in order to use `softprops/action-gh-release` to upload.
- permissions:
- contents: write
- steps:
- - name: Download win10-x64 artifact
- uses: actions/download-artifact@v3
- with:
- name: azureauth-${{ github.event.inputs.version }}-win10-x64.zip
- - name: Download osx-x64 artifact
- uses: actions/download-artifact@v3
- with:
- name: azureauth-${{ github.event.inputs.version }}-osx-x64.tar.gz
- - name: Download osx-arm64 artifact
- uses: actions/download-artifact@v3
- with:
- name: azureauth-${{ github.event.inputs.version }}-osx-arm64.tar.gz
-
- - name: Create Release
- uses: softprops/action-gh-release@v1
- with:
- name: ${{ github.event.inputs.version }}
- body: "Release ${{ github.event.inputs.version }}. See [`CHANGELOG.md`](https://github.com/AzureAD/microsoft-authentication-cli/blob/${{ github.event.inputs.version }}/CHANGELOG.md) for updates."
- tag_name: ${{ github.event.inputs.version }}
- prerelease: ${{ github.event.inputs.prerelease }}
- files: |
- azureauth-${{ github.event.inputs.version }}-win10-x64.zip
- azureauth-${{ github.event.inputs.version }}-osx-x64.tar.gz
- azureauth-${{ github.event.inputs.version }}-osx-arm64.tar.gz
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1caba211..9ffa9326 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Changed
- Temporarily paused the publishing of Linux binaries.
+- Upgrade MSAL from `4.59.1` to `4.61.3`.
## [0.8.6] - 2024-04-25
### Changed
diff --git a/bin/mac/publish b/bin/mac/publish
index de326b85..9e8536ee 100755
--- a/bin/mac/publish
+++ b/bin/mac/publish
@@ -42,4 +42,4 @@ esac
#------------------------------------------
# Publish
-dotnet publish "$GIT_DIR/src/AzureAuth/AzureAuth.csproj" --self-contained true -r "$runtime" -c release -o $DIST $*
+$GIT_DIR/bin/mac/dotnet publish "$GIT_DIR/src/AzureAuth/AzureAuth.csproj" --self-contained true -r "$runtime" -c release -o $DIST $*
diff --git a/bin/requirements.txt b/bin/requirements.txt
index d245284e..9150348e 100644
--- a/bin/requirements.txt
+++ b/bin/requirements.txt
@@ -1,11 +1,11 @@
azure-devops==6.0.0b4
-certifi==2023.7.22
+certifi==2024.7.4
charset-normalizer==2.1.1
idna==3.7
isodate==0.6.1
msrest==0.6.21
oauthlib==3.2.2
-requests==2.31.0
+requests==2.32.0
requests-oauthlib==1.3.1
six==1.16.0
-urllib3==1.26.18
\ No newline at end of file
+urllib3==1.26.19
\ No newline at end of file
diff --git a/bin/sign.py b/bin/sign.py
deleted file mode 100644
index 2b48ad78..00000000
--- a/bin/sign.py
+++ /dev/null
@@ -1,367 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-
-"""A script which wraps ESRPClient.exe for code signing."""
-
-import json
-import os
-import subprocess
-import sys
-from argparse import ArgumentParser
-from argparse import ArgumentDefaultsHelpFormatter
-from argparse import Namespace
-from collections.abc import Iterator
-from collections.abc import Generator
-from contextlib import ExitStack
-from contextlib import contextmanager
-from pathlib import Path
-from typing import Any
-from zipfile import ZipFile
-from zipfile import ZIP_DEFLATED
-
-JSON = dict[str, Any] # A naive type alias for JSON.
-
-
-def sign_operation(key_code: str, operation: str) -> JSON:
- """Return the JSON signing operation for a given key code/operation."""
- return {
- "KeyCode": key_code,
- "OperationCode": operation,
- "Parameters": {
- "OpusName": "Microsoft",
- "OpusInfo": "http://www.microsoft.com",
- "FileDigest": '/fd "SHA256"',
- "PageHash": "/NPH",
- "TimeStamp": '/tr "http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer" /td sha256',
- },
- "ToolName": "sign",
- "ToolVersion": "1.0",
- }
-
-
-def sign_operation_linux(key_code: str, operation: str) -> JSON:
- return {
- "KeyCode": key_code,
- "OperationCode": operation,
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0",
- }
-
-
-def linux_sign(key_code: str) -> JSON:
- """Return the JSON for a `LinuxSign` operation."""
- return sign_operation_linux(key_code, operation="LinuxSign")
-
-
-def mac_app_developer_sign(key_code: str) -> JSON:
- """Return the JSON for a `MacAppDeveloperSign` operation."""
- return sign_operation(key_code, operation="MacAppDeveloperSign")
-
-
-def sign_tool_sign(key_code: str) -> JSON:
- """Return the JSON for a `SigntoolSign` operation."""
- return sign_operation(key_code, operation="SigntoolSign")
-
-
-def sign_tool_verify(key_code: str) -> JSON:
- """Return the JSON for a `SigntoolVerify` operation."""
- return {
- "KeyCode": key_code,
- "OperationCode": "SigntoolVerify",
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0",
- }
-
-
-def sign_request_file(source: Path, customer_correlation_id: str) -> JSON:
- """Return the JSON for a `SignRequestFiles` entry."""
- return {
- "CustomerCorrelationId": customer_correlation_id,
- "SourceLocation": source.name,
- "DestinationLocation": source.name,
- }
-
-
-def batch(source: Path, files: list[JSON], operations: list[JSON]) -> JSON:
- """Return a single signing batch for a given set of files and operations."""
- return {
- "SourceLocationType": "UNC",
- "SourceRootDirectory": str(source),
- "DestinationLocationType": "UNC",
- "DestinationRootDirectory": str(source),
- "SignRequestFiles": files,
- "SigningInfo": {"Operations": operations},
- }
-
-
-@contextmanager
-def windows_batches(
- source: Path,
- key_codes: dict[str, str],
- customer_correlation_id: str,
-) -> Generator[JSON, None, None]:
- """Yield the JSON signing batches for the win-x64 runtime."""
- files = [
- sign_request_file(path, customer_correlation_id)
- for path in source.iterdir()
- if path.suffix in [".exe", ".dll"] and path.is_file()
- ]
-
- key_code = key_codes["authenticode"]
- operations = [sign_tool_sign(key_code), sign_tool_verify(key_code)]
-
- # Yield the batches to ESRPClient.exe signing.
- yield {
- "Version": "1.0.0",
- "SignBatches": [batch(source, files, operations)],
- }
-
-
-@contextmanager
-def osx_batches(
- source: Path,
- key_codes: dict[str, str],
- customer_correlation_id: str,
-) -> Generator[JSON, None, None]:
- """Yield the JSON signing batches for the osx-x64 and osx-arm64 runtimes."""
- dlls = []
- dylibs = []
- dylibs_zip = source / "dylibs.zip"
-
- # Find .dlls and .dylibs (including azureauth).
- for path in source.iterdir():
- if path.suffix == ".dll" and path.is_file():
- dlls.append(path)
- elif (path.name == "azureauth" or path.suffix == ".dylib") and path.is_file():
- dylibs.append(path)
-
- with ZipFile(dylibs_zip, mode="w", compression=ZIP_DEFLATED) as file:
- for path in dylibs:
- file.write(path, path.relative_to(source))
-
- dll_files = [sign_request_file(dll, customer_correlation_id) for dll in dlls]
- dylib_files = [sign_request_file(dylibs_zip, customer_correlation_id)]
-
- authenticode_key_code = key_codes["authenticode"]
- mac_key_code = key_codes["mac"]
- dll_operations = [
- sign_tool_sign(authenticode_key_code),
- sign_tool_verify(authenticode_key_code),
- ]
- dylib_operations = [mac_app_developer_sign(mac_key_code)]
-
- # Yield the batches to ESRPClient.exe signing.
- yield {
- "Version": "1.0.0",
- "SignBatches": [
- batch(source, dll_files, dll_operations),
- batch(source, dylib_files, dylib_operations),
- ],
- }
-
- # At this point signing is finished. Extract the signed dylibs.
- with ZipFile(dylibs_zip, mode="r") as file:
- file.extractall(source)
- dylibs_zip.unlink()
-
-
-@contextmanager
-def linux_batches(
- source: Path,
- key_codes: dict[str, str],
- customer_correlation_id: str,
-) -> Generator[JSON, None, None]:
- """Yield the JSON signing batches for the linux-x64 runtime."""
- files = [
- sign_request_file(path, customer_correlation_id)
- for path in source.iterdir()
- if path.suffix in [".deb"] and path.is_file()
- ]
-
- key_code = key_codes["linux"]
- operations = [linux_sign(key_code)]
-
- # Yield the batches to ESRPClient.exe signing.
- yield {
- "Version": "1.0.0",
- "SignBatches": [batch(source, files, operations)],
- }
-
-
-def auth(tenant_id: str, client_id: str) -> JSON:
- """Return auth JSON metadata."""
- return {
- "Version": "1.0.0",
- "AuthenticationType": "AAD_CERT",
- "TenantId": tenant_id,
- "ClientId": client_id,
- "AuthCert": {
- "SubjectName": f"CN={client_id}.microsoft.com",
- "StoreLocation": "LocalMachine",
- "StoreName": "My",
- "SendX5c": "true",
- },
- "RequestSigningCert": {
- "SubjectName": f"CN={client_id}",
- "StoreLocation": "LocalMachine",
- "StoreName": "My",
- },
- }
-
-
-def policy() -> JSON:
- """Return policy JSON metadata."""
- return {
- "Version": "1.0.0",
- "Intent": "Product Release",
- "ContentType": "Signed Binaries",
- }
-
-
-@contextmanager
-def json_tempfile(path: Path, data: JSON) -> Generator[None, None, None]:
- """Create a JSON file with the given data and later remove it."""
- with path.open(mode="w") as file:
- json.dump(obj=data, fp=file, indent=2)
- yield
- path.unlink()
-
-
-def parse_env_vars(runtime: str) -> tuple[str, str, str, JSON]:
- """Parse and return environment variables"""
- try:
- aad_id = os.environ["SIGNING_AAD_ID"]
- tenant_id = os.environ["SIGNING_TENANT_ID"]
- customer_correlation_id = os.environ["SIGNING_CUSTOMER_CORRELATION_ID"]
- match runtime:
- case "win10-x64":
- # This key code is used for signing .exes and .dlls on both Windows and Mac.
- key_codes = {
- "authenticode": os.environ["SIGNING_KEY_CODE_AUTHENTICODE"]
- }
- case "osx-x64" | "osx-arm64":
- # SIGNING_KEY_CODE_AUTHENTICODE is used for signing .exes and .dlls on both Windows and Mac.
- # SIGNING_KEY_CODE_MAC is used for signing .dylibs on Macs.
- key_codes = {
- "authenticode": os.environ["SIGNING_KEY_CODE_AUTHENTICODE"],
- "mac": os.environ["SIGNING_KEY_CODE_MAC"],
- }
- case "linux-x64" | "linux-arm64":
- # This key code is used for signing .deb on Linux.
- key_codes = {"linux": os.environ["SIGNING_KEY_CODE_LINUX"]}
-
- return aad_id, tenant_id, customer_correlation_id, key_codes
- except KeyError as exc:
- # See https://stackoverflow.com/a/24999035/3288364.
- name = str(exc).replace("'", "")
- raise KeyError(f"Error: missing env var: {name}")
-
-
-def parse_args() -> Namespace:
- """Parse and return command line arguments."""
- cwd = Path.cwd()
- parser = ArgumentParser(
- description=__doc__,
- formatter_class=ArgumentDefaultsHelpFormatter,
- )
-
- parser.add_argument(
- "esrp_client",
- help="the path to the ESRPClient.exe binary",
- type=Path,
- )
- parser.add_argument(
- "--source",
- metavar="SRC",
- help="the source path",
- type=Path,
- default=str(cwd),
- )
- parser.add_argument(
- "--runtime",
- choices=["win10-x64", "osx-x64", "osx-arm64", "linux-x64"],
- help="the runtime of the build in source",
- default="win10-x64",
- )
-
- return parser.parse_args()
-
-
-def main() -> None:
- """Determine target runtime, generate inputs, and run ESRPClient.exe."""
- # 1. Parse command line arguments.
- args = parse_args()
- runtime = args.runtime.lower()
-
- # 2. Read env vars.
- aad_id, tenant_id, customer_correlation_id, key_codes = parse_env_vars(runtime)
-
- esrp_path = args.esrp_client.resolve()
- source_path = args.source.resolve()
- auth_path = Path("auth.json").resolve()
- policy_path = Path("policy.json").resolve()
- input_path = Path("input.json").resolve()
- output_path = Path("output.json").resolve()
-
- # 3. Determine runtime & create a batchmaker.
- match runtime:
- case "win10-x64":
- batchmaker = windows_batches(
- source=source_path,
- key_codes=key_codes,
- customer_correlation_id=customer_correlation_id,
- )
- case "osx-x64" | "osx-arm64":
- batchmaker = osx_batches(
- source=source_path,
- key_codes=key_codes,
- customer_correlation_id=customer_correlation_id,
- )
- case "linux-x64":
- batchmaker = linux_batches(
- source=source_path,
- key_codes=key_codes,
- customer_correlation_id=customer_correlation_id,
- )
- case _:
- # This should be unreachable because of argparse, but let's be safe.
- sys.exit(f"Error: Invalid runtime: {args.runtime}")
-
- # 4. Create the necessary context and run ESRPClient.
- esrp_args = [
- str(esrp_path),
- "sign",
- "-a",
- str(auth_path),
- "-i",
- str(input_path),
- "-p",
- str(policy_path),
- "-o",
- str(output_path),
- "-l",
- "Progress",
- ]
-
- # All temporary files created in this context should be cleaned up.
- with ExitStack() as stack:
- # Generate auth.json.
- auth_json = auth(tenant_id, aad_id)
- stack.enter_context(json_tempfile(auth_path, auth_json))
-
- # Generate policy.json.
- policy_json = policy()
- stack.enter_context(json_tempfile(policy_path, policy_json))
-
- # Generate input.json (and any supporting intermediate files).
- batches = stack.enter_context(batchmaker)
- stack.enter_context(json_tempfile(input_path, batches))
-
- # Run ESRPClient.exe.
- subprocess.run(esrp_args, check=True)
-
-
-if __name__ == "__main__":
- main()
diff --git a/src/AdoPat/AdoPat.csproj b/src/AdoPat/AdoPat.csproj
index 88deddb7..5e615c97 100644
--- a/src/AdoPat/AdoPat.csproj
+++ b/src/AdoPat/AdoPat.csproj
@@ -6,14 +6,18 @@
Microsoft.Authentication.AdoPat
-
+
-
+
+
+
+
+
diff --git a/src/MSALWrapper.Benchmark/BrokerBenchmark.cs b/src/MSALWrapper.Benchmark/BrokerBenchmark.cs
index b986b6ef..5c030136 100644
--- a/src/MSALWrapper.Benchmark/BrokerBenchmark.cs
+++ b/src/MSALWrapper.Benchmark/BrokerBenchmark.cs
@@ -44,7 +44,6 @@ public BrokerBenchmark()
public void WarmUp()
{
NativeBrokerBenchmark();
- ManagedBrokerBenchmark();
}
///
@@ -53,27 +52,14 @@ public void WarmUp()
[Benchmark]
public void NativeBrokerBenchmark()
{
- var pcaWrapper = BuildPCAWrapper(this.logger, this.clientID, this.tenantID, true);
+ var pcaWrapper = BuildPCAWrapper(this.logger, this.clientID, this.tenantID);
AuthParameters authParameters = new AuthParameters(this.clientID, this.tenantID, this.scopes);
Broker broker = new Broker(this.logger, authParameters, pcaWrapper: pcaWrapper);
broker.GetTokenAsync().Wait();
}
- ///
- /// Benchmark with .Net managed broker.
- ///
- [Benchmark]
- public void ManagedBrokerBenchmark()
- {
- var pcaWrapper = BuildPCAWrapper(this.logger, this.clientID, this.tenantID, false);
- AuthParameters authParameters = new AuthParameters(this.clientID, this.tenantID, this.scopes);
- Broker broker = new Broker(this.logger, authParameters, pcaWrapper: pcaWrapper);
-
- broker.GetTokenAsync().Wait();
- }
-
- private IPCAWrapper BuildPCAWrapper(ILogger logger, Guid clientId, Guid tenantId, bool useNativeBroker)
+ private IPCAWrapper BuildPCAWrapper(ILogger logger, Guid clientId, Guid tenantId)
{
IList errors = new List();
@@ -87,14 +73,7 @@ private IPCAWrapper BuildPCAWrapper(ILogger logger, Guid clientId, Guid tenantId
enablePiiLogging: false,
enableDefaultPlatformLogging: true)
;
- if (useNativeBroker)
- {
- clientBuilder.WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows));
- }
- else
- {
- clientBuilder.WithBroker();
- }
+ clientBuilder.WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows));
return new PCAWrapper(logger, clientBuilder.Build(), errors, tenantId);
}
diff --git a/src/MSALWrapper.Benchmark/MSALWrapper.Benchmark.csproj b/src/MSALWrapper.Benchmark/MSALWrapper.Benchmark.csproj
index 2652e4db..2e2c3892 100644
--- a/src/MSALWrapper.Benchmark/MSALWrapper.Benchmark.csproj
+++ b/src/MSALWrapper.Benchmark/MSALWrapper.Benchmark.csproj
@@ -21,7 +21,7 @@
-
+
@@ -31,7 +31,7 @@
- 4.59.1
+ 4.61.3
@@ -41,6 +41,6 @@
-
+
diff --git a/src/MSALWrapper/MSALWrapper.csproj b/src/MSALWrapper/MSALWrapper.csproj
index cc2fed03..9a3229d8 100644
--- a/src/MSALWrapper/MSALWrapper.csproj
+++ b/src/MSALWrapper/MSALWrapper.csproj
@@ -30,10 +30,10 @@
-
+
-
-
+
+