Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
65b18be
Initial plan
Copilot Jan 16, 2026
492cd3b
Add code-coverage GitHub Actions workflow
Copilot Jan 16, 2026
f7fb76f
Fix YAML syntax in code-coverage workflow
Copilot Jan 16, 2026
214235d
Apply suggestion from @Copilot
cacosta33 Jan 16, 2026
c52a606
Apply suggestion from @Copilot
cacosta33 Jan 16, 2026
dd6cb21
Apply suggestions from code review
cacosta33 Jan 16, 2026
773e749
Fix 0.0% coverage issue with better error handling and debugging
Copilot Jan 16, 2026
98c096d
Fix gradle.properties parsing error causing build failure
Copilot Jan 16, 2026
7af1ddd
Pivot to Azure Pipeline for code coverage instead of GitHub Actions
Copilot Jan 20, 2026
20be74e
fix
fadidurah Jan 20, 2026
9cc64db
common
fadidurah Jan 28, 2026
08cf666
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
fadidurah Jan 28, 2026
2c82323
revert
fadidurah Jan 28, 2026
bae3a06
try code cov pipeline
fadidurah Jan 29, 2026
dc0a7e9
jacoco
fadidurah Jan 29, 2026
faee566
jacoco
fadidurah Jan 29, 2026
05e2731
jacoco
fadidurah Jan 29, 2026
d72bc1a
actually use jacoco
fadidurah Jan 29, 2026
a4f783b
actually use jacoco
fadidurah Jan 29, 2026
45e908f
actually use jacoco
fadidurah Jan 29, 2026
a33e982
limit to one test task
fadidurah Jan 29, 2026
769bc50
limit to one test task
fadidurah Jan 29, 2026
0a2a704
limit to one test task
fadidurah Jan 29, 2026
133b5f8
limit to one test task
fadidurah Jan 30, 2026
826bf61
limit to one test task
fadidurah Jan 30, 2026
e7c3acf
limit to one test task
fadidurah Jan 30, 2026
39adcee
limit to one test task
fadidurah Jan 30, 2026
fef82c2
limit to one test task
fadidurah Jan 31, 2026
48b349b
Fix Yaml
fadidurah Jan 31, 2026
89511d8
Fix Yaml
fadidurah Jan 31, 2026
22f2bea
comment out jobs for now
fadidurah Jan 31, 2026
19daab4
comment out jobs for now
fadidurah Jan 31, 2026
1aa01fd
comment out jobs for now
fadidurah Jan 31, 2026
c878ded
comment out jobs for now
fadidurah Jan 31, 2026
664ee44
fix gradle
fadidurah Jan 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions azure-pipelines/pull-request-validation/compare_coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import sys
import xml.etree.ElementTree as ET

def get_coverage(xml_path):
tree = ET.parse(xml_path)
root = tree.getroot()
counter = root.find(".//counter[@type='INSTRUCTION']")
covered = int(counter.attrib['covered'])
missed = int(counter.attrib['missed'])
return covered / (covered + missed)

pr_cov = get_coverage(sys.argv[1])
dev_cov = get_coverage(sys.argv[2])

print(f"PR branch coverage: {pr_cov:.2%}")
print(f"Dev branch coverage: {dev_cov:.2%}")

if pr_cov < dev_cov:
print("ERROR: PR branch coverage is lower than dev branch. Failing...")
sys.exit(1)
else:
print("SUCCESS: PR branch coverage is not lower than dev branch, this is acceptable!")
231 changes: 157 additions & 74 deletions azure-pipelines/pull-request-validation/pr-msal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,83 +24,166 @@ resources:
name: AzureAD/microsoft-authentication-library-common-for-android
ref: dev
endpoint: ANDROID_GITHUB
- repository: msal-dev
type: github
name: AzureAD/microsoft-authentication-library-for-android
ref: dev
endpoint: ANDROID_GITHUB

