@@ -15,7 +15,7 @@ Haskell-jpのコンテンツの一つとして[Haskell Antenna](https://haskell.
1515
1616[ 2019年の今頃、これを自動毎時更新しようと Drone Cloudによる毎時更新を設定しました] ( https://haskell.jp/blog/posts/2019/hourly-antenna.html ) 。
1717
18- しかし。。。なんと3月ぐらいからこれが止まっています(どうやら、Drone Cloudのこの機能を利用してマイニングをした人がいたらしく止めてしまったようです )。
18+ しかし。。。なんと3月ぐらいからこれが止まっています(どうやら、[ Drone Cloudのこの機能を利用してマイニングをした人がいたらしく止めてしまった ] ( https://discourse.drone.io/t/cron-on-cloud-drone-io/3899/2 ) ようです )。
1919現在は** 僕がだいたい毎朝1回、手動でCIを回しています** 。。。
2020
2121ずっとなんとかしなきゃなぁと思い続けてはや9ヶ月。
@@ -24,14 +24,14 @@ Haskell-jpのコンテンツの一つとして[Haskell Antenna](https://haskell.
2424
2525# どうするか?
2626
27- [ GCPにはalways freeプランというのがあり] ( https://cloud.google.com/free/docs/gcp-free-tier?hl=ja#always-free ) 、GCEインスタンスはf1 -microであれば一台だけ無料です(2020/1現在)。
28- これに、毎時実行して更新をプッシュする antenna プログラムを仕込んでおけば良いではないかということに気づきました 。
27+ [ GCPにはalways freeプランというのがあり] ( https://cloud.google.com/free/docs/gcp-free-tier?hl=ja#always-free ) 、GCEインスタンスの場合はf1 -microであれば一台だけ無料です(2020/1現在)。
28+ これに、毎時実行して更新をプッシュするantennaプログラムを仕込んでおけば良いではないかということに気づきました 。
2929
30- Haskell Antenna自体はGitHub Pagesであり、HTMLなどは [ haskell-jp/antenna] ( https://github.com/haskell-jp/antenna ) という Haskell製CLIアプリケーションで生成しています。
31- これをcronか何かで毎時実行しても良いですが
30+ Haskell Antenna自体はGitHub Pagesであり、HTMLなどは[ haskell-jp/antenna] ( https://github.com/haskell-jp/antenna ) という Haskell製CLIアプリケーションで生成しています。
31+ これをcronか何かで毎時実行すればいいんですけど
3232
33- 1 . cronとDockerの組み合わせが割とめんどくさい(antenna は Docker Image として提供している )
34- 2 . cronにした場合更新を GitHub にどうやってプッシュしようかなどを考えるのがめんどくさい
33+ 1 . cronとDockerの組み合わせが割とめんどくさい(antennaはDocker Imageとして提供している )
34+ 2 . cronにした場合更新をGitHubにどうやってプッシュしようかなどを考えるのがめんどくさい
3535
3636という問題があります。
3737
@@ -40,17 +40,17 @@ Haskell Antenna自体はGitHub Pagesであり、HTMLなどは [haskell-jp/antenn
4040
4141# 実装する
4242
43- antennaプログラムに「gitコマンドを読んでGitHubリポジトリに更新をプッシュする機能 」と「全てを毎時実行する機能」の2つを組み込む必要があります。
43+ antennaプログラムに「gitコマンドを使ってGitHubリポジトリに更新をプッシュする機能 」と「全てを毎時実行する機能」の2つを組み込む必要があります。
4444ここで後方互換性を維持するために、これらはオプションでオンする機能にしましょう。
4545なのでまずは、antenna CLIアプリケーションのオプションを整理するところから始めます。
4646
4747## オプションの整理
4848
49- 改修前の antenna は特別オプションを持っていません 。
49+ 改修前のantennaはオプションを持っていません 。
5050` getArgs ` で引数(設定ファイルのパス)を受け取るだけです
5151
5252``` haskell
53- import System.Environment (getArgs )
53+ import System.Environment (getArgs )
5454
5555-- generate 関数が設定から HTML ファイル群を生成する IO アクション
5656main :: IO ()
@@ -63,7 +63,6 @@ main = (listToMaybe <$> getArgs) >>= \case
6363
6464``` haskell
6565-- withGetOpt' は usage を独自で扱えるように拡張した Data.Extensible.withGetOpt です
66- -- runCmd 関数が内部で runCmd を呼び出します
6766main :: IO ()
6867main = withGetOpt' " [options] [input-file]" opts $ \ r args usage ->
6968 if | r ^. # help -> hPutBuilder stdout (fromString usage)
@@ -93,18 +92,38 @@ verboseOpt = optFlag ['v'] ["verbose"] "Enable verbose mode: verbosity level \"d
9392
9493差分全体はこの[ PR] ( https://github.com/haskell-jp/antenna/pull/20 ) で確認することができます。
9594興味のある人はみてみてください。
96- ついでに ` runCmd ` 関数は[ mix.hs] ( https://github.com/matsubara0507/mix.hs ) を使って ` RIO env () ` のボイラーテンプレートを減らしています(実はおいおい役に立ちます)。
95+ ` generate ` 関数は以下の ` runCmd ` 関数から呼ばれています
96+
97+ ``` haskell
98+ import Mix
99+ import Mix.Plugin.Logger as MixLogger
100+
101+ runCmd :: Options -> Maybe FilePath -> IO ()
102+ runCmd _ Nothing = error " please input config file path."
103+ runCmd opts (Just path) = do
104+ config <- readConfig path
105+ let plugin = hsequence
106+ $ # logger <@=> MixLogger. buildPlugin logOpts
107+ <: # config <@=> pure config
108+ <: nil
109+ Mix. run plugin $ generate path
110+ where
111+ logOpts = # handle @= stdout
112+ <: # verbose @= (opts ^. # verbose)
113+ <: nil
114+ ```
115+
116+ ` runCmd ` 関数は[ mix.hs] ( https://github.com/matsubara0507/mix.hs ) を使って ` RIO env () ` のボイラーテンプレートを減らしています(実はおいおい役に立ちます)。
97117
98118## git コマンドを呼ぶ
99119
100- Haskellアプリケーションからgitコマンドを実行するにはShellyを使うことにします 。
101- そこで、mix .hsのshellプラグインを使うことで簡単に実装することができます。
120+ Haskellアプリケーションからgitコマンドを実行するには [ Shelly ] ( https://hackage.haskell.org/package/shelly ) を使うことにします 。
121+ Shellyはmix .hsのshellプラグインを使うことで簡単に実装することができます。
102122まずはコミットを作る部分を実装しましょう
103123
104124``` haskell
105125import qualified Git -- 自作Shelly製gitコマンド関数群
106- import Mix
107- import qualified Mix.Plugin.Shell as MixShell
126+ import qualified Mix.Plugin.Shell as MixShell
108127
109128runCmd :: Options -> Maybe FilePath -> IO ()
110129runCmd opts (Just path) = do
@@ -133,7 +152,7 @@ commitGeneratedFiles = do
133152```
134153
135154全ての差分はこの[ PR] ( https://github.com/haskell-jp/antenna/pull/21 ) から確認できます。
136- PRを見ればわかりますが、 ` runCmd ` 関数に追記したのは ` when (opts ^. #withCommit) ` から始まる2行です(` Options ` に ` #withCommit ` を追加しています)。
155+ ` runCmd ` 関数に追記したのは ` when (opts ^. #withCommit) ` から始まる2行です(` Options ` に ` #withCommit ` を追加しています)。
137156mix.hsのshellプラグインを使うことでShellyのログをだいたいそれっぽくrioのロガーに流してくれます。
138157
139158次に、` git push ` も実装します
@@ -156,16 +175,16 @@ pushCommit = do
156175
157176前から使っている ` gitConfig ` は設定ファイルからgitコマンドに関する設定を取ってきています(例えば、どのファイルをコミットするかやどのブランチにプッシュするかなど)。
158177
159- 差分があった場合は` git commit ` を実行し、最後に` git push ` するようなオプション、` --with-commit ` と` --with-push ` を実装できました(他にも実装していますが割愛)。
178+ これで、 差分があった場合は` git commit ` を実行し、最後に` git push ` するようなオプション、` --with-commit ` と` --with-push ` を実装できました(他にも実装していますが割愛)。
160179
161180## 毎時実行
162181
163182メインディッシュである毎時実行です。
164- Haskell-jp Slackで、スケジューリング実行をHaskellアプリケーション内で行うのにちょうど良いパッケージはありますか?と尋ねたところcronというパッケージを紹介してもらいました (名前がややこしい笑)。
183+ Haskell-jp Slackで、スケジューリング実行をHaskellアプリケーション内で行うのにちょうど良いパッケージはありますか?と尋ねたところ [ cron ] ( https://hackage.haskell.org/package/cron ) というパッケージを紹介してもらいました (名前がややこしい笑)。
165184調べてみたところ、ちょうど良さそうなのでこれを使うことにします
166185
167186``` haskell
168- import System.Cron (addJob , execSchedule )
187+ import System.Cron (addJob , execSchedule )
169188
170189main :: IO ()
171190main = withGetOpt' " [options] [input-file]" opts $ \ r args usage ->
@@ -184,10 +203,11 @@ withCron act t = do
184203
185204全ての差分はこの[ PR] ( https://github.com/haskell-jp/antenna/pull/22 ) から確認できます。
186205すっごい簡単ですね。
187-
188206ついでに、毎日実行と毎分実行するオプションも追加しています。
189207
190- # インスタンスを起動する
208+ これでアプリケーションの方は出来上がったので、こいつをGCEインスタンスで動作させてみましょう。
209+
210+ # インスタンスで起動する
191211
192212まずはGCP Consoleからインスタンス作成します。
193213構成は次の通りです
@@ -200,7 +220,7 @@ withCron act t = do
200220GCP ConsoleからSSHして、docker コマンドをインストールします(やり方は[ 公式サイト] ( https://docs.docker.com/install/linux/docker-ce/ubuntu/ ) のをそのまま)。
201221ここまでできたら試しに ` sudo docker pull haskelljp/antenna ` して最新のイメージを取得してみましょう。
202222
203- 次に、GitHubにプッシュするためにSSH Keyを生成してデプロイキーを haskell-jp/Antenna に設定します 。
223+ 次に、GitHubにプッシュするためにSSH Keyを生成してデプロイキーを haskell-jp/antenna リポジトリに設定します 。
204224できたら適当に ` git clone git@github.com:haskell-jp/antenna.git ` してブランチを ` gh-pages ` に切り替えます。
205225
206226あとは次のコマンドでantennaプログラムを実行するだけです
0 commit comments