├── project ├── build.properties └── plugins.sbt ├── src ├── sbt-test │ └── sbtghpackages │ │ ├── startup │ │ ├── test │ │ ├── build.sbt │ │ └── project │ │ │ ├── build.properties │ │ │ └── plugins.sbt │ │ └── publish │ │ ├── project │ │ ├── build.properties │ │ └── plugins.sbt │ │ ├── test │ │ └── build.sbt └── main │ └── scala │ └── sbtghpackages │ ├── TokenSource.scala │ ├── GitHubPackagesKeys.scala │ └── GitHubPackagesPlugin.scala ├── .gitignore ├── .travis.yml ├── README.md └── LICENSE.txt /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.3 2 | -------------------------------------------------------------------------------- /src/sbt-test/sbtghpackages/startup/test: -------------------------------------------------------------------------------- 1 | > show publishTo 2 | -------------------------------------------------------------------------------- /src/sbt-test/sbtghpackages/startup/build.sbt: -------------------------------------------------------------------------------- 1 | name := "startup-test" 2 | -------------------------------------------------------------------------------- /src/sbt-test/sbtghpackages/publish/project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.3 2 | -------------------------------------------------------------------------------- /src/sbt-test/sbtghpackages/startup/project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.10 2 | -------------------------------------------------------------------------------- /src/sbt-test/sbtghpackages/publish/test: -------------------------------------------------------------------------------- 1 | > publisher/publish 2 | > resolver/update 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | 3 | # vim 4 | *.sw? 5 | 6 | # Ignore [ce]tags files 7 | tags 8 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.codecommit" % "sbt-spiewak-sonatype" % "0.9.1") 2 | -------------------------------------------------------------------------------- /src/sbt-test/sbtghpackages/publish/project/plugins.sbt: -------------------------------------------------------------------------------- 1 | sys.props.get("plugin.version") match { 2 | case Some(x) => addSbtPlugin("com.codecommit" % "sbt-github-packages" % x) 3 | case _ => sys.error("""|The system property 'plugin.version' is not defined. 4 | |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) 5 | } 6 | -------------------------------------------------------------------------------- /src/sbt-test/sbtghpackages/startup/project/plugins.sbt: -------------------------------------------------------------------------------- 1 | sys.props.get("plugin.version") match { 2 | case Some(x) => addSbtPlugin("com.codecommit" % "sbt-github-packages" % x) 3 | case _ => sys.error("""|The system property 'plugin.version' is not defined. 4 | |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) 5 | } 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: scala 3 | 4 | jdk: 5 | - openjdk8 6 | 7 | branches: 8 | except: 9 | - /^v\d+\.\d+\.\d+$/ # don't redundantly build tags 10 | 11 | scala: 12 | - 2.12.10 13 | 14 | script: 15 | - sbt ++$TRAVIS_SCALA_VERSION ci 16 | 17 | before_cache: 18 | - find $HOME/.sbt -name "*.lock" -type f -delete 19 | - find $HOME/.ivy2/cache -name "ivydata-*.properties" -type f -delete 20 | 21 | env: 22 | global: 23 | - COURSIER_PROGRESS=0 24 | 25 | cache: 26 | directories: 27 | - $HOME/.ivy2/cache 28 | - $HOME/.coursier/cache 29 | - $HOME/.sbt 30 | -------------------------------------------------------------------------------- /src/sbt-test/sbtghpackages/publish/build.sbt: -------------------------------------------------------------------------------- 1 | import scala.sys.process._ 2 | 3 | val ArtifactId = "sbt-github-packages-tests-publish" 4 | 5 | ThisBuild / organization := "com.codecommit" 6 | ThisBuild / version := s"${sys.props("plugin.version")}" 7 | 8 | ThisBuild / githubOwner := "djspiewak" 9 | ThisBuild / githubRepository := "sbt-github-packages" 10 | ThisBuild / githubTokenSource := TokenSource.Environment("GITHUB_TOKEN") 11 | 12 | lazy val root = project.in(file(".")) 13 | 14 | lazy val publisher = project 15 | .in(file("publisher")) 16 | .settings(name := ArtifactId) 17 | 18 | lazy val resolver = project 19 | .in(file("resolver")) 20 | .settings( 21 | libraryDependencies += "com.codecommit" %% ArtifactId % version.value) 22 | -------------------------------------------------------------------------------- /src/main/scala/sbtghpackages/TokenSource.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Daniel Spiewak 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sbtghpackages 18 | 19 | sealed trait TokenSource extends Product with Serializable { 20 | def ||(that: TokenSource): TokenSource = 21 | TokenSource.Or(this, that) 22 | } 23 | 24 | object TokenSource { 25 | final case class Environment(variable: String) extends TokenSource 26 | final case class GitConfig(key: String) extends TokenSource 27 | final case class Or(primary: TokenSource, secondary: TokenSource) extends TokenSource 28 | } 29 | -------------------------------------------------------------------------------- /src/main/scala/sbtghpackages/GitHubPackagesKeys.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Daniel Spiewak 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sbtghpackages 18 | 19 | import sbt._ 20 | 21 | trait GitHubPackagesKeys { 22 | val githubOwner = settingKey[String]("The github user or organization name") 23 | val githubRepository = settingKey[String]("The github repository hosting this package") 24 | 25 | val githubTokenSource = settingKey[TokenSource]("Where to get the API token used in publication (defaults to github.token in the git config)") 26 | 27 | val githubSuppressPublicationWarning = settingKey[Boolean]("Whether or not to suppress the publication warning (default: false, meaning the warning will be printed)") 28 | 29 | val githubPublishTo = taskKey[Option[Resolver]]("publishTo setting for deploying artifacts to GitHub packages") 30 | } 31 | 32 | object GitHubPackagesKeys extends GitHubPackagesKeys 33 | -------------------------------------------------------------------------------- /src/main/scala/sbtghpackages/GitHubPackagesPlugin.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Daniel Spiewak 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sbtghpackages 18 | 19 | import sbt._, Keys._ 20 | 21 | import scala.sys.process._ 22 | import scala.util.Try 23 | 24 | object GitHubPackagesPlugin extends AutoPlugin { 25 | @volatile 26 | private[this] var alreadyWarned = false 27 | 28 | override def requires = plugins.JvmPlugin 29 | override def trigger = allRequirements 30 | 31 | object autoImport extends GitHubPackagesKeys { 32 | type TokenSource = sbtghpackages.TokenSource 33 | val TokenSource = sbtghpackages.TokenSource 34 | 35 | implicit class GHPackagesResolverSyntax(val resolver: Resolver.type) extends AnyVal { 36 | def githubPackages(owner: String, repo: String = "_"): MavenRepository = 37 | realm(owner, repo) at s"https://maven.pkg.github.com/$owner/$repo" 38 | } 39 | } 40 | 41 | import autoImport._ 42 | 43 | val authenticationSettings = Seq( 44 | githubTokenSource := TokenSource.Environment("GITHUB_TOKEN"), 45 | 46 | credentials += { 47 | val src = githubTokenSource.value 48 | inferredGitHubCredentials("_", src) match { // user is ignored by GitHub, so just use "_" 49 | case Some(creds) => 50 | creds 51 | 52 | case None => 53 | sys.error(s"unable to locate a valid GitHub token from $src") 54 | } 55 | }) 56 | 57 | val packagePublishSettings = Seq( 58 | githubPublishTo := { 59 | val log = streams.value.log 60 | val ms = publishMavenStyle.value 61 | val back = for { 62 | owner <- githubOwner.?.value 63 | repo <- githubRepository.?.value 64 | } yield "GitHub Package Registry" at s"https://maven.pkg.github.com/$owner/$repo" 65 | 66 | back foreach { _ => 67 | if (!ms) { 68 | sys.error("GitHub Packages does not support Ivy-style publication") 69 | } 70 | } 71 | 72 | back 73 | }, 74 | 75 | publishTo := { 76 | val suppress = githubSuppressPublicationWarning.value 77 | val log = streams.value.log 78 | 79 | githubPublishTo.value orElse { 80 | GitHubPackagesPlugin synchronized { 81 | if (!alreadyWarned && !suppress) { 82 | log.warn("undefined keys `githubOwner` and `githubRepository`") 83 | log.warn("retaining pre-existing publication settings") 84 | alreadyWarned = true 85 | } 86 | } 87 | 88 | publishTo.value 89 | } 90 | }, 91 | 92 | resolvers ++= githubOwner.?.value.toSeq.map(Resolver.githubPackages(_)), 93 | 94 | scmInfo := { 95 | val back = for { 96 | owner <- githubOwner.?.value 97 | repo <- githubRepository.?.value 98 | } yield ScmInfo(url(s"https://github.com/$owner/$repo"), s"scm:git@github.com:$owner/$repo.git") 99 | 100 | back.orElse(scmInfo.value) 101 | }, 102 | 103 | homepage := { 104 | val back = for { 105 | owner <- githubOwner.?.value 106 | repo <- githubRepository.?.value 107 | } yield url(s"https://github.com/$owner/$repo") 108 | 109 | back.orElse(homepage.value) 110 | }, 111 | 112 | pomIncludeRepository := (_ => false), 113 | publishMavenStyle := true) ++ 114 | authenticationSettings 115 | 116 | def resolveTokenSource(tokenSource: TokenSource): Option[String] = { 117 | tokenSource match { 118 | case TokenSource.Or(primary, secondary) => 119 | resolveTokenSource(primary).orElse( 120 | resolveTokenSource(secondary)) 121 | 122 | case TokenSource.Environment(variable) => 123 | sys.env.get(variable) 124 | 125 | case TokenSource.GitConfig(key) => 126 | Try(s"git config $key".!!).map(_.trim).toOption 127 | } 128 | } 129 | 130 | def inferredGitHubCredentials(user: String, tokenSource: TokenSource): Option[Credentials] = { 131 | resolveTokenSource(tokenSource) map { token => 132 | Credentials( 133 | "GitHub Package Registry", 134 | "maven.pkg.github.com", 135 | user, 136 | token) 137 | } 138 | } 139 | 140 | private def realm(owner: String, repo: String) = 141 | s"GitHub Package Registry (${owner}${if (repo != "_") s"/$repo" else ""})" 142 | 143 | override def projectSettings = packagePublishSettings 144 | 145 | override def buildSettings = Seq(githubSuppressPublicationWarning := false) 146 | } 147 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sbt-github-packages [![Build Status](https://travis-ci.com/djspiewak/sbt-github-packages.svg?branch=master)](https://travis-ci.com/djspiewak/sbt-github-packages) 2 | 3 | Configures your project for publication to the [GitHub Package Registry](https://help.github.com/en/articles/about-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. 4 | 5 | ## Usage 6 | 7 | Add the following to your **project/plugins.sbt** file: 8 | 9 | ```sbt 10 | addSbtPlugin("com.codecommit" % "sbt-github-packages" % "") 11 | ``` 12 | 13 | Published for sbt 1.x. No dependencies. 14 | 15 | 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: 16 | 17 | ```sbt 18 | githubOwner := "djspiewak" 19 | githubRepository := "sbt-github-packages" 20 | ``` 21 | 22 | In the event that you do *not* override these values, you will see a warning like the following: 23 | 24 | ``` 25 | [warn] undefined keys `githubOwner` and `githubRepository` 26 | [warn] retaining pre-existing publication settings 27 | ``` 28 | 29 | 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. 30 | 31 | 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. 32 | 33 | Once everything is configured, run `sbt publish` to publish the package. 34 | 35 | ### Resolvers 36 | 37 | If you're consuming packages that were published in the GitHub Package Registry, this plugin defines some convenience syntax for adding resolvers: 38 | 39 | ```sbt 40 | resolvers += Resolver.githubPackages("OWNER") 41 | ``` 42 | 43 | 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. 44 | 45 | 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. 46 | 47 | 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: 48 | 49 | ```scala 50 | sealed trait TokenSource extends Product with Serializable { 51 | def ||(that: TokenSource): TokenSource = 52 | TokenSource.Or(this, that) 53 | } 54 | 55 | object TokenSource { 56 | final case class Environment(variable: String) extends TokenSource 57 | final case class GitConfig(key: String) extends TokenSource 58 | final case class Or(primary: TokenSource, secondary: TokenSource) extends TokenSource 59 | } 60 | ``` 61 | 62 | 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: 63 | 64 | ```sbt 65 | githubTokenSource := TokenSource.Environment("GITHUB_TOKEN") 66 | ``` 67 | 68 | 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. 69 | 70 | To use a token from `~/.gitconfig` you should add: 71 | 72 | ```sbt 73 | githubTokenSource := TokenSource.GitConfig("github.token") 74 | ``` 75 | 76 | This assumes you have your token stored there like this: 77 | 78 | ```gitconfig 79 | [github] 80 | token = TOKEN_DATA 81 | ``` 82 | 83 | The `||` combinator allows you to configure multiple token sources which will be tried in order on first-read of the setting. 84 | 85 | 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: 86 | 87 | ```bash 88 | # in your .profile file 89 | $ export GITHUB_TOKEN="abcdef12345cafebabe" # <-- your token here (or your build bot's) 90 | 91 | # ...and when setting up your project 92 | $ travis encrypt GITHUB_TOKEN=$GITHUB_TOKEN 93 | ``` 94 | 95 | If using GitHub Actions, the following is usually sufficient: 96 | 97 | ```yaml 98 | env: 99 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 100 | ``` 101 | 102 | #### Token Permissions 103 | 104 | 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. 105 | 106 | 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. 107 | 108 | #### Manual Configuration 109 | 110 | 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: 111 | 112 | ```sbt 113 | credentials += 114 | Credentials( 115 | "GitHub Package Registry", 116 | "maven.pkg.github.com", 117 | "USERNAME", 118 | "TOKEN") 119 | ``` 120 | 121 | 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`. 122 | 123 | ### GitHub Actions 124 | 125 | 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. 126 | 127 | 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. 128 | 129 | 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. 130 | 131 | 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](https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes) scope and use it `GITHUB_TOKEN: ${{ secrets.TOKEN_WITH_READ_PACKAGES_SCOPE }}` 132 | 133 | ### Keys 134 | 135 | The following setting keys are defined: 136 | 137 | - `githubOwner : String` Defines the organization or user name that owns the package registry to which this project will be published 138 | - `githubRepository : String` The repository which hosts this project under the organization/user defined in the other setting 139 | - `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. 140 | - `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`. 141 | - `githubPublishTo : Option[Resolver]` The default `publishTo` target for GitHub Packages. This setting is useful for switching `publishTo` target to [sbt-sonatype](https://github.com/xerial/sbt-sonatype) or GitHub Packages: 142 | 143 | ```scala 144 | // Switch publishTo target for using Sonatype if RELEASE_SONATYPE env is true, 145 | // otherwise publish to GitHub Packages: 146 | val RELEASE_TO_SONATYPE = sys.env.getOrElse("RELEASE_SONATYPE", "false").toBoolean 147 | publishTo := if(RELEASE_SONATYPE) sonatypePublishTo.value else githubPublishTo.value 148 | 149 | `homepage` and `scmInfo` will be automatically set for you if `githubOwner` and `githubRepository` are themselves set. 150 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | --------------------------------------------------------------------------------