Skip to content

Latest commit

History

History
121 lines (85 loc) 路 5.5 KB

readme.md

File metadata and controls

121 lines (85 loc) 路 5.5 KB

Scala.js facades for the Probot framework 馃

This project contains Scala.js facades for the Probot framework used to build GitHub Apps on Node.js.

馃毀 WORK IN PROGRESS 馃毀

This project is in active development, there are no published releases yet. Things may break without a warning, so don't rely on it.

If you want to experiment with it and write a GitHub bot in Scala.js, don't hesitate to write to the Gitter chat and ask any questions. And if you're looking for ideas, check out the dedicated probot/ideas repo.

Usage

First of all you should head to the Probot docs and read at least the Getting Started part. It explains the basics very well and gives you a general understanding of how this framework functions.

For interacting with the GitHub API this library depends on the Scala.js facades for the Octokit library: scalajs-octokit.

For the usage example refer to the scalafmt-probot project. The project setup will be simplified in the future.

Installation

馃洜 Check installation instructions later, when there is a published release...
  1. Add Probot dependency to your project. It's important that the version of the underlying JS library matches the one this facade is built for.

    • If it's a Node.js project where you manage dependencies with npm, run

      npm install probot@next --save
    • If it's a Scala.js project use [scalajs-bundler] and add to your build.sbt:

      Compile/npmDependencies += "probot" -> "next"

    These facades are based on the TypeScript version of Probot which is not released yet, but is available under the next version tag.

  2. Add facades dependency to your build.sbt:

    resolvers += Resolver.jcenterRepo
    libraryDependencies += "laughedelic" %%% "scalajs-probot" % "<version>"

    (see the latest release version on the badge above)

  3. To turn the project into a runnable application add to your build.sbt:

    scalaJSUseMainModuleInitializer := true

    Then in the code implement a Probot.Plugin (which is a function Application => Unit) and define a main method:

    import laughedelic.probot._
    
    object ProbotApp {
    
      def plugin(app: Application): Unit = ???
    
      def main(args: Array[String]): Unit = ProbotApp.run(plugin)
    }

    See the example below.

  4. (Optionally) for local testing you may want to add a dependency on the smee-client

    Compile/npmDependencies += "smee-client" -> "1.0.1"

    Then you can run the application with sbt run it should work the same as the npm start (=probot run ./lib/index.js) from the Probot docs. The only difference is that it ignores any command line args, so I have to set environment variables. You can set them in the .env file.

Example

Here's a translation of the Hello World example from the Probot docs to Scala:

import laughedelic.probot._
import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue

object HelloWorld {

  def plugin(app: Application): Unit = {

    app.on("issues.opened") { context =>
      // Post a comment on every new issue
      context.github.issues.createComment(
        owner  = context.issue().owner,
        repo   = context.issue().repo,
        number = context.issue().number,
        body   = "Hello World! 馃憢"
      )
    }
  }

  def main(args: Array[String]): Unit = Probot.run(plugin)
}

The translation from JavaScript is pretty straightforward. A couple of things to notice:

  • In JS all GitHub API parameters are just objects, so it's possible to reuse context.issue and write
    context.github.issues.createComment(
      // context.issue appends given object to { owner: ..., repo: ..., number: ... }
      context.issue({body: 'Hello World!'})
    )
    In Scala createComment method has typed arguments, so we have to pass those values from the context explicitly. I don't think it's too verbose, but if anybody has an idea how to improve it, let me know.
  • { context => ... } callback returns a Future which is converted to a js.Promise, this is why the execution context import is needed.

For a more complex example and the general project setup refer to the scalafmt-probot project.