There are many Scala open source libraries on Github. They all have automatic testing capabilities.


For example, a small icon (Build Passing) on the README page indicates whether the current version has passed the test.




For example, whenever someone submits a Pull Request, there is also a little check to report whether the change passed the test.




Also, these libraries are published to the Maven central repository, and I can download them automatically if I want to use them in my own projects by adding a dependency to my SBT configuration.

These automated test and release capabilities are continuous integration and delivery and can be implemented with Travis CI and SBT-Best-Practice.

Travis CI is a continuous integration service. Once Travis CI is enabled on your Github repository, it will trigger Travis CI to execute a script every time someone pushes code in the repository or submits a Pull Request.

For Scala projects, SBT is typically used to manage the build process, so we would expect the Travis CI to be triggered to perform test and publish SBT tasks. And then we can do all the things that we’re trying to do.

Step 1: Enable Travis CI

The Travis CI build process is configured in the.travis. Yml file. The.travis. Yml of the Scala library should look like this:


# tell Travis CI that the script configured in this file should be executed using a system image already installed with Scala -sbt test # Execute the "release with-defaults" task to automatically publish the deploy: skip_cleanup: true provider: script script: sbt "release with-defaults" on: condition: -e ./deploy.sbt all_branches: trueCopy the code

With.travis. Yml, you also need to access your Profile page on Travis CI to enable Travis CI for the Github repository.


CI then automatically performs the SBT test test for each commit. In addition, CI checks whether deploy. SBT exists and, if so, performs the SBT “Release with-Defaults” task to automatically publish.

Step 2: Add the Sbt plug-in

SBT test and SBT “Release with-Defaults” tasks are provided by the SBT plug-in. Edit project/plugins.sbt to enable the SBT-best-practice plug-in, and these tasks are automatically configured.


addSbtPlugin("com.thoughtworks.sbt-best-practice" % "sbt-best-practice" % "latest.release")Copy the code

Adding a Test framework

For automated testing, you also need to add test framework dependencies and write your own test cases.

Common testing frameworks in the Scala community include JUnit, ScalaTest, Specs2, and µTest.

Using µTest as an example, edit or create build.sbt:


LibraryDependencies += "com.lihaoyi" %% "utest" % "0.4.3" % "test" testFrameworks += new TestFramework("utest.runner.Framework")Copy the code

This way, test cases written in SRC /test/ Scala will be executed by SBT Test.

Step 3: Provide an open source license for project information at the time of automatic release

Software to be published to the Maven central repository must be open source. You need to prepare a LICENSE file. Such as we often use the Apache License content can be found here: https://www.apache.org/licenses/LICENSE-2.0

Organization name and project name

Of course, you also need to specify the name of the library. SBT projects are uniquely identified by the organization name plus a combination of project names. Edit or create build.sbt Settings as follows:


organizatio := "com.thoughtworks.q"

name := "q"Copy the code

The version number

The version number should be saved in version.sbt:


Version in ThisBuild := "1.0.0-snapshot"Copy the code

Step 4: Set the authentication mechanism for automatic advertisement, such as password and key. Apply for a Sonatype account

Most of the software in Maven’s central repository is synchronized from Sonatype. So whenever you publish a project to Sonatype, it will be automatically published to the Maven central repository.

First, you need to sign up for a Sonatype account:

https://issues.sonatype.org/secure/Signup! default.jspa

Then, fill out the form and apply for permission to publish the item to Sonatype:

Issues.sonatype.org/secure/Crea…


You can refer to my application format to fill in:

https://issues.sonatype.org/browse/OSSRH-22779

Generate and upload PGP keys

Software published to Sonatype must be signed with PGP. So you have to generate a pair of PGP keys.

You can use GnuPG to generate keys.


gpg --gen-key
gpg --export --armor --output pubring.asc
gpg --export-secret-keys --armor --output secring.ascCopy the code

Fill in the information required by the key. In one step, you need to fill in the encryption password. Press Enter to fill in the empty command. The private key file secring.asc and the public key file pubr.asc will appear in the current directory.

Next, you need to upload the public key.

Access the MIT PGP Key Server, paste the pubr. asc content into “Enter ASCII-Armored PGP Key here:”, and click “Submit this Key to the Keyserver! ” .


Generate a Github Personal Access Token

CI automatically assigns a version tag to the version in the Github repository via the SBT-Best-practice plug-in when publishing Scala libraries. Therefore, you need to set the Github repository modification permission for CI. This can be done with the Github Personal Access Token.

