Upgrade to Pro — share decks privately, control downloads, hide ads and more …

syndicationd LT

ymgyt
February 29, 2024

syndicationd LT

ymgyt

February 29, 2024
Tweet

More Decks by ymgyt

Other Decks in Programming

Transcript

  1. TUI の Feed Viewer を自宅の Raspbery Pi で 公開するまで Nix

    で Rust の開発環境から CI,Deploy まで管理する 山口 裕太 · 2024‑03‑05
  2. 話すこと 作成したツールのライフサイクルについて • TUI の Feed Viewer を作った • Nix

    で開発環境,CI,Deploy を管理した • Release では cargo‑release と cargo‑dist を利 用した • Trace,Metrics,Logs は OpenTelemetry を利用し た
  3. ratatui let (header, widths, rows) = self.entry_rows(cx); let entries =

    Table::new(rows, widths) .header(header.style(cx.theme.entries.header)) .column_spacing(2) .style(cx.theme.entries.background) .highlight_symbol(ui::TABLE_HIGHLIGHT_SYMBOL) .highlight_style(cx.theme.entries.selected_entry) .highlight_spacing(HighlightSpacing::WhenSelected); Table や List 等の基本的な widget が用意されている
  4. crossterm async fn event_loop<S>(&mut self, input: &mut S) where S:

    Stream<Item = io::Result<CrosstermEvent>> + Unpin, { loop { tokio::select! { biased; Some(event) = input.next() => { } _ = self.background_jobs => { } }; } 複数の入力も async で書ける
  5. crossterm fn handle_terminal_event(&mut self, event: std::io::Result<CrosstermEvent>) { match event.unwrap() {

    CrosstermEvent::Resize(columns, rows) => { } CrosstermEvent::Key(key) => match key.code { KeyCode::Tab => { }, KeyCode::Char('j') => { }, } } } Key 入力の処理も簡単
  6. Nix による開発 環境の管理 そもそも Nix とは > A build tool,

    package manager, and programming language https://zero‑to‑nix.com/concepts/nix
  7. Nix による開発 環境の管理 { inputs.nixpkgs.url = "github:NixOS/nixpkgs/ release-23.11"; outputs =

    { self, nixpkgs, ... }: let dev_packages = with pkgs; [ graphql-client git-cliff cargo-release cargo-dist oranda ]; in { devShells.default = craneLib.devShell { packages = dev_packages; }; }); } project root の flake.nix で開発時の依存を宣言
  8. CI でも nix develop name: CI jobs: tests: runs-on: ubuntu-latest

    steps: - uses: actions/checkout@v4 - run: nix develop .#ci --accept- flake-config --command just check • install action が不要 • 開発環境と同一 version
  9. Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI

    を Nix で管理できる • Cache を Nix で管理できる
  10. Nix で管理する と何がうれし いのか name: CI jobs: tests: runs-on: ubuntu-latest

    steps: - uses: actions/checkout@v4 - uses: cachix/install-nix-action@v25 with: github_access_token: $ {{ secrets.GITHUB_TOKEN }} - uses: cachix/cachix-action@v14 with: name: syndicationd authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: nix develop .#ci --accept-flake-config -- command just check cache を設定した最終的な CI の workflow local と CI で同じ cache の仕組みを利用できる
  11. Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI

    を Nix で管理できる • Cache を Nix で管理できる • Install を Nix で管理できる
  12. Nix で管理する と何がうれし いのか nix run で一時的に実行したり nix profile で

    install もできる Mac と Linux で同じ package 管理ができる
  13. Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI

    を Nix で管理できる • Cache を Nix で管理できる • Install を Nix で管理できる • Deploy を Nix で管理できる
  14. Nix で systemd service を宣言 { config, pkgs, syndicationd, ...

    }: let syndPkg = syndicationd.packages."${pkgs.system}".synd- api; in { config = { systemd.services.synd-api = { description = "Syndicationd api"; wantedBy = [ "multi-user.target" ]; environment = { SYND_LOG = "INFO"; }; serviceConfig = { ExecStart = "${syndPkg}/bin/synd-api" }; }; }; } https://github.com/ymgyt/mynix/blob/main/homeserver/ modules/syndicationd/default.nix
  15. Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI

    を Nix で管理できる • Cache を Nix で管理できる • Install を Nix で管理できる • Deploy を Nix で管理できる
  16. cargo でも公開 したい cargo publish するには以下が必要 • Cargo.toml の package.version

    の bump • Workspace 内に依存 package がある場合は合 わせて bump • CHANGELOG の生成 • git の tagging これを workspace の member crate ごとに実施 する必要がある
  17. cargo でも公開 したい cargo release --package foo patch を実行する と

    • foo package の Cargo.toml package.version を bump(v0.1.2 ‑> v0.1.3) • foo に依存している workspace 内の package の dependencies.foo.version を bump • 設定に定義した replace 処理を実施 (CHANGELOG の[unreleased] ‑> [v0.1.3]) • git の commit, tagging, push • cargo publish
  18. homebrew で も公開したい 専用の repository(homebrew-syndicationd)に以下 のような記述が必要 class Synd < Formula

    desc "terminal feed viewer" version "0.1.6" on_macos do on_arm do url "https://github.com/ymgyt/syndicationd/releases/download/synd- term-v0.1.6/synd-term-aarch64-apple-darwin.tar.gz" sha256 "c02751ba979720a2a24be09e82d6647a6283f28290bbe9c2fb79c03cb6dbb979" end on_intel do url "https://github.com/ymgyt/syndicationd/releases/download/synd- term-v0.1.6/synd-term-x86_64-apple-darwin.tar.gz" sha256 "3be81f95c68bde17ead0972df258c1094b28fd3d2a96c1a05261dba2326f31d8" end end
  19. cargo‑dist が やってくれる cargo dist init を実行して質問に答えると • Cargo.toml の[workspace.metadata.dist]に設

    定が追加 • .github/workflows/release.yml を生成 この状態で cargo‑release で git tag を push する と
  20. cargo‑dist が やってくれる cargo‑dist が以下をやってくれる(設定次第) • 各種 platform(aarch64,x86 の darwin,windows,

    linux gnu,musl)向けの binary 生成 • shell,powershell の install script 作成 • homebrew 用 repository の更新(push 権限を渡 す必要あり)
  21. cargo‑dist が やってくれる cargo dist plan を実行すると CI で実行される 内容を確認できる

    workflow yaml にベタ書きされているのではな く、cargo dist plan の出力を参照するように なっている
  22. cargo‑dist が やってくれる cargo‑release と一緒に使うことが想定されてお り cargo publish と git

    の tag push までが cargo‑ release それ以降の配布処理が cargo‑dist という役割分 担がよかったので使ってみた