Netlify にホームページのプレビューサイトを設置

昨年 Hugo と GitHub Actions で static サイトの生成と公開を自動化しました

blog.kondoumh.com

自動化で楽にはなりましたが、publish が全ファイル転送なのでけっこう時間がかかります。ブログカードの見え方などはローカルサーバーでは表示されず、実際にサイトに配置しないと確認できないというのもあって更新が億劫になっていました。

そこで、プレビュー用のサイトを Netlify に立て、GitHub リポジトリで preview ブランチを作り、このブランチが更新されたら Netlify に publish するようにしてみました。

github.com

Netlify も Hugo に対応しており build / publish が爆速なので、気軽に push してプレビューできます。

本番用のサーバーに publish するのは master ブランチへのマージ時のみにしたいので、GitHub Actions のトリガーを master への push のみにしました。

on:
  push:
    paths:
      - content/**
      - layout/**
      - config.toml
    branches:
      - master

プレビューサイトで確認が終わったらプルリクを作って master に squash merge すれば本番用サーバに publish されます。

これで運用が楽になりました。Netlify に課金してないのでプレビューサイトが public なのはご愛敬ですが。

VS Code Extension 公開時の Access Token 取得 2020

以前 Marketplace に放流した ChangeLog extension

blog.kondoumh.com

久々にちょっと修正したので、Marketplace に publish しようとしました。 前回 publish した時の Access Token はとっくに expired なので、再取得。

しかし、vsce login で Token を渡しても 401 エラーになってしまいます。

ちゃんと公式ドキュメントを読みました。

code.visualstudio.com

  • Token Name: 任意
  • Organization: All accessible organization
  • Expireation: One year
  • Scope: Custom defined
    • Marketplace: Aquire, Manage

Token 名がなんでもよくなって、Organization が All accessible organization に変わったみたいです。 前回は、Scope として All Scopes を選んでましたが、今回は Marketplace の Scope を指定しました。

これで無事 publish できました。

marketplace.visualstudio.com

ちなみに修正内容ですが、ファイル名 ChangeLog だけでなく拡張子が .ChangeLog の場合も発動するようにしただけです。

とはいえ普段は Emacs で書いていますが。

blog.kondoumh.com

GitHub Actions でビルド番号が使えるようになってる

GitHub Actions でもビルド番号が利用できるようになりました。

help.github.com

かなり最近入った機能なので、現時点では日本語ドキュメントでも説明が英語のままです。

GITHUB_RUN_IDGITHUB_RUN_NUMBER それぞれ 実行ID と実行番号というところでしょうか。他のビルトイン環境変数と同様、GITHUB_ という予約されたプレフィクスになっています。

環境変数 説明
GITHUB_RUN_ID リポジトリ内の実行単位で採番される ID
GITHUB_RUN_NUMBER リポジトリ内のワークフロー毎にユニークに採番される。1からスタートし実行される度にインクリメントされる

どちらも、ワークフローの Re-Run で変わることはありません。GITHUB_RUN_ID はリポジトリ内でユニークな数字であり、 一般にビルド番号としての利用が想定されるのは、GITHUB_RUN_NUMBER だと思います。ワークフロー単位なので、ワークフロー内の異なるジョブでも、同じ ID, 番号が取得されます。今のところ、番号をリセットする API などはない模様です*1

使い方ですが、ワークフロー内に記述するときは、${{ github.run_number }} で取得できます。ビルド成果物にビルド番号を含めて保存する例です。

steps:
- uses: actions/upload-artifact@v1
  with:
    name: my-artifact-${{ github.run_number }}
    path: path/to/my-artifact

run や シェルでは GITHUB_RUN_NUMBER という環境変数として取得できます。

echo ${GITHUB_RUN_NUMBER}

GitHub Action かなり機能が充実してきましたが、手動起動なども実装されて欲しいところです *2

*1:番号をリセットしたい時は、ワークフローの YAML ファイルをリネームすればよいかもしれません

*2:'repository_dispatch' トリガーを追加すれば curl から叩いたりできるのですが、branch に対してワークフローを指定できないなど微妙な仕様です。

Twitter タイムラインの自動リフレッシュを Electron アプリで実現

デスクトップでは Twitter を PWA で使っていますが、タイムラインが自動更新されないのがちょっと・・と思っていました。

かなり前に Electron で作ってた Twitter client

blog.kondoumh.com

このアプリに自動リフレッシュを組み込んでみようと思いました。定期的にホームボタンの click イベントを発火させるのが簡単そうです。

f:id:kondoumh:20200308134720p:plain

Chrome の DevTools で調べるとこのボタンは SVG 画像を a タグで囲んだもので、"data-testid" という属性を持っていました。DevTools の console では以下のようなコードで発火させられました。

document.querySelector("a[data-testid]").click();

Electron WebView では executeJavaScript メソッドで上記のコードを実行できます。

function clickHome() {
  webview.executeJavaScript('document.querySelector("a[data-testid]").click();');
}

あとは、setInterval で適当な間隔でこのfunction を呼び出せば、懐かしい感じにタイムラインが自動で流れていくようになりました。

追記) タイムライン以外の検索や通知の画面でリフレッシュされるのがうざいので、さらに調べたところ、メインカラムのタイトルが 「ホームタイムライン」になっているのがタイムライン選択状態のようです。そこで以下のようなコードを executeJavaScript に渡すといい感じにタイムラインの時だけリフレッシュしてくれるようになりました。

if (document.querySelector("h1[aria-level]").innerHTML === "ホームタイムライン") {
  document.querySelector("a[data-testid]").click();
}

Twitter 側のデザイン変更にとても弱そうな方式ではありますが。

github.com

Scrapbox プロジェクトのグラフ構造を Visualize してみる

Scrapbox で他のページへのリンクを作成した途端、ページの下にアイキャッチ付きのリンクがリアルタイムでできていくので書いててテンション上がりますよね。

Scrapbox API を使うと各ページの情報とページ間のリンクを JSON で取得できます。

scrapbox.io

Go の場合 struct を次のように定義し、取得したページデータを json.Unmarshal すると当該ページからの 1hop link のリストとページを作成した User (Author) が取れます*1

type Page struct {
    ID            string  `json:"id"`
    Title         string  `json:"title"`
    Author        User    `json:"user"`
    Collaborators []User  `json:"collaborators"`
    Related struct {
        Links []struct {
            ID    string `json:"id"`
            Title string `json:"title"`
        } `json:"links1hop"`
    } `json:"relatedPages"`
}

type User struct {
    ID           string `json:"id"`
    Name         string `json:"name"`
    DisplayName  string `json:"displayName"`
}

ページ間のリンクはサロゲートキー的な ID のペアになっているので、比較的簡単にグラフ構造を生成できます。

自分の Scrapbox プロジェクトのデータを抽出しました。

scrapbox.io

そしてGraphViz で可視化してみました。

f:id:kondoumh:20200305000013p:plain

見づらいですが、Gadget 関連とDev 関連のクラスター的なものが形成されているので納得感あります。

複数のユーザが作っているプロジェクトではユーザとページの関連も見れます。

Scrapbox の help プロジェクト scrapbox.io

ユーザをシアンで塗り潰したノードで可視化してみました(ユーザ名は anonymize してます)。

f:id:kondoumh:20200306204303p:plain

会社のプライベートなプロジェクトはページ数が5000近くになっているため、ページビューなどでフィルターかけないとグラフが大規模になり閲覧自体が困難です。インタラクティブにフィルタリングする可視化システムを作りたくなります。

*1:User は単独のオブジェクトとして扱いたいのでネストさせてません

Linux Desktop でも VS Code 使う

これまで Linux はもっぱら SSH で使ってたのですが、ここにきて Desktop も使うようになってきました。Kubernetes にデプロイしたアプリの動作確認を VM の localhost でするためです。

当然コードを書くのは VS Code の生産性が圧倒的に高いのでインストールしました。

会社ではプロキシサーバ配下で利用するのですが、拡張をインストールしようとすると settings.json で proxy 設定していても market place から取得できません。ぐぐったところ、起動用ファイルの設定で起動時オプション --proxy-server を追加すればよいようです。

GNOME では VS Code は「お気に入り」に自動追加され /usr/share/applications/code.desktop が起動用のファイルのようです。このファイルを以下のように編集したところ、無事拡張をインストールできました。

[Desktop Entry]
Name=Visual Studio Code
Comment=Code Editing. Redefined.
GenericName=Text Editor
Exec=/usr/share/code/code --no-sandbox --unity-launch --proxy-server=proxy.server.host:8080 %F
Icon=com.visualstudio.code
Type=Application

フォントは DejaVu Sans Mono を入れるとわりと見やすくなりました。

f:id:kondoumh:20200217222527p:plain

コードを書いている分には Windows や macOS と同等に動作している印象です。

VirtualBox 6.1 で Intel CPU の Nested Virtualization が解除された

Nested Virtualization は仮想マシンからホストマシンの CPU の仮想化機能を利用できる機能です。

VirtualBox では AMD CPU の Nested Virtualization が 6.0.6 でリリースされました。そして 6.1.0 で Intel CPU でも Nested Virtualization が利用できるようになりました。

Changelog – Oracle VM VirtualBox

リリースノートには、

starting with 5th generation Core i, codename Broadwell

とあり、僕の MacBook Pro Early 2015 は ギリギリ第5世代ですので使えるはずです。

現バージョンでは仮想マシン名を指定して個別に有効化する必要があります。

2.34. Nested Virtualization

'Ubuntu 18' という仮想マシンに対して Nested Virtualization を有効化するには以下を実行します。

$ VBoxManage modifyvm 'Ubuntu 18' --nested-hw-virt on

これで、有効化されました。

f:id:kondoumh:20200211235159p:plain

仮想マシンを起動して CPU がハードウェア仮想化をサポートしているか確認してみます。

KVM/Installation - Community Help Wiki

$ egrep -c '(vmx|svm)' /proc/cpuinfo
1

この数値が1以上ならサポートされているので OK です。KVM2 をインストールしてみます。

$ sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils

インストールが終わって KVM acceleration が利用可能になったかチェック。

$ kvm-ok 
INFO: /dev/kvm exists
KVM acceleration can be used

大丈夫みたいです。

/dev/kvm へのアクセス権をログインユーザーに付与します。

$ sudo chown <username> /dev/kvm

libvirt でエラーがないことを確認。

$ virt-host-validate

virt-host-validate
  QEMU: Checking for hardware virtualization                                 : PASS
    :
  QEMU: Checking for cgroup 'blkio' controller mount-point                   : PASS
  QEMU: Checking for device assignment IOMMU support                         : WARN (No ACPI DMAR table found, IOMMU either disabled in BIOS or not supported by this hardware platform)
   LXC: Checking for Linux >= 2.6.26                                         : PASS
    :
   LXC: Checking if device /sys/fs/fuse/connections exists                   : PASS

OK でした。

/etc/libvirt/libvirtd.conf に以下の設定を追加

unix_sock_group = "libvirtd"
unix_sock_ro_perms = "0770"
unix_sock_rw_perms = "0770"

いったんリブートしておきます。

KVM を使って Ubuntu の仮想マシンに CentOS 7 仮想マシンをインストールしてみます。

$ curl -LO http://ftp.riken.jp/Linux/centos/7.7.1908/isos/x86_64/CentOS-7-x86_64-DVD-1908.iso

$ sudo kvm -hda centos7.img -cdrom CentOS-7-x86_64-DVD-1908.iso -boot once=d -m 512

インストーラが起動。

f:id:kondoumh:20200212220124p:plain

インストーラの GUI が起動しました。

f:id:kondoumh:20200212221907p:plain

ソフトウェアインストール後の initramfs の初期化などにすごく時間がかかっていましたが、なんとかコンソールが起動しました。

f:id:kondoumh:20200213082002p:plain

ホストマシンが実機の場合は当たり前の光景ですが、これが仮想マシン内で実行されているのは中々凄いですね。

QEMU で仮想マシンが動くなら、Minikube で KVM も使えそうです。

以前 Minikube を macOS の HyperKit と Windows の Hyper-V で使ってみました。

blog.kondoumh.com

Linux 版の Minikube をインストールします。

Linux | minikube

$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_1.7.2-0_amd64.deb \
 && sudo dpkg -i minikube_1.7.2-0_amd64.deb

vm-driver に kvm2 を指定して minikube を実行

f:id:kondoumh:20200212004452p:plain

CPU が振り切ったまま、マウスカーソルすら表示されなくなってしまいました。

ということで、マシンパワーが足りないのか VirtualBox 側の最適化が足りないのか、僕の環境では実用的な速度では動きませんでした。もう少し熟成を待つ方がよさそうです。