Access Sign in to GitHub · GitHub, then fill in Token Description and check public_repo permissions.


Making generates a similar 74 bf3a944382ec8e07625a6e55eb05a416ca585d Personal Access Token. Please save this Personal Access Token for later use.

Create a Secret Gist to hold all passwords and keys

All of these passwords and keys can be set via Sbt. However, I don’t think you would want to put your password in a public repository.

So I suggest you put your passwords and keys in Secret Gist, which only you know. Then set the Secret Gist URL in the Travis CI Secret environment variable. Then, when CI runs the SBT task, it can read the environment variable and access Secret Gist to get all these passwords and keys.

Visit https://gist.github.com/ and click the “Add File” button to Add three files:

secret.sbt

// Github Personal Access Token githubCredential in Global := Bf3a944382ec8e07625a6e55eb05a416ca585d PersonalAccessToken (" 74 ") / / should fill in what you have just registered here Sonatype use account and password credentials in Global Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", "Your Sonatype account ", "Sonatype password ") val currentDirectory = file(sourcecode.file ()).getParentFile pgpSecretRing := currentDirectory / "secring.asc" pgpPublicRing := currentDirectory / "pubring.asc" pgpPassphrase := Some(Array.empty)Copy the code

secring.asc

Please copy the secring.asc content generated by GnuPG here.

pubring.asc

Please copy the pubr.asc content generated by GnuPG here.

Finally, click the “Create Secret Gist” button to generate the secret GIST.

Please take note of the new generation Secret Gist url, like https://gist.github.com/Atry/xxxxxxxxxxxxxxxxxxxx

Create a secret environment variable for the Travis CI

Add in your Travis CI project Settings panel SECRET_GIST environment variables, set as you have just generated Secret Gist https://gist.github.com/Atry/xxxxxxxxxxxxxxxxxxxx


Create deploy. SBT to read the SECRET_GIST environment variable

Deploy. SBT contains the Settings for publishing Scala libraries. We enable Travis and SonatypeRelease, then read the SECRET_GIST environment variable and load the secret.sbt file in Secret Gist


enablePlugins(Travis)

enablePlugins(SonatypeRelease)

lazy val secret = project settings(publishArtifact := false) configure { secret =>
  sys.env.get("SECRET_GIST") match {
    case Some(gitUri) =>
      secret.addSbtFilesFromGit(gitUri, file("secret.sbt"))
    case None =>
      secret
  }
}Copy the code

Precautions for daily use

About the deploy. SBT. Disabled

After pushing.travis. Yml, project/plugins. SBT, LICENSE, build. SBT, and deploy. SBT files to Git repository, CI triggers automatic testing and automatic publishing. After each successful publication, SBT-best-practice automatically changes the name of deploy.sbt to deploy.sbt.disabled, so if future commits are made, automatic tests will only be triggered, not automatic publishing. If you want to release the next release, manually rename deploy.sbt.disabled to deploy.sbt to trigger CI to perform the automatic release process.

About version Number

Once a release is triggered, CI automatically changes the version number recorded in version.sbt. For example, if you have 1.0.0-snapshot in your repository, the CI will first change the version number to 1.0.0 and then mark it with GIT tag, and then change the version number to 1.0.1-snapshot. If you want the next release to be 1.5.0, you need to manually change the version number recorded in version.sbt to 1.5.0-snapshot before triggering the next automatic release.

A link to the

  • Scala – a multi-paradigm programming language that underlies all the technologies covered in this article.
  • Scala-project-template-scala project template, similar to the structure described in this article, but uses a private Git repository instead of Secret Gist to store passwords, so the deploy.sbt content is slightly different.
  • Q.scala – Fully set up for automatic testing and publishing Scala libraries.
  • SBBT – Simple Build Tool, the most widely available Build Tool in the Scala community.
  • Sbt-best-practice-sbt plug-in, which provides all the publishing features mentioned in this article.
  • µTest – a simple and easy-to-use Scala testing framework.
  • Travis CI – provides continuous integration services for Github projects. In addition to Travis CI, other continuous integration solutions include GoCD, Jenkins, Bamboo, etc. Compared to these solutions, the Travis CI is very lean and completely omits the concept of pipeline, which I love. Travis CI is freely available for open source projects. The most common continuous integration service I have seen in open source projects is Travis CI.