pool:
name: MSSecurity-1ES-Build-Agents-Pool
image: MSSecurity-1ES-Windows-2022
os: windows
jobs:
- job: build_test
displayName: Build & Test
cancelTimeoutInMinutes: 1
variables:
Codeql.Enabled: true
steps:
- checkout: self
clean: true
submodules: recursive
persistCredentials: True
- bash: |
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_USERNAME]VSTS"
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_ACCESSTOKEN]$(System.AccessToken)"
displayName: 'Set VSTS Fields in Environment'
- template: azure-pipelines/templates/steps/automation-cert.yml@common
- task: JavaToolInstaller@0
displayName: Use Java 17
inputs:
versionSpec: '17'
jdkArchitectureOption: x64
jdkSourceOption: PreInstalled
- task: CodeQL3000Init@0
- task: Gradle@2
name: Gradle1
displayName: Assemble Local
inputs:
tasks: clean msal:assembleLocal
publishJUnitResults: false
testResultsFiles: '**/build/test-results/TEST-*.xml'
jdkVersion: $(BuildParameters.jdkVersion)
jdkArchitecture: $(BuildParameters.jdkArchitecture)
sqGradlePluginVersion: 2.0.1
- task: CodeQL3000Finalize@0
- task: Gradle@2
displayName: Run Unit tests
inputs:
tasks: msal:testLocalDebugUnitTest -Plabtest -PlabSecret=$(LabVaultAppCert) -ProbolectricSdkVersion=${{variables.robolectricSdkVersion}} -PmockApiUrl=$(MOCK_API_URL) -PnativeAuthConfigString=$(NATIVE_AUTH_CONFIG_STRING)
javaHomeSelection: $(BuildParameters.javaHomeSelection)
jdkVersion: 1.17
- job: spotbugs
displayName: SpotBugs
cancelTimeoutInMinutes: 1
steps:
- checkout: self
clean: true
submodules: recursive
persistCredentials: True
- bash: |
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_USERNAME]VSTS"
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_ACCESSTOKEN]$(System.AccessToken)"
displayName: 'Set VSTS Fields in Environment'
- template: azure-pipelines/templates/steps/spotbugs.yml@common
parameters:
project: msal
- job: lint
displayName: Lint
cancelTimeoutInMinutes: 1
steps:
- checkout: self
clean: true
submodules: recursive
persistCredentials: True
- bash: |
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_USERNAME]VSTS"
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_ACCESSTOKEN]$(System.AccessToken)"
displayName: 'Set VSTS Fields in Environment'
- task: Gradle@3
displayName: Lint Local debug
inputs:
tasks: clean msal:lintLocalDebug
publishJUnitResults: false
jdkVersion: 1.17

