class: center, middle, inverse, title-slide # rocker/r-verとかのアップデートをちょっと自動化した話 ## 第93回R勉強会 @ 東京(#TokyoR) ### eitsupi ### 2021-07-03 (updated:2021-11-30) --- # [@eitsupi](https://twitter.com/eitsupi) .center[![eitsupi](./image/eitsupi.jpg)] - R歴二年くらい - Docker歴一年くらい --- # Docker(Linuxコンテナ)を使うメリット - 環境構築かんたん。 - Dockerさえセットアップすればどのマシンでも同じように動く。多分。 - 破棄も簡単。ライブラリの依存関係が壊れたらコンテナを捨てるだけ。 - 日本語版WindowsでもShift-JISの呪いから解放される。重要。 --- # rocker/r-verとは? - (後述の派生含めて)よく使われるRのコンテナイメージのひとつ - GitHubリポジトリは[rocker-org/rocker-versioned2](https://github.com/rocker-org/rocker-versioned2) - Docker Official Imagesの[r-base](https://hub.docker.com/_/r-base)との比較 <table> <thead> <tr> <th style="text-align:left;"> 観点 </th> <th style="text-align:left;"> r-base </th> <th style="text-align:left;"> rocker/r-ver </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> ベースイメージ </td> <td style="text-align:left;"> Debian </td> <td style="text-align:left;"> Ubuntu </td> </tr> <tr> <td style="text-align:left;"> Rパッケージ </td> <td style="text-align:left;"> ソースインストール(遅い) </td> <td style="text-align:left;"> バイナリインストール(速い) </td> </tr> <tr> <td style="text-align:left;"> Rパッケージ固定 </td> <td style="text-align:left;"> なし </td> <td style="text-align:left;"> あり(後述) </td> </tr> <tr> <td style="text-align:left;"> RStudio </td> <td style="text-align:left;"> なし </td> <td style="text-align:left;"> rocker/rstudio </td> </tr> <tr> <td style="text-align:left;"> アーキテクチャ </td> <td style="text-align:left;"> 色々 </td> <td style="text-align:left;"> amd64のみ </td> </tr> </tbody> </table> --- # rocker/r-verのレシピ `rocker/r-ver`は再現性を重視しており、古いバージョンのRのイメージでは「そのバージョンのRが最新だった時代のパッケージをインストールする」という挙動をとる。 これはほぼ毎日CRANのミラーを取得しているRSPM(R3.6.3以前はMRAN)の特定の日付のミラーをCRANとして使用することで実現している。 READMEに書かれているように、だいたい以下のようなルールでDockefileが作られている。 1. そのバージョンのRがリリースされた時点で最新のUbuntu LTSをベースにする。 2. そのバージョンのRが最新だった最後の日のRSPMのCRANミラーをデフォルトのRパッケージリポジトリにする。 3. (明言されていないが)RStudioもそのバージョンのRが最新だったときの最新バージョンで固定する。 --- # 問題 - RやRStudioのリリース時に手作業でDockefileのアップデートやイメージのビルドを行っているため最新バージョンをすぐに試せない - 手動編集による変数の設定ミス多発(CRANのスナップショットが本来の日付の一年前だったり……) --- # 自動化したい! 誰が設定しても同じ値になるようなレシピなのだから自動化できるはず! --- # Rのリリース日 `rversions::r_versions`関数によりRのSVNリポジトリ <https://svn.r-project.org/R/tags/> から良い感じに取得可能(よく分かってません……) ```r rversions::r_versions() |> tail() ``` ``` ## version date nickname ## 120 4.0.3 2020-10-10 07:05:24 Bunny-Wunnies Freak Out ## 121 4.0.4 2021-02-15 08:05:13 Lost Library Book ## 122 4.0.5 2021-03-31 07:05:15 Shake and Throw ## 123 4.1.0 2021-05-18 07:05:22 Camp Pontanezen ## 124 4.1.1 2021-08-10 07:05:06 Kick Things ## 125 4.1.2 2021-11-01 08:05:12 Bird Hippie ``` --- # Ubuntu LTSのリリース日 Ubuntuがローカルに持っているcsvファイルから取得可能 ```r read.csv("/usr/share/distro-info/ubuntu.csv") |> dplyr::select(version, series, release, eol, eol.esm) |> tail() ``` ``` ## version series release eol eol.esm ## 31 19.10 eoan 2019-10-17 2020-07-17 ## 32 20.04 LTS focal 2020-04-23 2025-04-23 2030-04-23 ## 33 20.10 groovy 2020-10-22 2021-07-22 ## 34 21.04 hirsute 2021-04-22 2022-01-20 ## 35 21.10 impish 2021-10-14 2022-07-14 ## 36 22.04 LTS jammy 2022-04-21 2027-04-21 2032-04-21 ``` --- # CRANミラー Rのリリース日とUbuntuのコードネームで生成 |> `pak::repo_ping`関数で有効性確認 ```r "https://packagemanager.rstudio.com/cran/__linux__/focal/2021-05-17" |> (function(x) pak::repo_ping(cran_mirror = x, bioc = FALSE))() ``` ``` ## Repository summary: source ## CRAN @ packagemanager.rstudio.com ✔ (935ms) ``` --- # RStudio Serverのリリース日 Gitのタグの情報をGitHub APIで取得 |> タグの打たれているコミットの日付を取得 ```r httr::GET( "https://api.github.com/repos/rstudio/rstudio/tags", httr::add_headers(accept = "application/vnd.github.v3+json"), query = list(per_page = 5) ) |> httr::content() |> (function(x) data.frame(version = purrr::map_chr(x, "name")))() ``` ``` ## version ## 1 v2021.09.1+372 ## 2 v2021.09.0+351 ## 3 v1.4.1717 ## 4 v1.4.1106 ## 5 v1.4.1103 ``` --- # RStudio Serverのリリース日 Gitのタグの情報をGitHub APIで取得 |> タグの打たれているコミットの日付を取得 ```r "https://api.github.com/repos/rstudio/rstudio/commits/df86b69ebdf62f1a9ed51af59c168572677541f1" |> httr::GET(httr::add_headers(accept = "application/vnd.github.v3+json")) |> httr::content() |> purrr::pluck("commit", "committer", "date") |> as.Date() ``` ``` ## [1] "2021-05-24" ``` --- # これらの処理をGitHubActionsで定期実行させ自動PR作成! ```yaml jobs: createPullRequest: container: image: rocker/tidyverse:latest steps: - uses: actions/checkout@v2 - run: install2.r --error --skipinstalled -r https://r-lib.github.io/p/pak/dev/ -n -1 pak - run: ./make-stacks.R - name: Create Pull Request uses: peter-evans/create-pull-request@v3 with: commit-message: Automatic update of container definition files branch: auto-detected-updates delete-branch: true title: 'Automatic update of container definition files' body: | - Auto-generated by [create-pull-request][1] [1]: https://github.com/peter-evans/create-pull-request ``` --- # [マージされました](https://github.com/rocker-org/rocker-versioned2/pull/164) .center[![PullRequest](./image/pr164.png)] --- # まとめ - 使ったことのないパッケージのことを色々知ることができた。作者の皆様に感謝。 - GitHubActionsすごい。 - 自動化楽しい。