Skip to content

Instantly share code, notes, and snippets.

@thinca
Created May 7, 2023 10:27
Show Gist options
  • Select an option

  • Save thinca/ce4db5e7c7f7e5e1a18ad9f6e20740d0 to your computer and use it in GitHub Desktop.

Select an option

Save thinca/ce4db5e7c7f7e5e1a18ad9f6e20740d0 to your computer and use it in GitHub Desktop.

Revisions

  1. thinca created this gist May 7, 2023.
    3 changes: 3 additions & 0 deletions Gemfile
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    source 'https://rubygems.org'

    gem 'webrick'
    8 changes: 8 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,8 @@
    ## 使い方

    - `compose.yml` と同じディレクトリに置く
    - `compose.yml` のあるディレクトリで `git clone https://github.com/thinca/MODal modal` をして `modal` ディレクトリにリポジトリがあるようにしておく
    - GitHub Webhooks で設定した token を `SECRET_TOKEN` に設定する
    - `sbt``~/.local/bin/sbt` にある前提になっている
    - LISTEN ポートは 20001 (適当)
    - その他、`X-Forwarded-For` ヘッダを表示するようにしていたり payload をデバッグ目的で全ダンプしていたりと全体的に雑
    62 changes: 62 additions & 0 deletions deploy.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    require 'webrick'
    require 'openssl'
    require 'json'

    SECRET_TOKEN = 'XXX'

    def secure_compare(a, b)
    return false unless a.bytesize == b.bytesize

    OpenSSL.fixed_length_secure_compare(a, b)
    end

    def verify_signature(payload_body, signature)
    return false unless signature
    calced_signature = "sha256=#{OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), SECRET_TOKEN, payload_body)}"
    secure_compare(calced_signature, signature).tap do |b|
    puts "signature doesn't match: #{calced_signature} <=> #{signature}" unless b
    end
    end

    def deploy(payload)
    unless payload[:ref] == 'refs/heads/main'
    puts "Does not a target ref. ignored: #{payload[:ref]}"
    return
    end
    spawn('bash', '-c', <<-SHELL, chdir: __dir__)
    set -eu
    cd modal
    git pull
    rm -fr target/scala-*
    git rev-parse --short @ > src/main/resources/commit_hash
    ~/.local/bin/sbt package
    cp target/scala-*/modal_*.jar ../data/plugins
    cd ..
    docker compose exec minecraft rcon-cli plugman reload MODal
    SHELL
    end

    srv = WEBrick::HTTPServer.new({
    :BindAddress => '127.0.0.1',
    :Port => 20001,
    })

    srv.mount_proc('/') { |req, res|
    puts "X-Forwarded-For: #{req['X-Forwarded-For']}"
    if req.request_method != 'POST'
    res.status = 405
    elsif !verify_signature(req.body, req['x-hub-signature-256'])
    res.status = 403
    else
    payload = JSON.parse(req.body, symbolize_names: true)
    pp payload
    deploy(payload)
    res.status = 200
    end
    res.content_type = 'text/plain'
    res.body = res.reason_phrase
    }

    Signal.trap(:INT){ srv.shutdown }
    srv.start