diff --git a/README.md b/README.md index e749441..cf00b98 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,15 @@ You will need to ensure that both `githubActor` and `githubTokenSource` are set Once this is configured, sbt-github-packages will automatically set your `githubActor` key to its value. That just leaves the `githubTokenSource`. The `TokenSource` ADT has the following possibilities: ```scala -sealed trait TokenSource extends Product with Serializable +sealed trait TokenSource extends Product with Serializable { + def ||(that: TokenSource): TokenSource = + TokenSource.Or(this, that) +} object TokenSource { final case class Environment(variable: String) extends TokenSource final case class GitConfig(key: String) extends TokenSource + final case class Or(primary: TokenSource, secondary: TokenSource) extends TokenSource } ``` @@ -62,6 +66,8 @@ Environment variables are a fairly good default. For example, I have a GitHub to githubTokenSource := TokenSource.Environment("GITHUB_TOKEN") ``` +The `||` combinator allows you to configure multiple token sources which will be tried in order on first-read of the setting. + Note that your CI server will need to set the `GITHUB_TOKEN` environment variable as well, as well as any collaborators on your project. The environment-specific nature of these login credentials are a major part of why they are *not* just strings sitting in the `build.sbt` file. As an example, if you're using Travis, you can do something like the following: ```bash diff --git a/src/main/scala/sbtghpackages/GitHubPackagesPlugin.scala b/src/main/scala/sbtghpackages/GitHubPackagesPlugin.scala index ce2ab3b..cf743b6 100644 --- a/src/main/scala/sbtghpackages/GitHubPackagesPlugin.scala +++ b/src/main/scala/sbtghpackages/GitHubPackagesPlugin.scala @@ -93,21 +93,26 @@ object GitHubPackagesPlugin extends AutoPlugin { userDefaults ++ authenticationSettings - def inferredGitHubCredentials(user: String, tokenSource: TokenSource) = { - val tokenM = tokenSource match { + def inferredGitHubCredentials(user: String, tokenSource: TokenSource): Option[Credentials] = { + def make(tokenM: Option[String]) = + tokenM map { token => + Credentials( + "GitHub Package Registry", + "maven.pkg.github.com", + user, + token) + } + + tokenSource match { + case TokenSource.Or(primary, secondary) => + inferredGitHubCredentials(user, primary).orElse( + inferredGitHubCredentials(user, secondary)) + case TokenSource.Environment(variable) => - sys.env.get(variable) + make(sys.env.get(variable)) case TokenSource.GitConfig(key) => - Try(s"git config $key".!!).map(_.trim).toOption - } - - tokenM map { token => - Credentials( - "GitHub Package Registry", - "maven.pkg.github.com", - user, - token) + make(Try(s"git config $key".!!).map(_.trim).toOption) } } diff --git a/src/main/scala/sbtghpackages/TokenSource.scala b/src/main/scala/sbtghpackages/TokenSource.scala index b8d26f1..85ad3ae 100644 --- a/src/main/scala/sbtghpackages/TokenSource.scala +++ b/src/main/scala/sbtghpackages/TokenSource.scala @@ -16,9 +16,13 @@ package sbtghpackages -sealed trait TokenSource extends Product with Serializable +sealed trait TokenSource extends Product with Serializable { + def ||(that: TokenSource): TokenSource = + TokenSource.Or(this, that) +} object TokenSource { final case class Environment(variable: String) extends TokenSource final case class GitConfig(key: String) extends TokenSource + final case class Or(primary: TokenSource, secondary: TokenSource) extends TokenSource }