自分が出したpull reqがconflictしていたら通知するGitHub Action君

というのを作った。

仕事で自分が関わっている特定のリポジトリでは、以前からそういうの作ってbotがpull reqに直接コメントするようにしている。(自分のものだけではなく、そのリポジトリのpull req全てに対して)

そうではなく、自分が出したOSS含めた任意のpull reqでconflictしていたら通知欲しいので、作った。

https://github.com/xuwei-k/cron/commit/17c9c731593ce5de9178fabdb26c088631d74e74

通知先はとりあえずslackにしたが、ここはメールでもなんでも、好きものでいいと思う。

自分のJavaScriptの能力はゴミなので、明らかにリファクタ出来そうだけれど、とりあえず動いたので一旦妥協した。 改変して使う際は q のauthor部分は、直接埋め込んであるけれど、自分のgithubのidに変えてください。

f:id:xuwei:20211230163940p:plain
slack

on:
  schedule:
  - cron: '0 1 * * *'
  workflow_dispatch:
jobs:
  check-conflict:
    timeout-minutes: 5
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - run: npm install @actions/core
    - uses: actions/github-script@v5
      id: conflict_pull_requests
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        script: |
          const script = require(`${process.env.GITHUB_WORKSPACE}/cron.js`)
          console.log(script({github, context}))
    - uses: slackapi/slack-github-action@v1.16.0
      with:
        payload: "{\"text\":\"${{ steps.conflict_pull_requests.outputs.value }}\"}"
      env:
        SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
const core = require(`${process.env.GITHUB_WORKSPACE}/node_modules/@actions/core`);

module.exports = ({github, context}) => {
  (async () => {
    // https://octokit.github.io/rest.js/v18#search-issues-and-pull-requests
    const pulls = await github.rest.search.issuesAndPullRequests({
      q: "is:open+is:pr+author:xuwei-k+archived:false",
      per_page: 100
    });
    const conflicts = [];
    for (const pull of pulls.data.items) {
      console.log(pull.url);
      const pull_req = await github.request(`GET ${pull.pull_request.url}`)
      if (pull_req.data.mergeable === false) {
        console.log(pull_req.data.mergeable);
        conflicts.push(pull.html_url);
      }
    }
    console.log(conflicts);
    if (conflicts.length == 0) {
      core.setOutput('value', 'There is no conflict pull requests😀');
    } else {
      core.setOutput('value', 'conflict pull requests\\n' + conflicts.join("\\n"));
    }
  })();
};

2021年の最新技術を使った場合のScalaのコンパイル速度

ここでいう最新技術とは以下です。

  • JDK8や11よりも、17の方が速い?
  • M1 Macが速い?(2021年最新のM1 Maxではなく、2020のMacbook Pro 13インチのM1です・・・。M1 Max欲しい!!! => 最後に追記したぞ)
  • Scala 2より3の方が速い?

自分の最近の経験上、それらが速いはず?なので。

上記は、全部場合による(projectによる)かもしれないし、あまり変わらないパターンも含まれているかもしれませんが、とりあえず一部(Scala 2自体のcompile)を除いて、上記の条件でコンパイル速度を計測してみたら、 数年前の感覚と比較して結構速い感じがあったので、それの計測結果の共有です。

続きを読む

Scala 2のJDK17対応状況

最新情報は以下の公式の情報をご覧ください。で終わるのですが、これ書いている2021年9月現在の情報を簡単にまとめておきます(ただのtweet貼り付け)

続きを読む

Scala 3でMatchableに推論されたら警告かエラーにするcompiler plugin

scala.Matchable自体の解説はしませんが、AnyValやAnyやAnyRefや Product with Serializable と同様に、それに推論されたら、わりとミスなことが多い気がするので、作ってみました。

続きを読む

MockitoのwhenとScala 3の型推論

Scala 2ではcompile errorなのにScala 3では実行時にClassCastExceptionやその他変なエラーになる。 なるほど・・・Scala 3のcompilerはあまり悪くない気がするから、よけいに辛い・・・

続きを読む

Scala 3のmacroによる型安全かつ実行時にリフレクションにならないClose型クラス(ローンパターン)の実装

というのがおそらく作成できたけれど、もっと書き方改善可能なところあったら教えて下さい。 このくらいすでに、Scala 3でも前例が存在する気もするけど、とりあえず(あまり前例は調査はせずに)自作しました。

  • テスト書いてあるとおり、指定されたcloseメソッドがなかったらコンパイル時にエラーです
  • コンパイル時にはstructural typeのような感じですが、本物のメソッド呼び出しに、コンパイル時に置き換えてるはずなので、実行時に余計なコストはかからないはずです*1

ところでScala 3側のbugなのかsbt側のbugなのか、仕様なのかわからないけど、これ全部いっしょにコンパイルすると(typeCheckErrorsなど使うと?) 変なエラーが出るので、いい感じに分けてコンパイルするかなにか工夫をしないといけなかった、面倒・・・。

gist.github.com

*1:もちろん型クラスのインスタンス生成コストくらいはあります。Scalaの普通のstructural typeみたいに、リフレクションにはならない、の意味。型クラス自体をさらにinlineは単純には無理だった https://twitter.com/xuwei_k/status/1398978228400754688