sharoa
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # 【第6週】パRails輪読会🚂 \(2023\-09\-25\~ 2023\-09\-29\) ###### tags: `パRails🚂` - [開催概要](https://hackmd.io/4A_8ahJtQNi5hz713N5Y7w?view) - [パRails輪読会 ノートまとめ](https://hackmd.io/jsgA8Pf_RVioOgSL_VOR4g) - サンプルコード・正誤表:[サポートページ:パーフェクトRuby on Rails【増補改訂版】:|技術評論社](https://gihyo.jp/book/2020/978-4-297-11462-6/support) - **サンプルコードをダウンロードしただけでは、すぐに`rails s`できない可能性が高い**です。 以下のページに環境構築の手順をまとめたので、ドライバーをやってくださるという方は、こちらに沿って環境構築をお願いします🙏 ⏩ [環境構築の手順 2022年版](https://hackmd.io/y7qb2BRMT2Wd4tAtKYObcQ) ⏩ [環境構築の手順 2023年版](https://hackmd.io/3_lnn8_QRD6wEjwFbWcBzQ) 💁‍♀️ [更新の手順 2章編](https://hackmd.io/pZAmF2EjSmyQ38lUtJ_CqA) ## 目次 [TOC] ------ ## 2023\-09\-25(月) ### ファシリ @shodan ### ドライバー @hiromisugie ### 読んだところ 3−1−8 126p 「Rails 6.0で追加された並列テスト」から、 3−2−2 133p 終わりまで。 PR: https://github.com/hiromisugie/Perfect_Ruby_on_Rails_Ch3/pull/5 ### 次回 3-2-3 134p 「Rackミドルウェアとは」から。🚂 ### 学んだこと・感想 - @sharoa - テストを高速に実行するための並列実行がおこなるようになった。(Rails6.0から。)デフォルトでは並列化していてテストを実行するようになっている。意識せずとも並列化の恩恵を受けることができる。 - 目の前で実行結果の違いを見れて良かったです。 - Rackについて。Webアプリケーションのサーバとフレームワーク間のインターフェイスを共通化した仕様であり実装となっているライブラリのこと。 - 非常にシンプルなインターフェイスを定義している、Rackに対応するアプリケーションやフレームワークはこの規約に則ったインターフェイスを定義する必要がある。 - 簡単なRackアプリケーションとして、こちらも実行結果が確認できて良かった。 - @shodan - Rails6.0からデフォルトで並列テストが実行されるようになった。 - `test/test_helper.rb`の設定で並列度を変更したりできる。テストのデバッグで使ったり?することもあるようなので頭に入れておく。 - RackはフレームワークとWebアプリケーションサーバを仲介してくれる存在。 - `git commit --amend`はタイポのお助けとしてしか見れてなかったので、覚えておきます&gitもっとちゃんと理解します……。 - 久しぶりだったので緊張しました🫠また改めてよろしくおねがいします〜。 - @sadanora - Rails6.0からデフォルトで並列テストになった。 - 並列テストは、複数のテストをプロセスやスレッドごとに並列実行できるので高速。(デフォルトはプロセス) - 並列テストを実行する際は、DBも並列度にあわせて複数用意される。 - Rack - WebアプリケーションサーバーとWebアプリケーションフレームワークの間のインターフェイスを共通化した仕様であり実装 - これがなかったときは、アプリケーションサーバーとWebアプリケーションフレームワークが密結合していて大変だったらしい - RailsならWebアプリケーションサーバーは〇〇、みたいにそれぞれの選択に融通がききにくかったのを、Rackが間を取り持つことで柔軟に選べるようになった、みたいなこと...? - @moegi29 - Rails6から並列テストがデフォルトになった。テストが落ちるときとか挙動を確認したいときに直列実行したりする。実際に`parallelize(workers: 1)`の値を変えてみたりしてよくわかった。 - Rackが登場してWebアプリサーバとフレームワークの間のインターフェースを共通化したライブラリの組み合わせを柔軟に選択できるようになった。Unicorn,Merb,WEBrickとかよく知らなかったので調べてみたいです~ - `git commit --amend`でコミットメッセージの修正もできる! - @motohiro-mm - テストを並列で行うとテストが高速で実行される - `test_helper.rb`の`palallelize(workers: )`のところで設定できる - `:number_of_processors`はCPUの数で並列実行する指定 - `1`にすると直列でテストを実行できる - RackはWebアプリケーションサーバとWebアプリケーションフレームワーク間のインターフェイスを共通化した仕様であり実装となっているライブラリ - WEbアプリケーションサーバ:UnicornやPumaなど - Rackアプリケーションは自分で定義できる - Rackがまだ理解が微妙なので後でもう一度読みたいと思います - @hiromisugie - 並列テストについて。ふむふむという感じだったけど、PCのプロセッサ数に応じた並列テストができるということや、並列テストで何かうまくいかない場合に1列にしてみる、といった方法があるらしい?並列の度合いを変えて実際に結果の秒数が変わるのを確認できて楽しかった。 - 唐突に`Rack`が出てきてよくわからなかった…。もう少し調べてみないとなと思った。 - `git commit --amend`で1つ前のコミットをいじれる。例えば1つ前のコミットに別の作業を含めたい場合は、何かしら変更を加えたのちに改めて`git add .`して、`git commit --amend`でvimが開くのでそのまま保存すると、最後のaddが1つ前のコミットに含まれる。あとはコミットメッセージをタイポしてしまった時とかに修正もできる、らしい。gitスキルをもっと付けなければ…。 ------ ## 2023\-09\-26(火) ### ファシリ @sharoa ### ドライバー @hiromisugie ### 読んだところ 3-2-3 134p 「Rackミドルウェアとは」から 3-2-5 「RailsとRackの関係」まで。 PR: ### 次回 3-2-6 139p 「自作のRackミドルウェアをRailsに追加していよう。」から。🚂 ### 学んだこと・感想 - @sharoa - 昨日からやってるRackが曲者ですw  - Rackにはアプリケーションサーバとアプリケーションの間に処理を追加するミドルウェアという機構が備わっている。 - 自分でもRackミドルウェアが作れる - 玉ねぎの図も難しい。 - ただ、最後の`rackup`だけでrailsが立ち上がるのには感動した。 - @sadanora - ミドルウェア - Appサーバーとアプリケーションの間に処理を追加する機構。Rackにもこれが備わっていてRackミドルウェアという。 - Rackミドルウェア - Rackミドルウェアがinitializeで受け取る引数は、後続のアプリケーションのオブジェクト。自分のcallオブジェクトが呼ばれるとinitializeで受け取ったオブジェクトのcallメソッドを呼ぶ、みたいな感じで処理が続いていく。 - Railsがrackupで起動するのに感動 - RailsもRackを利用してAppサーバーとアプリの間に色々やりたい処理を追加(たまねぎの層を追加)してるのかな???って思いました。 - ActiveRecordとか、見覚えのあるクラスの名前がいろいろあった - Rack、むずかしくない??? - @moegi29 - ミドルウェアはアプリサーバーとアプリの間に処理を追加する機能 - useメソッドでミドルウェアオブジェクトを指定する - ミドルウェアはいろいろあって、便利なミドルウェアを集めた別リポジトリもある - 唐突に出てきた玉ねぎの図、いまいちわからない。 - @hiromisugie - Rack、引き続き難しい、、、 - タマネギの図はさっぱりわからないけど、ミドルウェア単位で「何らかの機能追加」みたいなことを足していけるのかなと思ったりした。明日、`Ruby`を`RUBY`に変換するだけのミドルウェアを作るというのがあるようなので、そこでも理解を深めたい。 - Rackミドルウェアについてはよくわからなかったが、`rackup`コマンドでRailsを立ち上げることができたのは楽しかったし、RailsがRackアプリケーションであるということを体感出来て良かったです。 - @motohiro-mm - Rackミドルウェア:アプリケーションサーバとアプリケーションの間に処理を追加する機構 - サーバからリクエストを受けるとミドルウェアを経由してアプリケーションに到達し、アプリケーションからレスポンスデータを受け取るとさらにミドルウェアを経由してサーバに到達する(合ってるか不安) - Railsでもいつものrails serverではなくrackupで9292ポートにつなげることができる ------ ## 2023\-09\-27(水) ### ファシリ @motohiro-mm ### ドライバー @hiromisugie ### 読んだところ 3-2-6 139p 「自作のRackミドルウェアをRailsに追加していよう。」から 3-3-2 「テーブルの定義を反映させる」まで。 PR: ### 次回 3-3-3 144p 「スキーマファイルの取り扱い」から。🚂 ### 学んだこと・感想 - @sharoa - 自分のプラクティスがRailsに入ったので、出てくる単語が少しずつわかってきて、うれしいです。(感想✨) - 自作のRackミドルウェアをRailsに追加できる。`config.middleware.use`を使う。 - 目の前で変化が確認できたのがよかった。 - 他にも、`config.middleware.insert_after` `~insert_before` `~delete` がある。 - railsコマンドは覚える(前にも言ったかも。) - マイグレーションファイル内で利用できる専用のメソッド、up,down,changeの3つがある。むずい。 - @sadanora - Rackがふわっとおわった。 - `config/environments`内の環境ごとの設定ファイルや、`config/application.rb`から呼び出すことで自分で書いたミドルウェアを使える - `config.middleware.use`などconfigオブジェクトを通じて追加したり削除したり、呼び出す順番を指定したりできる - migrateの状態が良くわからなくなって怖かったですが、migrationファイルは、`change`しか使っているところをみたことがなかったので`up`や`down`を試せたのはよかったです。 - @moegi29 - Rackミドルウェアを追加するとき常に使用したい場合はconfig/application.rb内、develop環境でのみ使う場合はconfig/environments/development.rbに追加する。 - 通常のuseメソッド、既存ミドルウェアの最後に追加される。順序変えたりもできる。 - DB操作は極力しないようにしていたのでいろんな操作を見れて勉強になりました。 - @motohiro-mm - 自作のミドルウェアをRailsに追加するには、`/lib`にミドルウェアディレクトリ、その中にファイルを作成して、それを`/config/envinronments`のファイルに`require`すると使える。 - Rackミドルウェアのメソッドには4つある - `Rails_ENV=production`をつけてdb:createするとproduction環境のデータベースが作れる - @hiromisugie - Rackミドルウェアで`Ruby`の表示を`RUBY`に変えるというのを試して面白かった。 - 自作のミドルウェアを既存のミドルウェア群のどの順番に差し込むかと言うのを設定できる。 - 例えば`insert_after 引数1, 引数2`で、引数1のミドルウエアの直後に引数2のミドルウェアを差し込む、など。 - `db:xxx`のタスクは半分くらいは使ったこともないだけど、ふむふむという感じで確認しました。 - `db:migrate`で、マイグレーションファイルに記載されているテーブル定義を反映させる。 - マイグレーションファイル内の設定で`change`メソッド以外に`up`や`down`メソッドがあるが、まだちゃんと理解できていない…。基本的には`change`を使い、`db:migrate`で反映、`db:rollback`で戻す、というのをまず使いこなしたいと思った。 ----- ## 2023\-09\-28(木) ### ファシリ @motohiro-mm ### ドライバー @hiromisugie ### 読んだところ 3-3-3 144p 「スキーマファイルの取り扱い」から 3-3-6 「複数DBを扱う」まで。 PR: ### 次回 3-4 152p 「秘密情報を管理する」から。🚂 ### 学んだこと・感想 - @sharoa - RailsではDBの構成を`db/schema.rb`として残している。 - `db:migrate`などを実行したときに作成されるものだけど、このファイルに書き出される内容はマイグレーションファイルではなく、DBに定義されている内容を反映したもの。 - `schema.rb`を読み込むことで、マイグレーションを実行することなく現在のDB環境を作成することもできる。 - `db:seed`の使い方。 - `db/seeds.rb`を実行してデータを読み込む。`ActiveRecord`のコードを直接書くことができるから、簡単にデータの投入を行うことができる。 - 複数DBを扱うところは再度よみます。 - @moegi29 - `bin/rails runner "p Blog.count"`のように`runner`を使えばわざわざコンソールを開かなくて良いのが便利。 - 特定のモデルを特定のDBへ接続させたい場合は`establish_connection`を利用する、rails dbタスクは`replica:true`で制御できる。 - 複数DBへ接続する場合のいろいろを学んだ ちゃんと整理して理解したい。 - @shodan - `db:setup`を実行した時に参照されるのはマイグレーションファイルではなくスキーマファイルと、`db/seeds.rb`(あらかじめ用意しておいた、投入したいデータ群)。 - `db:prepare`を使うと、DBがあればマイグレーション、なければ`db:setup`を行う。 - 複数DBを使ったり、読み込み・書き込み専用のDBを分けて作ったりできる。その場合はモデルの方にも、処理の際にどのDBに所属・問い合わせるをするのかを明示したりするような設定が必要。 - 感想:まさにパーフェクトRuby on Railsって感じですね😇 - `connect_to`ではなく`connects_to`が正そう? https://api.rubyonrails.org/classes/ActiveRecord/ConnectionHandling.html#method-i-connects_to - @hiromisugie - `schema.rb`にはマイグレーションファイルではなくDBに定義されている内容が反映されているということを初めて知った。マイグレーションファイルの内容だと思っていた。。。 - `rails runner`は任意のスクリプトを実行できる。`rails c`せずにDBに入ってるかどうかを確認したりできるので便利。 - Rails6.0から複数DBに対応している。それまでは専用のgemを使う必要があったらしい。 - 書き込み用DB、読み込み用DBに分けるというのがよくある構成。そういえばそういうのは聞いたことがある気がするが、実際の仕組みをおぼろげながら見ることができて良かった。 - 感想:今読んでいる章、まだ3章目でしかも「押さえておきたいRailsの基本機能」というタイトルなのに今まで見たことも使ったこともない機能がたくさん出てきて、Railsの奥深さを感じています。。。😇 - @motohiro-mm - `bin/rails runner "〜"`で任意のスクリプトを実行できる - スキーマファイルはテーブル定義を反映したもの - シードファイルはデータを書いておくと`bin/rails db:seed`でデータを読み込んでくれる - 複数のDBを扱うことができる - DBの応対速度を上げるため - 例えば、書き込み専用と読み取り専用にする ----- ## 2023\-09\-29(金) ### ファシリ @motohiro-mm ### ドライバー @hiromisugie ### 読んだところ 3-4 152p 「秘密情報を管理する」から 3-4-6 「Rails 6.0(credentialsの拡張)まで。 PR: ### 次回 3-5 159p 「HTTPとRailsアプリケーション」から。🚂 ### 学んだこと・感想 - @sharoa - 今日は全体的に「ふむふむ」の感じでした。というかなんだか難しかった。 - Railsにおける秘密情報の取扱の歴史はこんな感じだったんだな~と頭の片隅においておきます。 - @shodan - 現場Railsでこの辺やったはずなんですが、正直ふわ〜っと進めていたので全然まっさらな状態で読むことになりました😅(しかも現場RailsはRails5) - `config/master.key`がないとそもそも秘密情報の参照・編集はできない。`rails new`した段階で`master.key`は発行されるが、第三者がこれを使って秘密情報にアクセスしてはいけないので、自動的に`gitignore`に追加してくれる。 - @sadanora - credentials - 環境変数ごとに値を切り替えない - credentilasの登場人物 - credentials.yml.enc - 暗号化した設定ファイル - master.key - RAILS_MASTER_KEY - master.keyの値を環境変数経由で受け渡す場合の環境変数名 - credentailsの扱いがよくわからなくて、自作サービスではdotenv-railsというgemに頼りました。 - @moegi29 - Rails4.0では秘密情報の文字列を安全に管理する標準的な方法がなかった~Rails6.0でcredentialsの機能が拡張されるまでの変遷を知れた - masterkeyはrails newしたひとのローカル環境でしか見れない、EDITOR="vi"を前につけると`credentials:show`をvimで編集できるようになる - DHHが43歳ということに衝撃をうけました - @motohiro-mm - Railsの秘密情報の管理の歴史がなんとなくわかりました - credentials:master.keyを使って情報を暗号化・復号化している、master.keyは情報と別に保存されていて共有されない - 今現場Railsでちょうどcredentialsの話のところが出たので、どちらも見ながら復習したいと思います。 - @hiromisugie - 秘密情報を管理する方法はRailsの歴史とともに移り変わっているとのことで、Rails4からの変遷を見ることができた。 - ほぼわからず、「ふむふむ」という感じでした…。まず「秘密情報」がピンときていないが、クラウド環境へ接続するためのトークンやアプリケーションで固定の値として利用している外部に見せてはいけない秘密の文字列のこと。(ユーザーのパスワードとかかなと思ったけど、ちょっと違うっぽい) - vimの使い方を完全に忘れている。`i`で入力モード、`esc`でそれを解除し、`:wq`で保存して閉じる。これくらいは覚えておかないと…。 - ここから宣伝です💬 10/27・28開催のKaigi on Rails 2023 のお手伝いしています、チケットの残りが少なくなってきたので迷われている方は是非!先日タイムテーブルも公開されました。フィヨブー卒業生が6人ほど登壇するようです。おすすめはフィヨブー卒業生3人組によるライブコーディングです!(オンライン鑑賞は無料、現地参加は割と良いお値段です😇) https://kaigionrails.org/2023/talks/tebiki/ - @ayu-0505   - Railsチュートリアル上でRAILS_MASTER_KEYをよく理解せぬままチュートリアルに沿って使っていたのですが、理由がわかってよかったです。 -----

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully