Skip to content

Commit 10fb67b

Browse files
committed
feat: Support no credentials mode
1 parent 3690075 commit 10fb67b

File tree

7 files changed

+67
-33
lines changed

7 files changed

+67
-33
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ The example how to use with GitHub Actions is:
8484
access_token_lifetime: '240s'
8585
```
8686

87+
### No credentials mode
88+
If you want to access only public buckets without any authentication you can disable credentials loading:
89+
```
90+
googleCredentialsDisable := true
91+
```
92+
8793
### Configure publish access level (GCS only):
8894
```
8995
gcsPublishFilePolicy := GcsPublishFilePolicy.InheritedFromBucket // Default

build.sbt

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ lazy val sbtGcsArtifactRepositoryPlaygroundToPublish = project
4646
.in( file( "playground-publish-artifact-repository" ) )
4747
.settings(
4848
name := "sbt-gcs-plugin-playground-artifact-publish",
49-
version := "0.0.20-SNAPSHOT",
49+
version := "0.0.25-SNAPSHOT",
5050
crossScalaVersions := Nil,
5151
gcsPublishFilePolicy := GcsPublishFilePolicy.InheritedFromBucket,
52-
publishTo := Some(
52+
publishTo := Some(
5353
"Custom Releases" at "artifactregistry://europe-north1-maven.pkg.dev/latestbit/latestbit-artifacts-snapshots"
5454
),
5555
logLevel := Level.Debug
@@ -62,7 +62,7 @@ lazy val sbtGcsArtifactRepositoryPlaygroundToResolve = project
6262
crossScalaVersions := Nil,
6363
resolvers += "Custom Releases" at "artifactregistry://europe-north1-maven.pkg.dev/latestbit/latestbit-artifacts-snapshots",
6464
libraryDependencies ++= Seq(
65-
"org.latestbit" %% "sbt-gcs-plugin-playground-artifact-publish" % "0.0.20-SNAPSHOT"
65+
"org.latestbit" %% "sbt-gcs-plugin-playground-artifact-publish" % "0.0.25-SNAPSHOT"
6666
),
6767
logLevel := Level.Debug
6868
)
@@ -74,11 +74,12 @@ lazy val plugin = project
7474
lazy val sbtGcsRoot = project
7575
.in( file( "." ) )
7676
.settings(
77-
name := "sbt-gcs-plugin-root",
78-
crossScalaVersions := Nil,
79-
publish := {},
80-
publishLocal := {},
81-
publishArtifact := false,
82-
logLevel := Level.Debug
77+
name := "sbt-gcs-plugin-root",
78+
crossScalaVersions := Nil,
79+
publish := {},
80+
publishLocal := {},
81+
publishArtifact := false,
82+
logLevel := Level.Debug,
83+
googleCredentialsDisable := true
8384
)
8485
.aggregate( sbtGcsPlaygroundToPublish )

project/plugins.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ addSbtPlugin( "org.latestbit" % "sbt-gcs-plugin" % "1.12.0" )
77
addSbtPlugin( "org.scalameta" % "sbt-scalafmt" % "2.5.4" )
88

99
addSbtPlugin( "com.typesafe.sbt" % "sbt-git" % "1.0.2" )
10+
11+
addSbtPlugin( "org.xerial.sbt" % "sbt-sonatype" % "3.12.2" )

sbt-gcs-plugin/src/main/scala/org/latestbit/sbt/gcs/GcsPlugin.scala

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,32 @@ object GcsPlugin extends AutoPlugin {
3333
import autoImport._
3434

3535
private val gcsPluginDefaultSettings = Seq(
36-
gcsPublishFilePolicy := GcsPublishFilePolicy.InheritedFromBucket,
37-
googleCredentialsFile := None
36+
gcsPublishFilePolicy := GcsPublishFilePolicy.InheritedFromBucket,
37+
googleCredentialsFile := None,
38+
googleCredentialsDisable := false
3839
)
3940

4041
private val gcsPluginTaskInits = Seq(
4142
onLoad in Global := ( onLoad in Global ).value.andThen { state =>
4243
implicit val logger: Logger = state.log
4344
implicit val projectRef: ProjectRef = thisProjectRef.value
4445
Try {
45-
val googleCredentials = loadGoogleCredentials(
46-
googleCredentialsFile.value.map( _.toPath )
47-
)
46+
val googleCredentials = if ( googleCredentialsDisable.value ) {
47+
logger.debug( s"Google Application Default Credentials lookup is disabled for ${projectRef.toString}" )
48+
None
49+
} else {
50+
Some(
51+
loadGoogleCredentials(
52+
googleCredentialsFile.value.map( _.toPath )
53+
)
54+
)
55+
}
4856
GcsUrlHandlerFactory.install( googleCredentials, gcsPublishFilePolicy.value )
4957
} match {
50-
case Success( _ ) => state
58+
case Success( _ ) => state
5159
case Failure( err ) => {
5260
logger.err(
53-
s"Unable to find/initialise google credentials: ${err}. Publishing/resolving artifacts from GCP is disabled."
61+
s"Unable to find/initialise google credentials: ${err}. Publishing/resolving artifacts from GCP is disabled (${projectRef.toString})."
5462
)
5563
state
5664
}
@@ -77,10 +85,10 @@ object GcsPlugin extends AutoPlugin {
7785
.createScoped( scopes )
7886
}
7987
.orElse {
80-
Option(System.getenv("GOOGLE_OAUTH_ACCESS_TOKEN")).map(accessToken =>
88+
Option( System.getenv( "GOOGLE_OAUTH_ACCESS_TOKEN" ) ).map( accessToken =>
8189
GoogleCredentials
82-
.create(AccessToken.newBuilder().setTokenValue(accessToken).build())
83-
.createScoped(scopes)
90+
.create( AccessToken.newBuilder().setTokenValue( accessToken ).build() )
91+
.createScoped( scopes )
8492
)
8593
}
8694
.getOrElse {
@@ -93,9 +101,9 @@ object GcsPlugin extends AutoPlugin {
93101
private def lookupGoogleCredentialsInSbtDir(): Option[Path] = {
94102
Try( Option( System.getProperty( "user.home" ) ) ).toOption.flatten.flatMap { userHomeDir =>
95103
val sbtUserRootDir = new File( userHomeDir, ".sbt" )
96-
if (sbtUserRootDir.exists() && sbtUserRootDir.isDirectory) {
104+
if ( sbtUserRootDir.exists() && sbtUserRootDir.isDirectory ) {
97105
val googleAccountInSbt = new File( sbtUserRootDir, "gcs-resolver-google-account.json" )
98-
if (googleAccountInSbt.exists() && googleAccountInSbt.isFile) {
106+
if ( googleAccountInSbt.exists() && googleAccountInSbt.isFile ) {
99107
Some( googleAccountInSbt.toPath )
100108
} else
101109
None

sbt-gcs-plugin/src/main/scala/org/latestbit/sbt/gcs/GcsPluginKeys.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,7 @@ class GcsPluginKeys {
2424

2525
val googleCredentialsFile = settingKey[Option[File]]( "A file path to Google credentials (optional)" )
2626

27+
val googleCredentialsDisable =
28+
settingKey[Boolean]( "If true, disables automatic lookup of Google Application Default Credentials." )
29+
2730
}

sbt-gcs-plugin/src/main/scala/org/latestbit/sbt/gcs/GcsUrlHandlerFactory.scala

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ import java.net.URL
2929

3030
object GcsUrlHandlerFactory {
3131

32-
/**
33-
* To install if it isn't already installed gs:// URLs handler
34-
* without throwing a java.net.MalformedURLException.
35-
*/
36-
def install( credentials: GoogleCredentials, gcsPublishFilePolicy: GcsPublishFilePolicy )( implicit
32+
/** To install if it isn't already installed gs:// URLs handler without throwing a java.net.MalformedURLException.
33+
*/
34+
def install( credentials: Option[GoogleCredentials], gcsPublishFilePolicy: GcsPublishFilePolicy )( implicit
3735
logger: Logger,
3836
projectRef: ProjectRef
3937
) = {
4038

41-
val gcsStorage = StorageOptions.newBuilder().setCredentials( credentials ).build().getService
39+
val gcsStorage = {
40+
val builder = StorageOptions.newBuilder()
41+
credentials.foreach( builder.setCredentials( _ ) )
42+
builder.build().getService
43+
}
4244
val googleHttpRequestFactory = createHttpRequestFactory( credentials )
4345

4446
// Install gs:// handler for JDK
@@ -59,7 +61,7 @@ object GcsUrlHandlerFactory {
5961
// Install gs:// handler for ivy
6062
val dispatcher: URLHandlerDispatcher = URLHandlerRegistry.getDefault match {
6163
case existingUrlHandlerDispatcher: URLHandlerDispatcher => existingUrlHandlerDispatcher
62-
case otherKindOfDispatcher =>
64+
case otherKindOfDispatcher =>
6365
logger.info( "Setting up Ivy URLHandlerDispatcher to handle gs:// and artifactregistry://" )
6466
val dispatcher: URLHandlerDispatcher = new URLHandlerDispatcher()
6567
dispatcher.setDefault( otherKindOfDispatcher )
@@ -75,9 +77,15 @@ object GcsUrlHandlerFactory {
7577
new NetHttpTransport()
7678
}
7779

78-
private def createHttpRequestFactory( credentials: GoogleCredentials ): HttpRequestFactory = {
79-
val requestInitializer = new HttpCredentialsAdapter( credentials )
80-
val httpTransport = httpTransportFactory.create()
81-
httpTransport.createRequestFactory( requestInitializer )
80+
private def createHttpRequestFactory( credentials: Option[GoogleCredentials] ): HttpRequestFactory = {
81+
val httpTransport = httpTransportFactory.create()
82+
credentials
83+
.map { creds =>
84+
httpTransport.createRequestFactory( new HttpCredentialsAdapter( creds ) )
85+
}
86+
.getOrElse {
87+
httpTransport.createRequestFactory()
88+
}
89+
8290
}
8391
}

sbt-gcs-plugin/src/main/scala/org/latestbit/sbt/gcs/artifactregistry/GcsArtifactRegistryIvyUrlHandler.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,13 @@ class GcsArtifactRegistryIvyUrlHandler( googleHttpRequestFactory: HttpRequestFac
9696
}
9797
}
9898
)
99-
httpRequest.execute()
99+
try {
100+
httpRequest.execute()
101+
} catch {
102+
case ex: Exception =>
103+
logger.error( s"Unable to publish an artifact to '${dest}': ${ex.getMessage}" )
104+
throw ex
105+
}
100106
Option( l ).foreach( _.end( event ) )
101107
}
102108

0 commit comments

Comments
 (0)