stages:
- stage: build_and_test
displayName: Build and Test
jobs:
- job: build_test
displayName: Build & Test (PR Branch)
cancelTimeoutInMinutes: 1
variables:
Codeql.Enabled: true
steps:
- checkout: self
clean: true
submodules: recursive
persistCredentials: True
- bash: |
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_USERNAME]VSTS"
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_ACCESSTOKEN]$(System.AccessToken)"
displayName: 'Set VSTS Fields in Environment'
- template: azure-pipelines/templates/steps/automation-cert.yml@common
- task: JavaToolInstaller@0
displayName: Use Java 17
inputs:
versionSpec: '17'
jdkArchitectureOption: x64
jdkSourceOption: PreInstalled
- task: CodeQL3000Init@0
- task: Gradle@2
name: Gradle1
displayName: Assemble Local
inputs:
tasks: clean msal:assembleLocal
publishJUnitResults: false
testResultsFiles: '**/build/test-results/TEST-*.xml'
jdkVersion: $(BuildParameters.jdkVersion)
jdkArchitecture: $(BuildParameters.jdkArchitecture)
sqGradlePluginVersion: 2.0.1
- task: CodeQL3000Finalize@0
- task: Gradle@2
displayName: Run Tests
inputs:
tasks: msal:jacocoTestReport -PcodeCoverageEnabled=true -ProbolectricSdkVersion=${{variables.robolectricSdkVersion}} -PmockApiUrl=$(MOCK_API_URL) -PnativeAuthConfigString=$(NATIVE_AUTH_CONFIG_STRING)
javaHomeSelection: $(BuildParameters.javaHomeSelection)
jdkVersion: 1.17
- script: tree "$(Build.SourcesDirectory)\msal" /F /A
displayName: 'Print File Structure Tree'
- publish: $(Build.SourcesDirectory)/msal/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml
artifact: jacocoReport
displayName: 'Publish JaCoCo Report Artifact (PR Branch)'
- task: PublishCodeCoverageResults@1
displayName: Publish Code Coverage Results
condition: always()
inputs:
codeCoverageTool: 'JaCoCo'
summaryFileLocation: '$(Build.SourcesDirectory)/msal/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml'
reportDirectory: '$(Build.SourcesDirectory)/msal/build/reports/jacoco/jacocoTestReport/html'
failIfCoverageEmpty: false
# This needs to be commented for now, because dev doesn't have the jacocoTestReport task yet, will uncomment in the next PR.
# - job: build_test_dev
# displayName: Build & Test (Dev)
# cancelTimeoutInMinutes: 1
# variables:
# Codeql.Enabled: true
# steps:
# - checkout: msal-dev
# clean: true
# submodules: recursive
# persistCredentials: True
# - bash: |
# echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_USERNAME]VSTS"
# echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_ACCESSTOKEN]$(System.AccessToken)"
# displayName: 'Set VSTS Fields in Environment'
# - template: azure-pipelines/templates/steps/automation-cert.yml@common
# - task: JavaToolInstaller@0
# displayName: Use Java 17
# inputs:
# versionSpec: '17'
# jdkArchitectureOption: x64
# jdkSourceOption: PreInstalled
# - task: CodeQL3000Init@0
# - task: Gradle@2
# name: Gradle1
# displayName: Assemble Local
# inputs:
# tasks: clean msal:assembleLocal
# publishJUnitResults: false
# testResultsFiles: '**/build/test-results/TEST-*.xml'
# jdkVersion: $(BuildParameters.jdkVersion)
# jdkArchitecture: $(BuildParameters.jdkArchitecture)
# sqGradlePluginVersion: 2.0.1
# - task: CodeQL3000Finalize@0
# - task: Gradle@2
# displayName: Run Tests
# inputs:
# tasks: msal:jacocoTestReport -PcodeCoverageEnabled=true -ProbolectricSdkVersion=${{variables.robolectricSdkVersion}} -PmockApiUrl=$(MOCK_API_URL) -PnativeAuthConfigString=$(NATIVE_AUTH_CONFIG_STRING)
# javaHomeSelection: $(BuildParameters.javaHomeSelection)
# jdkVersion: 1.17
# - script: tree "$(Build.SourcesDirectory)\msal" /F /A
# displayName: 'Print File Structure Tree'
# - publish: $(Build.SourcesDirectory)/msal/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml
# artifact: jacocoReportDev
# displayName: 'Publish JaCoCo Report Artifact (Dev Branch)'
- job: spotbugs
displayName: SpotBugs
cancelTimeoutInMinutes: 1
steps:
- checkout: self
clean: true
submodules: recursive
persistCredentials: True
- bash: |
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_USERNAME]VSTS"
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_ACCESSTOKEN]$(System.AccessToken)"
displayName: 'Set VSTS Fields in Environment'
- template: azure-pipelines/templates/steps/spotbugs.yml@common
parameters:
project: msal
- job: lint
displayName: Lint
cancelTimeoutInMinutes: 1
steps:
- checkout: self
clean: true
submodules: recursive
persistCredentials: True
- bash: |
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_USERNAME]VSTS"
echo "##vso[task.setvariable variable=ENV_VSTS_MVN_CRED_ACCESSTOKEN]$(System.AccessToken)"
displayName: 'Set VSTS Fields in Environment'
- task: Gradle@3
displayName: Lint Local debug
inputs:
tasks: clean msal:lintLocalDebug
publishJUnitResults: false
jdkVersion: 1.17
# - stage: compare_coverage
# displayName: Compare Code Coverage
# dependsOn:
# - build_and_test
# jobs:
# - job: compare
# displayName: Compare PR and Dev Coverage
# steps:
# - download: current
# artifact: jacocoReport # Adjust artifact name as needed
# - download: current
# artifact: jacocoReportDev # Adjust artifact name as needed
#
# - script: |
# python compare_coverage.py \
# $(Pipeline.Workspace)/jacocoReport/jacocoTestReport.xml \
# $(Pipeline.Workspace)/jacocoReportDev/jacocoTestReport.xml
# displayName: Compare Jacoco Coverage
...
2 changes: 1 addition & 1 deletion common
Submodule common updated 72 files
+3 −10 .github/copilot-instructions.md
+9 −1 LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/ILabAccount.java
+20 −1 LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/ILabClient.java
+9 −14 LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/LabAccount.java
+59 −10 LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/LabClient.java
+71 −0 LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/LabJsonStringAccountEntry.java
+25 −2 LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/constants/LabConstants.java
+24 −2 LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/constants/UserType.java
+1 −0 LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/exception/LabError.java
+42 −0 LabApiUtilities/src/test/com/microsoft/identity/labapi/utilities/client/LabClientTest.java
+2 −80 azure-pipelines/pull-request-validation/build-consumers.yml
+7 −1 changelog.txt
+1 −1 common/build.gradle
+0 −25 common/src/androidTest/java/com/microsoft/identity/common/CommandDispatcherTest.java
+11 −0 common/src/main/java/com/microsoft/identity/common/adal/internal/AuthenticationConstants.java
+8 −0 common/src/main/java/com/microsoft/identity/common/internal/broker/BrokerRequest.java
+11 −4 common/src/main/java/com/microsoft/identity/common/internal/broker/BrokerValidator.kt
+0 −2 common/src/main/java/com/microsoft/identity/common/internal/commands/Command.java
+0 −6 common/src/main/java/com/microsoft/identity/common/internal/commands/GenerateShrCommand.java
+0 −5 common/src/main/java/com/microsoft/identity/common/internal/commands/GetCurrentAccountCommand.java
+0 −5 common/src/main/java/com/microsoft/identity/common/internal/commands/GetDeviceModeCommand.java
+0 −4 ...on/src/main/java/com/microsoft/identity/common/internal/commands/GetPreferredAuthMethodFromAuthenticator.kt
+0 −5 common/src/main/java/com/microsoft/identity/common/internal/commands/LoadAccountCommand.java
+0 −5 common/src/main/java/com/microsoft/identity/common/internal/commands/RefreshOnCommand.java
+0 −5 common/src/main/java/com/microsoft/identity/common/internal/commands/RemoveAccountCommand.java
+0 −5 common/src/main/java/com/microsoft/identity/common/internal/commands/RemoveCurrentAccountCommand.java
+46 −8 common/src/main/java/com/microsoft/identity/common/internal/numberMatch/NumberMatchHelper.kt
+5 −0 common/src/main/java/com/microsoft/identity/common/internal/request/MsalBrokerRequestAdapter.java
+24 −0 common/src/main/java/com/microsoft/identity/common/internal/result/MsalBrokerResultAdapter.java
+0 −4 common/src/main/java/com/microsoft/identity/common/nativeauth/internal/commands/BaseNativeAuthCommand.kt
+150 −470 common/src/test/java/com/microsoft/identity/common/BrokerOAuth2TokenCacheTest.java
+1 −1 common/src/test/java/com/microsoft/identity/common/internal/broker/AuthUxJavaScriptInterfaceTest.kt
+84 −1 common/src/test/java/com/microsoft/identity/common/internal/numberMatch/NumberMatchHelperTest.kt
+9 −0 common/src/test/java/com/microsoft/identity/common/internal/request/MsalBrokerRequestAdapterTests.java
+45 −0 common/src/test/java/com/microsoft/identity/common/internal/request/MsalBrokerResultAdapterTests.kt
+10 −0 common4j/src/main/com/microsoft/identity/common/java/AuthenticationConstants.java
+47 −0 common4j/src/main/com/microsoft/identity/common/java/broker/IBrokerInfoProvider.java
+60 −20 common4j/src/main/com/microsoft/identity/common/java/cache/BrokerOAuth2TokenCache.java
+4 −1 common4j/src/main/com/microsoft/identity/common/java/cache/BrokerOAuth2TokenCacheTelemetryWrapper.java
+118 −15 common4j/src/main/com/microsoft/identity/common/java/cache/NameValueStorageFileManagerSimpleCacheImpl.java
+0 −5 common4j/src/main/com/microsoft/identity/common/java/commands/DeviceCodeFlowAuthResultCommand.java
+0 −5 common4j/src/main/com/microsoft/identity/common/java/commands/DeviceCodeFlowCommand.java
+0 −5 common4j/src/main/com/microsoft/identity/common/java/commands/DeviceCodeFlowTokenResultCommand.java
+0 −5 common4j/src/main/com/microsoft/identity/common/java/commands/ICommand.java
+0 −5 common4j/src/main/com/microsoft/identity/common/java/commands/InteractiveTokenCommand.java
+0 −5 common4j/src/main/com/microsoft/identity/common/java/commands/RopcTokenCommand.java
+0 −6 common4j/src/main/com/microsoft/identity/common/java/commands/SilentTokenCommand.java
+0 −26 common4j/src/main/com/microsoft/identity/common/java/controllers/CommandDispatcher.java
+0 −685 common4j/src/main/com/microsoft/identity/common/java/eststelemetry/EstsTelemetry.java
+27 −1 common4j/src/main/com/microsoft/identity/common/java/exception/BaseException.java
+12 −6 common4j/src/main/com/microsoft/identity/common/java/flighting/CommonFlight.java
+4 −0 common4j/src/main/com/microsoft/identity/common/java/jwt/AbstractJwtRequest.java
+3 −0 common4j/src/main/com/microsoft/identity/common/java/jwt/JwtRequestBody.java
+0 −2 common4j/src/main/com/microsoft/identity/common/java/nativeauth/providers/NativeAuthRequestProvider.kt
+22 −6 common4j/src/main/com/microsoft/identity/common/java/opentelemetry/AttributeName.java
+271 −154 common4j/src/main/com/microsoft/identity/common/java/opentelemetry/DefaultBenchmarkSpanPrinter.kt
+14 −0 common4j/src/main/com/microsoft/identity/common/java/opentelemetry/OTelUtility.kt
+0 −1 common4j/src/main/com/microsoft/identity/common/java/opentelemetry/SpanName.java
+4 −4 common4j/src/main/com/microsoft/identity/common/java/providers/oauth2/OAuth2Strategy.java
+27 −1 common4j/src/main/com/microsoft/identity/common/java/result/AcquireTokenResult.java
+0 −2 common4j/src/main/com/microsoft/identity/common/java/telemetry/events/CacheEndEvent.java
+65 −0 common4j/src/main/com/microsoft/identity/common/java/util/RequestHeaderSerializationUtil.java
+560 −0 ...est/com/microsoft/identity/common/java/cache/NameValueStorageFileManagerSimpleCacheImplConcurrencyTest.java
+0 −459 common4j/src/test/com/microsoft/identity/common/java/eststelemetry/EstsTelemetryTest.java
+0 −150 common4j/src/test/com/microsoft/identity/common/java/eststelemetry/MockAuthenticationResult.java
+0 −72 common4j/src/test/com/microsoft/identity/common/java/eststelemetry/MockCommand.java
+0 −30 common4j/src/test/com/microsoft/identity/common/java/eststelemetry/MockCommandResult.java
+2 −0 common4j/src/test/com/microsoft/identity/common/java/jwt/JwtRequestTests.java
+1 −1 common4j/src/test/com/microsoft/identity/common/java/nativeauth/providers/NativeAuthResponseHandlerTest.kt
+69 −0 common4j/src/test/com/microsoft/identity/common/java/util/RequestHeaderSerializationUtilTest.java
+1 −0 docs/design-context.md
+3 −2 labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/KeyVaultSecretsApi.java
45 changes: 45 additions & 0 deletions msal/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
id 'checkstyle'
id 'maven-publish'
id 'kotlin-android'
id 'jacoco'

