Skip to content

Releases: clee704/sbt-azure-devops-credentials

Release list

v0.0.9

Choose a tag to compare

@clee704 clee704 released this 23 May 03:22
v0.0.9
b244772

Fix

WorkloadIdentityCredential is now skipped from the credential chain when its AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_FEDERATED_TOKEN_FILE env vars are absent, empty, or whitespace-only. Fixes the v0.0.8 regression where ChainedTokenCredentialBuilder couldn't be assembled at all on developer workstations that had az login working but no workload-identity env vars set, leaving the plugin to always report "failed to get access token. Did you forget to run \az login`?"`.

If you're on v0.0.8 and using the plugin on a developer workstation (i.e. not in a workload-identity-enabled CI environment), upgrade to v0.0.9.

Other behavior changes

  • Parallel token resolution. Concurrent CredentialsBuilder instances (multi-project sbt builds resolving credentials in parallel) now share a reference-counted log-suppression instead of holding a JVM-wide lock across the Azure SDK call. Token fetches actually run in parallel; the org.slf4j.simpleLogger.log.com.azure.identity property is restored correctly after the last in-flight builder completes.
  • Broadened SLF4J suppression scope. org.slf4j.simpleLogger.log.com.azure.identity is now set to "off" at plugin classloading time if it isn't already set, defending against SLF4J SimpleLogger's per-logger init-time level caching. Pre-v0.0.9, suppression was strictly scoped to getToken calls — but if anything else in the JVM initialized a com.azure.identity logger before our first getToken, the per-call suppression silently no-op'd for the rest of the run. As a side effect, other plugins that consume azure-identity directly (azure-storage-blob, azure-keyvault, …) will now have their com.azure.identity logs suppressed across the whole sbt run too — set -Dorg.slf4j.simpleLogger.log.com.azure.identity=debug (or any non-off value) via JVM args to opt out.
  • Whitespace tolerance on AAD env vars. AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_FEDERATED_TOKEN_FILE values are now .trimmed before being passed to the SDK, so a stray trailing newline (e.g. from a YAML literal-block substitution leaving whitespace around the value) is tolerated instead of producing a credential that builds successfully but fails AAD validation at getToken time.

Compatibility

  • Binary-incompatible: CredentialsBuilder constructor parameter widened from sbt.internal.util.ManagedLogger to sbt.util.Logger. Source-compatible (ManagedLogger <: Logger); binary-incompatible. The class is effectively internal — only constructed by the plugin's own projectSettings task wiring — so this should be invisible to downstream users in practice.
  • Extension surface widened: Four CredentialsBuilder methods (mavenSettingsFile, newCredential, getRealm, getToken) widened from private to protected to enable unit-test substitution via anonymous subclasses. class CredentialsBuilder is unqualified-public, so this technically expands the downstream extension surface, even though there's no public extension point in practice (only projectSettings instantiates the class). Flagged so a future re-tightening to private is treated as the SemVer-major / deprecation-cycle change it would be, not a silent revert.

Internal

  • releaseAzureIdentityLogSuppression now throws IllegalArgumentException when called without a matching prior acquire. The method is private[chungmin] and only invoked internally by getTokenImpl's try/finally, so end users won't see this in practice — but it's a behavior change for anyone embedding the plugin and calling the suppression API directly. Previously an unbalanced release silently corrupted the counter, leaving the suppression dead for the rest of the JVM run; now it fails fast at the actual bad caller.

Test infrastructure (new)

  • First unit-test suite on this repo (CredentialsBuilderSpec + AzureDevOpsCredentialsPluginSpec) — 62 tests covering every code path with realistic ADO fixtures, 100% statement and branch coverage enforced via coverageMinimumStmt/BranchTotal := 100 + coverageFailOnMinimum := true.
  • GitHub Actions CI running sbt -batch clean coverage test coverageReport on JDK 8 / 11 / 17 / 21 against every PR and every push to master. Coverage results emitted to GITHUB_STEP_SUMMARY per-Java-version and full HTML report uploaded as a build artifact.
  • Test / parallelExecution := false in build.sbt to close the cross-suite property-race window introduced by suites mutating the JVM-global org.slf4j.simpleLogger.log.com.azure.identity. Only affects sbt test of this repository, not downstream consumers of the plugin.

Usage

addSbtPlugin("dev.chungmin" % "sbt-azure-devops-credentials" % "0.0.9")

PR: #5