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

syndicationd LT

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for ymgyt ymgyt
February 29, 2024

syndicationd LT

Avatar for ymgyt

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 という役割分 担がよかったので使ってみた