• Stars
    star
    174
  • Rank 219,104 (Top 5 %)
  • Language
    Scala
  • License
    Apache License 2.0
  • Created over 5 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A simple sbt plugin for publishing to GitHub Packages, in the style of sbt-sonatype and sbt-bintray

sbt-github-packages Build Status

Configures your project for publication to the GitHub Package Registry using its Apache Maven support. Note that GitHub Packages exclusively supports maven-style publication; using Ivy style will result in a warning. Also provides some convenience functionality for depending upon artifacts which have been published to the Package Registry.

Usage

Add the following to your project/plugins.sbt file:

addSbtPlugin("com.codecommit" % "sbt-github-packages" % "<version>")

Published for sbt 1.x. No dependencies.

In order to publish artifacts via this plugin, you will need to override the githubOwner and githubRepository setting keys to the relevant values for your project. For example:

githubOwner := "djspiewak"
githubRepository := "sbt-github-packages"

In the event that you do not override these values, you will see a warning like the following:

[warn] undefined keys `githubOwner` and `githubRepository`
[warn] retaining pre-existing publication settings

The reason this functionality is disabled by default is you may wish to utilize the Resolver syntax (described below) without overriding your default publication mechanism. In general, I wouldn't necessarily recommend this, since it means that your publication will not be self-contained within a single artifact realm, but that's a relatively common problem anyway these days so it's probably not a big deal.

As a note on publication, only publishMavenStyle := true (the default) is supported. If you explicitly override this setting to false, the sbt-github-packages plugin will produce an error and refuse to load (unless githubOwner and/or githubRepository are undefined). The reason for this is to remove a bit of a foot-gun: GitHub Packages will silently allow you to publish Ivy-style packages, and will even show it within the UI, but will not allow you to resolve them.

Once everything is configured, run sbt publish to publish the package.

Resolvers

If you're consuming packages that were published in the GitHub Package Registry, this plugin defines some convenience syntax for adding resolvers:

resolvers += Resolver.githubPackages("OWNER")

You may also optionally specify a repository as the second argument. This is not required! By default, sbt-github-packages will attempt to resolve from a repository named "_", which does not need to exist. If that repository does exist, and it is private, then the token used in authentication must have access to private repositories in that organization. In most cases, just the owner parameter will be sufficient.

This resolver will give you access to packages published on any repository within the organization. If the token provided in the authentication information only has access to public repositories, then packages published on private repositories will report "not found". If the token has access to private repositories as well as public, then all packages will be visible.

You will need to ensure that githubTokenSource is set to your details (i.e. the authentication information for the individual who ran sbt). The TokenSource ADT has the following possibilities:

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
}

Environment variables are a good default. For example, I have a GitHub token for my laptop stored in the GITHUB_TOKEN environment variable. If you mirror this setup, you should configure githubTokenSource in the following way:

githubTokenSource := TokenSource.Environment("GITHUB_TOKEN")

This is, in fact, exactly the default configuration. In other words, if you set the GITHUB_TOKEN environment variable, then this plugin will work out of the box with no configuration.

To use a token from ~/.gitconfig you should add:

githubTokenSource := TokenSource.GitConfig("github.token")

This assumes you have your token stored there like this:

[github]
  token = TOKEN_DATA

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 (if using the Environment token source), 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:

# in your .profile file
$ export GITHUB_TOKEN="abcdef12345cafebabe"   # <-- your token here (or your build bot's)

# ...and when setting up your project
$ travis encrypt GITHUB_TOKEN=$GITHUB_TOKEN

If using GitHub Actions, the following is usually sufficient:

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Token Permissions

GitHub Actions (and other instances of GitHub Apps) generate different tokens than those generated by the "Personal Access Tokens" section of your account settings. These tokens usually begin with v1.. They're weird because they are not associated with any particular user account. Thus, the value of GITHUB_ACTOR is irrelevant in such cases. It's entirely possible that GITHUB_ACTOR is irrelevant in all cases, but the API documentation claims otherwise. The API documentation claims many wrong things.

As an example, the documentation claims that, if you aren't publishing, your token only requires the read: package grant (and not write: package). Based on testing, as of right now, that appears to be false: write: package is required for all API calls against GitHub Packages, including resolution.

Manual Configuration

Once these values are set, the credentials key will be adjusted to reflect your GitHub authentication details. If you prefer, you are certainly free to set the credentials yourself, rather than trusting the plugin. They will need to take on the following form:

credentials += 
  Credentials(
    "GitHub Package Registry",
    "maven.pkg.github.com",
    "USERNAME",
    "TOKEN")

Please, for the love of all that is holy, do not check this into your repository if you hard-code your credentials in this way. The token is a password. Treat it as such. A better approach would be to place the above into some global location, like ~/.sbt/1.0/github.sbt.

GitHub Actions

Okay, so GitHub Actions is pretty much undocumented with respect to its interactions with GitHub Packages. Through experimentation though, we've learned some important things.

The default token automagically-provided to all repositories works with GitHub Packages. So in other words, if you add GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} to your workflow's env section, things should work out just fine. The token in question is a JWT bearer token, not a conventional OAuth token.

Despite the fact that this token is documented as "scoped to the current repository", it will actually allow for read access to all public packages, not just in the current repository but in other repositories as well.

It will NOT allow for read access to private packages within the same organization. You might see the following issue [error] not found: https://maven.pkg.github.com/.... In order to pass, you have to create personal access token with read:packages scope and use it GITHUB_TOKEN: ${{ secrets.TOKEN_WITH_READ_PACKAGES_SCOPE }}

Keys

The following setting keys are defined:

  • githubOwner : String Defines the organization or user name that owns the package registry to which this project will be published

  • githubRepository : String The repository which hosts this project under the organization/user defined in the other setting

  • githubTokenSource : TokenSource (defaults to Environment("GITHUB_TOKEN")) Where the plugin should go to read the GitHub API token to use in authentication. TokenSource has two possible values: Environment(variable: String) and GitConfig(key: String). You can compose multiple sources together using ||, which will result in each being attempted in order from left to right. This is mostly just a convenience. You're free to do whatever you want. Just don't, like, put it in your build.

  • githubSuppressPublicationWarning : Boolean (defaults to false) If you're just using this plugin as a means to resolve artifacts, not to publish them, the publication warning may serve as an annoyance more than anything else. Setting this to true will suppress the normal warning text when you fail to define githubOwner or githubRepository.

  • githubPublishTo : Option[Resolver] The default publishTo target for GitHub Packages. This setting is useful for switching publishTo target to sbt-sonatype or GitHub Packages:

    // Switch publishTo target for using Sonatype if RELEASE_SONATYPE env is true, 
    // otherwise publish to GitHub Packages:
    val RELEASE_TO_SONATYPE = sys.env.getOrElse("RELEASE_SONATYPE", "false").toBoolean 
    publishTo := if(RELEASE_SONATYPE) sonatypePublishTo.value else githubPublishTo.value
    

homepage and scmInfo will be automatically set for you if githubOwner and githubRepository are themselves set.

More Repositories

1

gll-combinators

A parser combinator library based on the GLL algorithm
Scala
302
star
2

emm

A general monad for managing stacking effects
Scala
205
star
3

parseback

A Scala implementation of parsing with derivatives
Scala
197
star
4

shims

Seamless interop layer between cats and scalaz
Scala
174
star
5

anti-xml

The scala.xml library has some very annoying issues. Time for a clean-room replacement!
Scala
169
star
6

cccp

Common Colaborative Coding Protocol
Scala
119
star
7

extreme-cleverness

A set of functional collections created, ported and modified for my tak at NE Scala 2011
Scala
91
star
8

sparse

Generalized, incremental parser combinators for scalaz-stream
Scala
63
star
9

skolems

A microlibrary for Scala encodings of higher-rank quantifiers
Scala
60
star
10

derivative-combinators

An implementation of derivative parsing in the parser combinator framework
Scala
59
star
11

sbt-spiewak

A plugin which represents my personal SBT project baseline
Scala
53
star
12

kitteh-redis

A toy Redis server implemented using pure FP on top of Cats Effect, Fs2, and Scodec
Scala
42
star
13

jedit-modes

A collection of new and modified edit modes for jEdit
34
star
14

scala-bison

A recursive ascent/descent parser generator for Scala
Scala
33
star
15

smock

A utility harness for testing free programs (built on specs2)
Scala
29
star
16

scala-collections

A number of collection implementations for Scala (including a few ported from Clojure)
Scala
27
star
17

async-runtime-benchmarks

Comparative benchmarks between asynchronous runtimes
Scala
27
star
18

scala-stm-proto

An implementation of a software transactional memory framework in Scala
Scala
19
star
19

sillio

Scala
16
star
20

ensime-sidekick

An ENSIME SideKick plugin for jEdit
Scala
16
star
21

linguistic-programming

Sources for my presentation on crafting DSLs in Scala
Scala
10
star
22

activeobjects

A Git fork of the mainline ActiveObjects SVN
Java
10
star
23

base.g8

My cool template
Scala
8
star
24

jbencode

A very fast Java Bencode pull parser/generator
Java
7
star
25

sbt-evil-mode

😈
Scala
7
star
26

shapely

Scala
7
star
27

cont-exp

Experiments with the continuation monad
Scala
7
star
28

dbpool

A fork of the excellent DBPool connection pool
Java
5
star
29

wronglisp

Scala
4
star
30

rst2twiki

A converter script from ReStructured Text to TWiki markup
4
star
31

iota-instances

Scalaz instances and things for iotaz coproducts
Scala
3
star
32

parser-workshop

Parser workshop at flatMap(Oslo) 2013
Scala
3
star
33

dist-mapper

A non-functional key/value store backend
Scala
2
star
34

schrodinger

Common communication protocol for IO / Task / Future data types
Scala
2
star
35

jedit-macros

1
star