// Test retries
id 'org.gradle.test-retry' version '1.5.6'
Expand All @@ -28,8 +29,15 @@ codeCoverageReport {
coverage.enabled = enableCodeCoverage
}

jacoco {
toolVersion = "0.8.10"
}

// https://blog.gradle.org/gradle-flaky-test-retry-plugin
tasks.withType(Test) {
jacoco {
includeNoLocationClasses = true // Required for Robolectric
}
retry {
// The maximum number of test failures that are allowed before retrying is disabled.
maxRetries = 2
Expand All @@ -40,6 +48,43 @@ tasks.withType(Test) {
}
}

tasks.register("jacocoTestReport", JacocoReport) {
dependsOn "testLocalDebugUnitTest" // Run Robolectric tests first

reports {
xml.required = true
html.required = true
}

def fileFilter = [
'**/R.class', '**/R$*.class', '**/BuildConfig.*',
'**/Manifest*.*', '**/*Test*.*',
'android/**/*.*'
]

def kotlinClasses = fileTree(
dir: "$buildDir/tmp/kotlin-classes/localDebug",
excludes: fileFilter
)

def javaClasses = fileTree(
dir: "$buildDir/intermediates/javac/localDebug/classes",
excludes: fileFilter
)

def mainSrc = "$projectDir/src/main/java"

sourceDirectories.setFrom(files([mainSrc]))
classDirectories.setFrom(files([kotlinClasses, javaClasses]))
executionData.setFrom(fileTree(
dir: buildDir,
includes: [
"jacoco/testLocalDebugUnitTest.exec",
"outputs/unit_test_code_coverage/localDebugUnitTest/testLocalDebugUnitTest.exec"
]
))
}

android {
namespace "com.microsoft.identity.msal"
compileOptions {
Expand Down