個人的に文章書いたりソースコード書いたりといった時に fossil-scm を長年使っています。
特徴としてはこんな感じ。
- Distributed / Centralized どっちも行ける感
- wiki / Bug Tracking等を内蔵
- 1ファイル/コマンドで全部入り(コピーすればすぐ使える)
- repositoryも1ファイルでバックアップ楽ちん
コマンド一発で 各種 Server としても動かせてとても便利なのですが、内蔵している th1スクリプトからの httpアクセス方法については、ドキュメントや実装上の問題等も多いので Webで検索しても成功例がなかなか見つからないと思います。
色々制約はあるのですが、通知目的ぐらいであれば全然出来ないってわけでも無いのでそのやり方について。
なお、CommitやPush時等で Chatbotを実装したいといった場合は Hookを使う方が楽ちんなはず。
th1スクリプトについて
th1は Tclを元にしたミニマルな言語です。
th1のスクリプトはコマンドの羅列。ifも 一つのコマンドです。
コマンドは 改行か ; で終端。
{ } で括られたのはブロックではなく複数行文字列。
言語としての文法らしい文法があまりないのでシンプルですが、Cっぽく見えちゃうあたりが逆に罠な感じに思います。
「なんとなく見ればわかる」気もしますが、一度公式のドキュメント等を参照していただくと良いと思います。
ベースにある tclについては tcl.tkのサイト にあるドキュメント。
日本語の解説だと株式会社フリーソフトネットのサイトにある解説が、とても役に立つかと思います。
th1 でサポートしている tclのコマンド及び、th1 独自コマンドは fossil-th1 公式ドキュメント を参照してください。
th1: httpコマンド
httpコマンドは以下の2パターンだけになります。
- GETなら
http -asynchronous -- URL
- POSTなら
http -asynchronous -- URL POSTDATA
公式ドキュメントを見ると POST 時の Content-Typeは text/plain だと書かれているのですが、
正しくは application/x-www-form-urlencoded かと思います(2.15.1時点1) 。
この呼び出しの結果を受け取る方法は現在のところ無い。はず。
th1-uri-regexp 設定
th1 からhttpアクセス可能な URLはなんでもOKというわけではなく、
各レポジトリ/グローバル設定の th1-uri-regexp に 正規表現で許可するURLを設定する必要があります2
この設定は repository毎の local設定で良いと思うので repository を checkoutした フォルダに行ってから、以下のようなコマンドを実行します3。
例では DiscordのWebHooks APIに限定して許可するような設定です。
fossil status && fossil set th1-uri-regexp "https://discord.com/api/webhooks/.*"
個人的に使ってるだけなら globalで全部許しちゃうというのもありかと思います。
fossil set th1-uri-regexp "http.*" --global
認証局証明書の設定
fossilは ssl通信に opensslを使っています。
信頼出来るルート証明書について OSが持っている証明書ストアを使わないため、なんとかする必要があります。
Debianや Ubuntu等では sudo apt-get install ca-certificates
で行けると思います。
macではやったことないですが(作業不要かな?)、Windowsの場合は以下の二通りのうちどちらかで対応します。
Windows対応その1 ルートCA証明書をインストール
ここは色々問題がある4のですが、公式が配布している x64版 fossil.exe の場合、
C:\Program Files\Common Files\SSL\cert.pem
に証明書を置くという方法が取れます。
設定する証明書は、PublicなCAでれば curlが配布している ルートCA一覧を使うと良いでしょう。
ダウンロードした cacert.pem
を C:\Program Files\Common Files\SSL\cert.pem
として保存します。
curlが使える環境であれば 管理者権限で以下のバッチで設定できます。
mkdir "C:\Program Files\Common Files\SSL"
curl -LRs https://curl.se/ca/cacert.pem -o "C:\Program Files\Common Files\SSL\cert.pem"
管理者権限が無く、上記のパスにファイルを置けないという場合、
以下の「その2」の設定を試してみてください。
Windows対応その2 ルートCA証明書のパスを指定する
ssl-ca-location にフルパスで設定を入れれば そのファイルが使われます。
サンプルの設定バッチファイルとしては以下です。
SET "CERTPATH=%LOCALAPPDATA%\fossil_cacert.pem"
curl -LRs https://curl.se/ca/cacert.pem -o "%CERTPATH%"
fossil settings ssl-ca-location "%CERTPATH%" --global
ここでは global設定としていますが、Private CAを利用している等で、CAの証明書を設定したい場合は Repository Localの設定を入れる等すれば良いかと。
設定確認
テストとして以下のコマンドを実行します。
fossil test-th-eval --open-config "http -asynchronous -- https://discord.com/api/webhooks"
何も出なければ 設定はうまくいってると思います。
th1-uri-regexpの設定にしくってる場合は以下のように url not allowed
エラーが表示されます。
C:\work\fossil\project>fossil test-th-eval --open-config "http -asynchronous -- https://discord.com/api/webhooks"
TH_ERROR: url not allowed
CA証明書の設定が出来ていないと以下の様に Verify出来ないのでサーバ証明書を受け入れるかどうかを聞いてきます。
C:\work\fossil\project>fossil test-th-eval --open-config "http -asynchronous -- https://discord.com/api/webhooks"
Unable to verify SSL cert from discord.com
subject: C = US, ST = CA, L = San Francisco, O = "Cloudflare, Inc.", CN = sni.cloudflaressl.com
issuer: C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
sha256: 8a50f2ecf6273f9416179361a05abe5fe2c6b9acb227efee8eebc511f902972a
accept this cert and continue (y/N)? N
TH_ERROR: SSL cert declined
なお、ここで受け入れをして y を答えるとSSL証明書確認の例外として保存する事も出来ます。
accept this cert and continue (y/N)? y
remember this exception (y/N)? y
この受け入れ情報が保存されるのは repository localではなく、global設定("%LOCALAPPDATA%\_fossil") のDBなので、ここらへん理解した上で実行する必要があるかと思います。
また、fossil uiで開くWeb UIでも th1スクリプトを入力する事が出来る(http://localhost:8080/admin_th1 等)のですが、設定をしくじっていた場合、Webページが戻ってこない事がある5のでコマンドラインでやりましょう。
Discordへの Chat送信
試しに Discordの Webhooksに Postしてみます。
まずth1スクリプトファイルを作ります。WEBHOOK.ID と WEBHOOK.TOKEN は自分で取得して設定してください。
http -asynchronous -- {https://discord.com/api/webhooks/WEBHOOK.ID/WEBHOOK.TOKEN} {content=Hello%20from%20Fossil-SCM}
コマンドで投入
fossil test-th-source --open-config discord-post.th
こんな感じで postできれば 確認完了です。
まとめ
- 認証局の証明書の設定を忘れずに。特にWindows
- デフォルトではhttpアクセスはすべてのURLについて禁止されているので、許可するURLを設定
- POSTする Content-Typeは application/x-www-form-urlencoded
-
it will be interpreted as text/plain and the POST method will be used ↩
-
これくらいはhttpコマンドのドキュメントに書いておいても良いと思うのですが……。設定値のドキュメントには記載があります。 ↩
-
Fossilの管理下にないFolderで実行すると Global設定になってしまいます。fossil statusを仕込んでいるのはfoolproofです。 ↩
-
X509_STORE_set_default_pathsで設定しているので、hardcoded default paths で設定されます。opensslが dllリンクだと環境依存のため不定としか言えない気がしますが、公式のfossil.exeは static linkのため、2.15.1 でのデフォルトは この記事に書いたパスです。
C:\Program Files\Common Files\SSL\certs\*
のディレクトリ指定もあるはずです。ただ、私が試す限りこちらは効いてないようでした。原因までは探っていません。 ↩ -
多分SSL証明書のConfirmationで止まってるような気がしています……。 ↩