tech.guitarrapc.cóm

Technical updates

GitHub Actions で .NET Framework プロジェクトをビルドする

Visual Studio 拡張 のプロジェクトは、今でも .NET Framework です。 .NET Framework ということは、基本的に Windows でのビルドになります。

今回、AppVeyor でやっていたビルドを GitHub Actions に移行したのでメモ。

最終的に、次のように .NET Framework のビルドが GitHub Actions で完結します。

.NET Framework のビルドがGitHub Actions で成功した図

目次

TL;DR

  • .NET Framework のアプリも GitHub ホストランナーで Windows OS を選べば問題ない
  • Visual Studio 拡張のような変なビルドでも問題ないので安心してビルドできる
  • GitHub Actions は AppVeyor にトドメを刺しそう (good bye

リポジトリ

VS拡張で提供している OpenUserSecrets をVS2019 対応するついでに AppVeyor から GitHub Actions に移植します。

github.com

事前知識

GitHub Actions での書き方など一通りの注意は公式Docみるかまとめたので参照してください。

tech.guitarrapc.com

CIサービスの変化

  • Before: AppVeyor
  • After: GitHub Actions

前提として、AppVeyor / GitHub Actions のいずれにおいても Windows 依存のビルドは Docker Image でのビルド実行ではなくホストマシンでの実行となります。

それぞれの定義を見ていきます。

AppVeyor の定義

OpenUserSecrets/appveyor.yml at 362cc778821bf9724176ed9439c8c4f6c84e5e8a · guitarrapc/OpenUserSecrets · GitHub

image: Visual Studio 2017
version: '1.0.{build}'  
shallow_clone: false    
pull_requests:   
  do_not_increment_build_number: false  

configuration: Release   
platform: Any CPU    

before_build:    
 - nuget restore src/OpenUserSecrets.sln  

build:   
  project: src/OpenUserSecrets.sln   

artifacts:   
- path: '**\*.vsix'

AppVeyor は、イメージに Visual Studio などのツールが入っているので Visual Studio 2017Visual Studio 2019 を選んでおきます。

www.appveyor.com

GitHub Actions

OpenUserSecrets/build.yml at master · guitarrapc/OpenUserSecrets · GitHub

name: build

on: [push]

jobs:
  build:

    runs-on: windows-2019

    steps:
    - uses: actions/checkout@v1
    - uses: warrenbuckley/Setup-Nuget@v1
    - run: nuget restore $Env:GITHUB_WORKSPACE\src\OpenUserSecrets\OpenUserSecrets.csproj
    - uses: warrenbuckley/Setup-MSBuild@v1
    - run: MSBuild.exe $Env:GITHUB_WORKSPACE\src\OpenUserSecrets\OpenUserSecrets.csproj -p:Configuration=Release
      timeout-minutes: 5
    - uses: actions/upload-artifact@v1.0.0
      with:
          name: artifacts
          path: src\OpenUserSecrets\bin\Release\OpenUserSecrets.vsix

GitHub Actions は、host によってインストールされているツールが変わります。

help.github.com

help.github.com

windows-2019 は Visual Studio および Microsoft.VisualStudio.Workload.VisualStudioExtension が入っているので、このホストイメージで問題ありません。

パスを解決する

こういったCI でビルドするときに妙なはまり方をしやすいのが「PATH」です。 特にツールのパスは、「どこにインストールされたのか興味がない」のに、パスがとっていないと気にする必要があります。 そのため、こういったツールを利用するときはパスを通すのが定石です。

.NET Framework のビルドは、「パッケージをNuGet で復元する」「msbuildでビルド」というよくある2段階を踏んで実行されます。 この2つで使うツールを、GitHub Actions でパス解決しつつ実行する方法を考えましょう。

nuget.exe のパス解決

NuGet のパッケージリストアはnuget.exe を使って行います。 nuget.exe のパス解決は、uses: warrenbuckley/Setup-Nuget@v1 で行えるのでぜひ利用しましょう。

github.com

これで nuget restore csprojのパス で NuGetのパッケージリストアが行えるようになりました。

MSBuild.exe のパス解決

MSBuild は通常 Visual Studio を一緒に入っています。 これを解決するツールとして vswhere があるのですが、そんなものを使わず warrenbuckley/Setup-MSBuild を使いましょう。パスに入れてくれます。

github.com

これで MSBuild.exe csprojやslnのパス でビルドが実行できるようになりました。

NuGet のパッケージリストアを行う

基本的に、現在のリポジトリのチェックアウトパスに興味ありません。 環境変数 GITHUB_WORKSPACE を使うといい感じにcheckout したときのベースパスが解決されます。

これで、csproj のパスが $Env:GITHUB_WORKSPACE\src\OpenUserSecrets\OpenUserSecrets.csproj とわかりました。

キャッシュを考えそうですが、今回のような即座にパッケージリストアが完了する場合は考えなくてもいいでしょう。

これでいい感じで NuGet のパッケージリストアが実行できました。

ビルドを行う

ビルド時のcsprojパスも NuGet と同じで GITHUB_WORKSPACE を使えばokです。

また、今回は Visual Studio 拡張をビルドしたら、そのビルドパッケージを配布するのでリリースビルドを行います。

MSBuild実行時時にConfigurationプロパティを Release に切り替えればokです。

これでいい感じで MSBuild が実行されました。

デフォルトの csproj は、CIでビルドするときに 次のセクションで紹介する devenv 初期化が走って限界である 6 hour までタスクがタイムアウトしません。 timeout-minute: 5 は、ビルドが5分以上かかること自体が異常とみなしてタイムアウトを仕掛けています。

Visual Studio 拡張ビルド時のdevenv 初期化をスキップする

Visual Stduio 拡張は、クラスライブラリなどと違って 「ビルド時に Visual Stduio )devenv.exe) の初期化を行う」動きをします。 CI 的にはdevenvの初期化なんてされてほしくないわけで、実際永遠に終わりません、厄介! (6 hour timeout でビルド失敗する悲劇が起こる)

6時間タイムアウトでビルドが失敗した図

対策はいくつか考えられます。

github.com

私のオススメは、PropertyGroup で DeployExtension を false にして初期化を行わないことです。 csprojに <DeployExtension Condition="'$(GITHUB_ACTIONS)' != ''">False</DeployExtension> を設定しておけば GitHub Actions でのみ無効化されます。

Debug と Release ビルドで無効化したいので次のようになるでしょう。

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <!-- Stop Initialize Visual Studio Experimental Instance on CI -->
    <DeployExtension Condition="'$(GITHUB_ACTIONS)' != ''">False</DeployExtension>
    <!-- 省略 -->
  </PropertyGroup>

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <!-- Stop Initialize Visual Studio Experimental Instance on CI -->
    <DeployExtension Condition="'$(GITHUB_ACTIONS)' != ''">False</DeployExtension>
    <!-- 省略 -->
  </PropertyGroup>

これはオススメしません。失敗するはず。(このPRも最終的に取り消して↑の手法に切り替わってる)

https://github.com/microsoft/azure-pipelines-image-generation/pull/828github.com

パッケージをアップロードして GitHub Webから取得できるようにする

GitHub Release に置くことも考えそうですが、Visual Studio 拡張はMarket Placeからの配布が基本なので今回は Release ページには載せないことにします。 となると、ビルドした Action 毎にビルド成果物である .vsix ファイルがWeb上から取得できればok です。

こういった時に使えるのが、Artifacts です。 ビルドで vsix が生成されるパスは、csproj のあるパスからみて bin\Release\OpenUserSecrets.vsix とわかっているので、指定すればok です。

upload-artifact アクションは、環境変数 GITHUB_WORKSPACE のパスで実行されるので、Artifacts の path は リポジトリルートからみた指定でok です、親切!

期待通りアップロードされています。

いい感じで取得できることがわかります。

おまけ

今回の OpenUserSecrets のアップデート (1.1.0) は、この記事にあったNuGet のパッケージをインストールしてくださいメッセージへの対処や VS2019対応です。

shuhelohelo.hatenablog.com

REF

基本はこれ。パス解決の考慮がないのでCI的には取り回しが悪いので注意。

github.community

GitHub Actions ことはじめ

GitHub Actions 以前調べたのですが、いろいろあって個人プロジェクトでサクッとビルドするのみに使っていました。 今回改めて調べを進めたのでメモ。

幾つかのリポジトリを GitHub Actions に移行したけど、記事にしようとまとめてたらやった内容以上に調べることになってめちゃめちゃ時間かかった。

目次

TL;DR

  • とりあえず公式ドキュメント読めばok

help.github.com

  • 公式ドキュメントにないのはだいたいフォーラムみればok

github.community

  • 基本は Azure pipeline だけど、結構使いやすい感じになってる
  • Azure Pipelines と違って、step の name を省略するとコマンドがそのまま表示されるので name は基本省略で行ける。 (これ重要)
  • public repo なら Github Actions もいい感じ。Windows や macOS 依存はこっちに移植する
  • private repo は、GitHub を新料金プランにしているか次第。CircleCI の Performance Plan のユーザー課金が納得いかないのでこっちに移行していきたい
  • クラウドホストランナーが基本でよさそうだけど、Kubernetes 上でのCDを考えると セルフホストわんちゃんある
  • AppVeyor でやってたことはほぼ移行できる
  • CircleCI もだいたい行ける。Orb だけ代替あるかが問題になるぽ

トレンド

GitHub Actions の今のスタイルがブログでアナウンスされた2019/Aug/8 ぐらいからトレンド上がってるんですね。

github.blog

github.blog

世界

日本

USA

GitHub Actions の基本

基本的な情報を裏取りする。

使用条件

  • Org は新GitHub Pricing に移行していること (旧プランの場合 Actions 自体使えない)

旧プランで使えないのは、最近の GitHub の新サービスあるあるなのですが、なるほど困るケース結構多い。

旧プランと新プランは、リポジトリ数課金 or 人数課金の違い。 小規模な会社で30リポジトリ100ユーザーとかだと、新旧で桁が違うレベルで料金が変わるため移行に踏み切れないのはままある。

  • 旧プランは、人数無制限、リポジトリ数で段階的なプラン選択
  • 新プランは、人数課金、リポジトリ数制約なし

旧プランのほうがお得なケースは多数あってなかなか新プランに移行が難しいケースも見かけるので実は難しいやつ。

使用制限

並列数やAPI、実行時間で制限がある。

help.github.com

  • 1リポジトリあたりの同時並列は20
  • 1時間当たり リポジトリの全アクションで1000 APIリクエスト
  • ワークフローは実行時間6時間が上限 (指定しないと6時間たつまでタイムアウトしないので長すぎ
  • 無料、有料で同時実行上限がある
GitHub plan Total concurrent jobs Maximum concurrent
macOS jobs
Free 20 5
Pro 40 5
Team 60 5
Enterprise 180 15

マイニングがダメとかその辺は当然あるので見ておきましょう。 Serverless Computing がダメなのもそれはそうなんだけど、いい感じにやってみた的にやりそうな人も出てきそうなので規約でしばるのでいいですね。

料金

OSS は無料で並列度高いので気軽に利用できていい感じ。CircleCI より緩くて Azure Pipeline や Travis 並みに楽。

会社など Private Repo だと、Team でも 3000min/month (旧:10000min/month) しかつかないので、十分ではなく追加購入必要になる感じ。 従量課金の体系はシンプルで、GitHub ユーザー課金ある前提と合わせて追加なので、もともと GitHub 使ってたこと考えると CircleCI の Performance Plan より納得度は圧倒的にある。だからこそ新料金プランに限定するんでしょうが。

github.co.jp

help.github.com

  • パブリックリポジトリ : 無料
  • プライベートリポジトリ : 含まれる利用時間 + 追加購入

含まれる利用時間

利用時間は毎月リセットされるけど、ストレージはリセットされない。

2020/4/13 までは以下でしたが、2020/4/14~ 変更に

~2020/4/13プラン 1か月あたり利用時間 ストレージ
Free 2,000分 500 MB
Pro 3,000分 1 GB
Team 10,000分 2 GB
Enterprise 50,000分 50 GB
2020/4/13~プラン 1か月あたり利用時間 ストレージ
Free 2,000分 500 MB
Team 3,000分 2 GB
Enterprise 50,000分 50 GB
GitHub One 50,000分 50 GB

利用時間的には、GitHub Team が 旧Pro 相当になった感じ。

ストレージ価格がおもむろに出てきたけど、public は無料。 private の場合に、アカウントの持つGitHub packages とGitHub Actions アーティファクトの利用合計らしい。 制限を超えてアカウントが利用していて、$0 を超えるLimit spendingを設定していると料金がかかるので注意がいりそう。 そんなに大きなサイズのArtifact を設定するなという話なのですが、要注意。

アカウント > Settings > Billing > Cost management > Limit spending で設定できる。デフォ $0

ビリングの storage に関してを見ておくほうがよさそう。 ちょっと細かいので随時確認しよ。

https://help.github.com/en/github/setting-up-and-managing-billing-and-payments-on-github/about-billing-for-github-actions#calculating-minute-and-storage-spending

OS別時間消費

Linux を 1として、Windows や macOS は利用時間の倍率がついているという考え。

Operating system Minute multiplier
Linux 1
macOS 10
Windows 2

追加購入

倍率に応じてなので、結果としてOS別に価格差が生じる。

Windows たっか。(あるある macOS やばい、これは追加になるとセルフホストまったなしになりそう。

ホストランナー スペック 料金
Linux 2 cores, 7GB $0.008 1分あたり
Windows 2 cores, 7GB $0.016 1分あたり
macOS 2 cores, 7GB $0.08 1分あたり
セルフホスト - Free

ホストランナーの指定

GitHub Actions は Azure Pipeline 同様にホストランナー1をどこで実行するか選択できる。

help.github.com

マネージド、セルフホストの選択

ホストランナーはマネージド、セルフホストが選択できる。

  • GitHub ホストランナー :マシンメンテナンス、アップグレードがマネージドに提供される
  • セルフホストランナー : 物理、仮想、コンテナ、オンプレミス、クラウド に自分でインストールする

通常はクラウドホストランナー (GitHub が提供するホスト) を選ぶし、それが最も手早く楽。

セルフホストランナーは既にビルドを実行する環境がある、けどビルドの管理をしたくない、何かしらマシンに事前にインストールが必要など融通をきかせたいときに便利。ようは Azure Pipeline の Self Hosted Agent と一緒。

help.github.com

例えば、自分たちのKubernetesクラスターにセルフホストランナーを入れてビルドをすることで、クラスターの認証への考慮を減らしてクラスターへのデプロイすることもできる。

github.com

個人のプロジェクトで考えるので、ここでは GitHub ホストランナー を前提としてみていく。

ハードウェアリソース

GitHub ホストランナーは、 Azure VM (Standard DS_v2) 上で動作するので、スペックはVMと同じ、素直。

  • 2コアCPU
  • 7 GBのRAMメモリー
  • 14 GBのSSDディスク容量

DSv2-series

インストールされるツール

OS 毎に一覧になってるので入ってないツールはインストールして対応で。

help.github.com

IP

GitHub の IP とは違うのが注意で、以下のURL のIPレンジではない。

https://api.github.com/meta

github.community

全て Azure VM でのホスト、かつ現状は us-east-2 region なのでIPもそこ縛り。2

IPレンジは毎週更新してJSONで公開されているが、このリンクはまさかの Download Center で面倒な状況。

www.microsoft.com

サポート回答もこのURLで、常に最新のjsonに直接アクセスできるリンクは用意しない気配。

github.community

直URL も日付入りで、決まったURLへ定期取得するのは想定されてなさそう。

https://download.microsoft.com/download/7/1/D/71D86715-5596-4529-9B13-DA13A5DE5B63/ServiceTags_Public_20191216.json

100日さかのぼってみたが、今のところ更新ない or URL生成ルール違うのか404。(ルールあるのかなぁ)

OSの選択

GitHub ホストランナーの実行可能な環境は3種類あり、Azure Pipeline と同じ。 ほとんどのケースではLinux 選んでおけばいいけど、.NET Framework のような Windows 固定、Xcode のような macOS 固定もあるので用途に応じて。

  • Linux
  • Windows
  • macOS

Azure Pipeline 同様にマトリックスビルドには対応しているので、OSS で各種OSむけのビルドは CircleCI より書きやすく、Travis CI の代替になりえる筋はある。

https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/configuring-a-workflow#configuring-a-build-matrix

実行権限

CIではツールインストールなど権限を必要とすることが多い。 Linux/Windows いずれにおいても管理者権限があるので権限で悩むことはないかな。

  • Linux, macOS: パスワードレス sudo 状態
  • Windows: UAC無効管理者状態

ファイルパス

実パスを気にせず、GitHub が提供している環境変数でアクセスできる。

  • $HOME : ユーザーパス。ログイン認証情報を含めてokらしい
  • $GITHUB_WORKSPACE : アクションとシェルコマンドの実行パス、変更可能
  • $GITHUB_EVENT_PATH : webhook イベントのPOSTペイロードへアクセスできる

ホスト仮想マシン

ファイルパスは静的ではないため、GitHub が提供している環境変数を使う必要がある。

  • home
  • workspace
  • workflow/event.json

コンテナ

静的にパスを利用するため、USER を指定すると $GITHUB_WORKSPACE にアクセスできなくなる。 /github Path Prefix を予約しているので自分でボリュームマウントするときは気を付ける。

  • /github/home
  • /github/workspace
  • /github/workflow/event.json

環境変数

CircleCI のように spin up した環境の変数は出してくれない。Azure Pipeline と一緒で不親切、正直なんでやねんっていつも思ってる。

自分で拾う必要があるので、適当にデフォルトの環境変数は把握しておく。

GitHub が使う環境変数は、GITHUB_ prefixがついており、 GITHUB_ prefixを使用して環境変数またはシークレットは設定できない。(エラーになる)

help.github.com

シークレット

Settings > Secrets からシークレットを設定できる。

Azure Pipeline 同様に、ログからは自動的にマスクされる。 制約として、ワークフローで最大100シークレット、容量は64K 。

help.github.com

構造化データを値にするのは避けるべきというのは、あるある注意。

GitHubがログのシークレットを確実に削除するよう、構造化データをシークレットの値として使用することは避けてください。たとえば、JSONやエンコードされたGit blobを含むシークレットは作成しないでください。

GITHUB_TOKEN

GitHub Actions で何気に一番うれしいやつ。GitHub への操作多いので、Token 自動的に生成してくれるの最高。

前提として、write アクセスがあるユーザーになってるので注意。

リポジトリに対してwriteアクセスがあるユーザなら、誰でもシークレットの作成、読み取りおよび使用ができます。

GitHub Apps をインストールするアクセストークンとして、GITHUB_TOKEN が自動生成される。 ジョブごとに60分後に期限切れになる一方で、ワークフローはデフォルト6hまでタイムアウトにならないので注意がいりそう (このデフォルトが長い)

help.github.com

権限は一通り書き込み権限があり、リリースにパッケージ投げたりコメント書いたりは十分。 逆に言うと結構強いので注意がいりそう。(もちろんOrg / Team はない)

Fork リポジトリからは read があるけど write がない。PRでトリガーされるワークフローで書き込み操作は軽くはまることはあり得る。

Permission Access type Access by forked repos
checks read/write read
contents read/write read
deployments read/write read
issues read/write read
metadata read read
packages read/write read
pull requests read/write read
repository projects read/write read
statuses read/write read

コンテキスト

コンテキストはかなり便利。

help.github.com

github コンテキストは REST API でとれるレスポンス/webhook レスポンスに近く、そのコミットの情報が結構とれる。 コミットメッセージまででるので、skip ci に似た処理を自作するときに便利です。

環境変数 GITHUB_ でほとんどとれるとか書いてるけど、取れるのはよくCIにある情報程度で、少し深くなるとコンテキスト触るしかない。

env や secrets もコンテキストの一種なので、めちゃめちゃ使う。

コンテキストは、steps じゃなくても参照できるのが重要で、jobs.if でも利用できるのでコンテキストが一致するかで job自体を実行するかとかも制御できる。

Artifact

なるほど、アーティファクトで job 間のデータ永続は Azure Pipeline まんま。

GitHub Actions のアーティファクトとは、ワークフロー実行中に生成されるファイル、またはファイルのコレクション。

ワークフロー内の各ジョブが異なるインスタンスで実行されるため、ワークフロー内でジョブ間でデータを受け渡すのには必須。 ビルドパッケージを置いたり、ログを置いたり何かと使うやつ。

help.github.com

アーティファクトはアップロードされると zip になるけど、ダウンロードは生データが取れるので取り回しは楽。

  • ジョブが終了する前にデータをアップロードして、ワークフロー実行の内部にファイルを保存できる。 アーカイブをアップロードするときは、名前を付ける
  • ファイルをアップロードすると、同じワークフロー実行内の別のジョブでダウンロードできる。 アーカイブをダウンロードするとき、アーカイブは名前で参照できます。 アップロードされているアーティファクトをダウンロードできるのは、同じワークフロー実行中だけ

ワークフロー終了後にジョブごとに Artifact をWebから取得できるので便利。

トリガーイベント

1つ以上のイベントをトリガーに設定できる。 pushや Issue、PR、webhookなどの各種イベント以外にも定期実行も可能。 ここが CircleCI では厳しかったので GitHub Actions でうれしいところ。

GITHUB_SHAGITHUB_REF 環境変数に現在のイベントに応じた状態がでるのでなるほど。(イベントごとに変わる) wiki ページの作成、更新は gollum イベントらしい。

help.github.com

ただ、ワークフローから別のワークフローはトリガーできないので、コメントなり適当なイベントを仲介する必要がある。

実行しているワークフローのアクションからは、新しいワークフローの実行をトリガーできない。

push イベントでファイルの変更を完全に終えず、REST API を使って取得が必要なのもなるほど。

GitHub Actionsが利用できるwebhookのペイロードには、commitオブジェクト中のadded、removed、modified属性は含まれない。

Fork されたリポジトリではデフォルトでは動かない。 もし実行するようにしても、Fork されたリポジトリの GitHub Actions は ベースリポジトリではトリガーされず、Fork先のリポジトリで許可が必要なのは普通のCIでよい。

Cache

なるほど、CircleCI とよく似てるけど、微妙に違う。

マッチングルールは、key で完全一致を見て、失敗したら restore-keys を上から順に前方一致で検索なのでよくあるとおり「長いキーから順に書き並べる」のが王道。さらに restore-keys で複数一致したら最近のキャッシュが利用されるので素直な印象。

  1. key の完全一致
  2. restore-keys を上から評価
  3. より最新のもの

help.github.com

Cache と Restore がセットになってるのはうれしいですね、actions/cache しておくと、そのパスに変更合った時にJobの終了時に自動的に post action としてキャッシュされるのは普通に便利。 この時キャッシュキーがすでにあればスキップされるので、意図通り。

www.kaizenprogrammer.com

OS別なら、${{ runner.os }} をキーに入れるのもあるある。 キャッシュ上書きがなく、7日でキャッシュ消えるものの任意のキャッシュクリアがないので、環境変数などで cache-version を定義してキャッシュキーに含めるのも王道。

pushとpull_request イベントだけ使えること、7日間以上アクセスされていないキャッシュエントリは削除されることに注意。 また、リポジトリのキャッシュサイズ制限が2GB と小さいのもはまる。

  • 400MBを超えないキャッシュ内の個々のファイル。 この制限を超えた場合、400 - Bad Requestが返さる
  • リポジトリ内のすべてのキャッシュの合計サイズが2GBを超えない

相変わらず Windows \ と macOS/Linux / でパス文字 の解釈が違って key の指定がコケるのはつらい。

github.com

Actions

CircleCI Orbs じゃないけど、似たような処理の塊は Actions と呼ばれていて、Marketplace で公開されている。

github.com

Actionsでやっていることを知りたいときは、追っていくと GitHub リポジトリにたどりつくので、やってることも読めるしいい感じになってる。

Actions について概要はドキュメントがあるのでみればok

help.github.com

Actions を使うときは、GitHub Web 上で YAML を編集する時なら右にポップアップが出る。

シンタックスエラーを検出したり、インテリセンスとかも利くので、こっち使うのが楽。

GitHub Web上ならシンタックスエラーも検出

インテリセンスも利く

通知

Web と Email が設定できる。

help.github.com

なるほどビルドがコケると通知される。

YAML

実際書くときは、YAML書いてみて、わからないものを調べるという流れで慣れていっている。 ではYAMLで実際にどう書くのかざくっと使うものを見てみる。

Azure Pipeline 風味が残ってるような感じで、もうちょっと砕けててほど良さもある。

Getting started

はじめての YAML テンプレートは、Actions 選択したときに選択できるテンプレートを使うのが楽。

https://help.github.com/en/actions/automating-your-workflow-with-github-actions/starting-with-preconfigured-workflow-templateshelp.github.com

YAMLシンタックス

どういう要素があるのかは、まずはシンタックスを把握すればok。

help.github.com

最低限の定義はこんな感じ。何の意味もないやつ。

on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo Hello

次の要素が必須なのがわかる。

  • name : Workflowの名前でリポジトリのActions画面で表示される名前。省略するとパスになるので付けたほうがいい
  • on: 必須。実行するイベントやブランチなどの指定をする
  • jobs: 必須。とりあえず jobs: でok
  • jobs..runs-on: 動作させるホストランナーの指定。GitHub hosted か Self-hosted かはここで決まる
  • jobs..steps: 必須。とりあえず steps: でok。jobs を書くときは、最低1つの steps が必要
  • jobs..steps.step : steps の中は最低1つのstep が必要。例は run step を使っている

on

実行するトリガーの定義をここでする。 GitHub Actions が他のCIと決定的に違うのが、ここでGitHub イベントと楽にバインドできることだと思う。

# push のみ
on: push
# push と pull request なら
on: [push, pull_request]

ブランチも含めた制御ができるのはいい感じ。

on:
  # Trigger the workflow on push or pull request,
  # but only for the master branch
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
  # Also trigger on page_build, as well as release created events
  page_build:
  release:
    types: # This configuration does not affect the page_build event above
      - created

定期実行は、schedule イベントで実行できる。

on:
  schedule:
    # * is a special character in YAML so you have to quote this string
    - cron:  '*/15 * * * *'

env

グローバルに、全Job、全step から参照する環境変数はここで指定する。 特定のジョブでなら jobs.<job_id>.env でいいし、特定のStep でなら jobs.<job_id>.steps.env があるので、あまり使いたくない。

jobs.<job_id>.needs

依存する job を指定できる。大事。 ここで指定しないと並列に回るので、直列で回すときは CircleCI 同様依存関係を作る必要がある。

jobs:
  prepare:
    runs-on: ubuntu-latest
    steps:
      - run: echo prepare

  build:
    runs-on: ubuntu-latest
    needs: prepare
    steps:
      - run: echo build

jobs.<job_id>.runs-on

実行するホストのOSをあらかじめ定義された値から選んで使う。

  • Windows Server 2019: windows-latest または windows-2019
  • Ubuntu 18.04: ubuntu-latestまたはubuntu-18.04
  • Ubuntu 16.04: ubuntu-16.04
  • macOS Catalina 10.15: macos-latest, macOS-10.15
jobs:
  build:
    runs-on: ubuntu-latest

jobs.<job_id>.container

ジョブをコンテナで実行したいならここで指定する。

jobs:
  my_job:
    runs-on: ubuntu-latest
    container: node:10.16-jessie

何気にイメージ指定するだけじゃなくて、細かくDockerの実行時パラメーターも調整できる。

jobs:
  my_job:
    runs-on: ubuntu-latest
    container:
      image: node:10.16-jessie
      env:
        NODE_ENV: development
      ports:
        - 80
      volumes:
        - my_docker_volume:/volume_mount
      options: --cpus 1

jobs.<job_id>.services

追加のコンテナを動かすときは services を用いる。 例えば、CI上で Database 起動させてテストするとかはこれ。

jobs:
  container-job:
    runs-on: ubuntu-latest
    container:
      image:  node:10.16-jessie
    services:
      redis:
        image: redis
        ports:
          - 6379/tcp

job も actionもコンテナで実行しているときに services のコンテナの参照をするときは、ホスト名でok。

そのステップがホストで実行しているときに services のコンテナの参照をするときは、localhost + マッピングしているホストのポート でアクセスする。 ホストでマッピングされたポートは ${{ job.services.<service_name>.ports[<port>] }} でとれる。 上のredisなら、${{ job.services.redis.ports['6379'] }}

jobs.<job_id>.if

ジョブの実行自体をここで制御できる。circleci のwhen を job で指定するみたいなやつ。 if ではコンテキスト参照できるので、特定のコミットメッセージの場合はジョブを実行しないとかが書ける。

jobs:
  my_first_job:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request' && github.event.action == 'unassigned'

あと、if ではコンテキスト参照するときに ${{ }} で囲まなくていい。 演算子とか書式はドキュメント見るのがいい。

help.github.com

job じゃなくて step を 条件で実行制御したい場合は、jobs.<job_id>.steps.if があるので、step に対して if を付ければok

jobs:
  my_first_job:
    runs-on: ubuntu-latest
    steps:
     - name: My first step
       if: github.event_name == 'pull_request' && github.event.action == 'unassigned'
       run: echo This event is a pull request that had an assignee removed.

jobs.<job_id>.steps

ここにやりたい処理を書いていく。 uses で、GitHub Actions を利用したり runs でシェルでコマンド実行したりできる。

uses は、step で特定のコンテナ実行とかもできるのでこれは結構便利。

  • パブリック Repository の任意のリリースやブランチ、コミットを指定できる
  • 自分のリポジトリで定義した action の参照
  • public registory の docker をステップで実行
jobs:
  my_first_job:
    runs-on: ubuntu-latest
    steps:
      # use GitHub Actions
      - uses: actions/setup-node@v1
      # use a specific version tag of a public repository
      - name: use AWS Repo
        uses: actions/aws@v2.0.1
      # use a action in workflow repository
      - uses: ./.github/actions/my-action
      # use a docker in public registory
      - uses: docker://gcr.io/cloud-builders/gradle

jobs.<job_id>.steps.run

一行、複数行、所定のパスで実行というのがよく使うパターン。 複数行は、安定の | なのでまぁ大丈夫そう。

jobs:
  my_first_job:
    runs-on: ubuntu-latest
    steps:
      # single line
      - run: sudo apt-get update
      # multi line
      - run: |
          sudo apt-get install google-cloud-sdk && \
          kubectl

他のシェルを指定するには shell: で指定する。

jobs:
  my_first_job:
    runs-on: ubuntu-latest
    steps:
      - run: sudo apt-get update
        shell: bash
      - run: Get-Location
        shell: pwsh

Windows の run、あるいはpowershellpwsh などを指定して PowerShell がシェルの場合、自動的に頭に $ErrorActionPreference = 'stop' が追加されて Fail fast になるのと、末尾に if ((Test-Path -LiteralPath variable:\LASTEXITCODE)) { exit $LASTEXITCODE } を追加して実行結果でrunステップが失敗するように処理が差し込まれているので注意。

jobs.<job_id>.steps.with

いわゆるパラメーター。 Actions とかでパラメーター渡すときは with の中に map (KeyValue) を書くことになる。 この with で指定したキーは、INPUT_ prefix つきで大文字に変換されて Actions 内部から参照できる。 first_name というキーで指定したなら INPUT_FIRST_NAME で値に参照できる。

jobs:
  my_first_job:
    runs-on: ubuntu-latest
    steps:
      - name: My first step
        uses: actions/hello_world@master
        with:
          first_name: Mona
          middle_name: The
          last_name: Octocat      

環境変数

step のrun実行時に渡したいなら、env: で指定する。

jobs:
  my_first_job:
    runs-on: ubuntu-latest
    steps:
      - name: Hello world
        run: echo Hello world $FIRST_NAME $middle_name $Last_Name!
        env:
          FIRST_NAME: Mona
          middle_name: The
          Last_Name: Octocat

step のrunの中でいじるなら、シェルに従って環境変数を触ればいい。

# windows
$env:PATH += ";$pwd\build\lib"

step 間で環境変数を保持したい場合は、set-env を echo 出力する。Azure Pipeline に似た感じだけど微妙に違う。

::set-env name={name}::{value}

action_state という環境変数に yellow という値をいれる場合はこうなる。

echo "::set-env name=action_state::yellow"

先ほどの PATH をstep間で保持するならこう。

# windows
$env:PATH += ";$pwd\build\lib"
echo "::set-env name=PATH::$env:PATH"

PATH 環境変数への追加は、 echo "::add-path::/path/to/dir" が用意されている。 echo "::set-env name=PATH::${PATH}:/path/to/dir" でも動くけど、楽なほうで。

help.github.com

シークレット

シークレットの利用は、secrets コンテキスト経由で利用できる。 例えば SuperSecret というキーで登録したなら、${{ secrets.SuperSecret }} 。 利用する際は、with 構文か env など環境変数経由で参照する。

steps:
  - name: Hello world action
    with: # Set the secret as an input
      super_secret: ${{ secrets.SuperSecret }}
    env: # Or as an environment variable
      super_secret: ${{ secrets.SuperSecret }}

GITHUB_TOKEN も シークレットコンテキスト経由で利用できます。

name: Pull request labeler
on:
- pull_request
jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/labeler@v2
      with:
        repo-token: ${{ secrets.GITHUB_TOKEN }}

ログの表示で任意の文字列をマスクするために ::add-mask::{value} もある。

Artifact

アップロード操作は$GITHUB_WORKSPACEを起点に path で指定できます。 常に相対パスでいいので、絶対パスを気にする機会が減っていい感じです。

アップロードしてダウンロード

jobs:
  job_1:
    name: Add 3 and 7
    runs-on: ubuntu-latest
    steps:
      - shell: bash
        run: |
          expr 3 + 7 > math-homework.txt
      - name: Upload math result for job 1
        uses: actions/upload-artifact@v1
        with:
          name: homework
          path: math-homework.txt

  job_2:
    name: Multiply by 9
    needs: job_1
    runs-on: windows-latest
    steps:
      - name: Download math result for job 1
        uses: actions/download-artifact@v1
        with:
          name: homework
      - shell: bash
        run: cat homework/math-homework.txt

Cache

サンプルはいくつかあるのでそれをみるのが手っ取り早い。

github.com

.NET Core の nuget を例で考えます。(.NET Framework は忘れましょう)

.NET Core は Package References にしていると csproj にpackage 情報に入るのが厄介です。 もし csproj が1つならこれでいいでしょう。

steps:
  - uses: actions/cache@v1
    with:
      path: ~/.nuget/packages
      key: ${{ env.cache-version }}-${{ runner.os }}-nuget-${{ hashFiles('src/project.csproj') }}
      restore-keys: |
        ${{ env.cache-version }}-${{ runner.os }}-nuget-${{ hashFiles(''src/project.csproj') }}
        ${{ env.cache-version }}-${{ runner.os }}-nuget-

1つだけプロジェクトがあるならならいいのですが、複数の csproj に分離していると当然パッケージとバージョンの同一性を担保する方法が lock ファイルに比べて面倒です。 CirclrCI でやったように、csproj を拾ってきて md5 あたりを拾ってキャッシュキーにする感じになるでしょう。 CircleCI の例を載せておきます。

steps:
  - run:
      name: Calculate cache key for csproj
      command: |
        {
          md5sum $(find << parameters.search_path >> -name << parameters.target_file_pattern >> | sort -r)
        } > ~/cache-key-source-<< parameters.project >>
      working_directory: << parameters.working_directory >>
  - save_cache:
      name: Cache nuget pacakges
      key: nuget-<< parameters.cache_key >>-<< parameters.project >>-{{ checksum "~/cache-key-source-<< parameters.project >>" }}
      paths:
        - "~/.nuget"

nuget-cache-orb/nuget_save_cache.yml at 77c2c0cafe089314ae3d3d08473d429372737289 · guitarrapc/nuget-cache-orb · GitHub

なお、nuget は、macOSは Xamarin などでキャッシュサイズが半端なくなるので、こういうのを避けるために NuGet Package のパスを明示的に設定するのはあり。 その場合は、NUGET_PACKAGES 環境変数にパスを指定して、actions/cache の path にも指定する。

env:
  NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
  - uses: actions/cache@v1
    with:
      path: ${{ github.workspace }}/.nuget/packages
      key: ${{ env.cache-version }}-${{ runner.os }}-nuget-${{ hashFiles('src/project.csproj') }}
      restore-keys: |
        ${{ env.cache-version }}-${{ runner.os }}-nuget-${{ hashFiles(''src/project.csproj') }}
        ${{ env.cache-version }}-${{ runner.os }}-nuget-

TIPS

細かいけど知っておくといい TIPS がたまってきたのでメモ。

step の name

step ごとに name を指定することで、GitHub 上の表示を設定できる。

step ごとの name を付ける

省略するとコマンドがそのままでるので、CircleCI のように基本的に name 指定しないのがよさそう。

step ごとの name を省略する

Azure Pipelie は、コマンドの内容ではなく command@1 とかのモジュール名の表示になってたので、GitHub Actions で改善してて本当に良かった、神。

タイムアウト

timeout-minutes で指定できる。 デフォルトが 6hour と長いので、指定した方がいいケースが多い。

タイムアウトは、job と step ごとの両方に指定可能。

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - run: sleep 300
        timeout-minutes: 3

skip ci / ci skip

2021/2/10 に、push/pull_request トリガーで標準サポートされました。

github.blog

競合でもよく使われる [skip ci], [ci skip], [no ci], [skip actions], or [actions skip] が網羅されててなるほど。

以前は、job の if で制御してましたがもう不要。

github.com

Organization の他の private repo の参照

ssh-agent Action を使えば SSH キーで known_hosts 設定したりできるけど、あんまり使いたくはない。

github.com

自動生成される Token でその制御はできないので、専用の Token を生成するのが一番手っ取り早い。

- uses: actions/checkout@v1  
  with:
    repository: organization_name/repo_name
    token: ${{ secrets.ACCESS_TOKEN }}

stackoverflow.com

Badge

サポートされてた。ドキュメントないけど。

srz-zumix.blogspot.com

いい感じの Action どこ

安定の awesome で。

github.com

ローカルで構文チェックするCLIとかないの

Circle CLI のようなローカル実行向けのCLI はないです。 残念。


  1. GitHub Actionsランナーアプリケーションがインストールされた、GitHubがホストする仮想マシン
  2. 今後増える可能性があるとのことですが、本当に増やすのかな?

CircleCI Orb をいくつか作った話

幾つか CircleCI Orb を作っていたのですが、記事にしていませんでした。

どれも必要になって作ったもので、いずれもプロダクションで万単位で実行されれているのでいい感じで使えそうなら幸いです。

目次

TL;DR

  • NuGet Cache を制御するなら guitarrapc/nuget-cache
  • Shallow Clone を制御するなら guitarrapc/git-shallow-clone
  • Chatwork にメッセージを投げるなら guitarrapc/chatwork
  • CircleCI は、公式Orb でやっているやり方をドキュメントに反映してほしいです。Orbを初めて作るときに把握から始まるのは結構ツライ

Orbs とは

CircleCI は Job や Command にまとめていた処理を Orb として共有できます。

circleci.com

これって結構強力でいい仕組みで、Executor を含んだり含まないことができます。

  • CircleCI でYAMLが特定の処理のためにやけに長くなってしまった (Executor 依存がないとよりよい)
  • 特定の操作を行いたい

特定のシーンにスコープを絞れば Executor 依存してもいいし、特定の処理に絞って汎用的に使いたいなら Executor 依存しないようにするといいでしょう。

CircleCI でやっていこうと思ったら、何かしたいときは Orb をチェックするのは標準的に行うといい流れを作ろうとしているし、実際そうだと思います。

既存のOrbs で提案があれば適当にPR出したりもいいでしょう。 どのみち config.yml は公開されますしね。

tech.guitarrapc.com

公開したOrbs

3つ作って公開しています。

どれも当初は commands として定義していたのですが、ほかのプロジェクトでも使えるし公開しました。

guitarrapc/git-shallow-clone

https://circleci.com/orbs/registry/orb/guitarrapc/git-shallow-clone

git shallow clone をするOrb は実はいくつかあります。 有名なのは、ganta/git でしょうか。

qiita.com

しかしこれらのOrb はどれも Fork プロジェクトは考慮されていません。 また、GitHubや BitBucket が死んでることを想定していないので、案外失敗します。

guitarrapc/git-shallow-clone は、Fork プロジェクトにも対応しつつ、実際に頻繁に使っても問題ないまでブラッシュアップしてあります。

利用はいたってシンプルです。

orbs:
  git: guitarrapc/git-shallow-clone@1.0.1
version: 2.1
workflows:
  build:
    jobs:
      - git/checkout_shallow

keyscan_bitbucket と keyscan_github で、実際のリポジトリを keyscan するか選べます。 デフォルトは、鍵の更新がしばらくないのでハードコードしてあります。

depth と fetch_depth で、深さを指定できます。 Shallow Clone は、depth で 1指定しておいて、fetch depth では少し深く 5~10指定しないとブランチとかをいい感じで処理できないのでその対策も入っています。 clone時にsingle branchを使ってると気にせずにすむのですが。

clone を高速に終わらせて、汎用的に使いたいならお勧めです。 毎日結構な回数動いてて安定しているので、大概のケースでいけるかと。

この Orb はテストを書くのが面倒でしたが、ひとこねしたテストも書けるのは CircleCI 強かった。

guitarrapc/nuget-cache

https://circleci.com/orbs/registry/orb/guitarrapc/nuget-cache

.NET Core のビルドで困るのが、nuget package の restoreサイズは大きく時間がかかるということです。 別に一切気にしないという手もありますが、キャッシュしておくほうが爆速になるのでやるでしょう。

ただ、cache をするにはキャッシュキーを決める必要があります。 利用するパッケージに変更があったらキャッシュを切り替えたいわけです。 .NET Core なら csprojの変化を見るのが一番間違いがないでしょう。(Directory.Build.props は考慮したくないですね!)

guitarrapc/nuget-cache を使うと、任意のファイルを拾って md5 を取得してキャッシュキーに利用しつつ、cache のsave/restoreが可能になります。

想定している流れ場、nuget_cache/nuget_restore_cache して、dotnet restore してnuget_cache/nuget_save_cacheです。

orb でいい感じのキーで nuget-restore して、dotnet cli でdotnet restore するのはキャッシュがあれば秒で終わります。 キャッシュがずれていたら適切に dotnet restoreでリストアされるので、あとはいい感じのキーでsave してあげれば次回以降のビルドで生きます。

orbs:
  nuget-cache: guitarrapc/nuget-cache@0.1.1
version: 2.1
executors:
  dotnet31:
    docker:
      - image: 'mcr.microsoft.com/dotnet/core/sdk:3.1'
    environment:
      DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
      NUGET_XMLDOC_MODE: skip
jobs:
  build:
    executor: dotnet31
    steps:
      - checkout
      - nuget_cache/nuget_restore_cache:
          cache_key: test_save_cache
          project: nuget-cache-orb
      - run: dotnet restore
      - nuget_cache/nuget_save_cache:
          cache_key: test_save_cache
          project: nuget-cache-orb
          project_cache: false
      - run: dotnet build

シンプルですが、こういうのが適当にできるのがいいなぁということで作りました。 いろんなプロジェクト構成に対応できるように、cache_key や project、working fidrectoryや target file pattern も指定できるようにしてあります。

実際、外部リポジトリを使った複雑なプロジェクト構成でも機能しているのでだいたいうまくいくはずです。

guitarrapc/chatwork

https://circleci.com/orbs/registry/orb/guitarrapc/chatwork

Chatwork のルームにメッセージを送信します。 さくっとメッセージを送るだけなら、Chatwork API を使うのがいいでしょう。(こんなことで OAuthしたくない)

ということで、curl でサクッと送ります。

orb:
  chatwork: guitarrac/chatwork@0.0.2
version: 2.1
workflow:
  build:
    jobs:
      - chatwork/notify:
          message: Hello+Chatwork%21
          room_id: '12345'

環境変数 CHATWORK_TOKEN に API Token だけ仕込んでおけばサクッと使えます。 また、when に対応してあるので、「on_success 成功時 (デフォルト) 」、「on_fail 失敗時」、「always いつでも」の状況に合わせた送信ができます。

Orb を作る

基本は公式を見ましょう。

circleci.com

namespace とか、circleci cli の基本操作は沿っておく必要があります。

ただし、公式 CircleCI Orb はいずれもこの構成とはずれています。ひどい。 ということで、実際どうやって構成しているのかを把握します。

Orb の構成を把握する

Orb を使うのはともかく、作るとなると「作ること自体は簡単」です。 ただ、「テストやCI/CD」まで含めると面倒ですが、テンプレート化してしまえばあとは流れ作業で作れます。

このテンプレート化がドキュメントがなく、CircleCI 公式Orb でもどれもバラバラなので把握が面倒です。

公式を見つつどんな構造化把握します。

基本構造

公式Orbもそうなのですが、Orb のディレクトリは基本的に次の構造になるはずです。

.
├── .circleci
│   └── config.yml
├── LICENSE.md
├── README.md
├── src
│   ├── commands
│   │   └── your_command.yml
│   ├── examples
│   │   └── your_command.yml
│   └── @orb.yml
└── tests
    ├── your_test.yml
    └── your_test_n.yml

シンプルに、@orb.yml に全部定義というのもいいと思います。

github.com

.circleci

Orb自体のCI/CDは CircleCI 自身で行います。後述。

src/@orb.yml

Orb のDescription と依存する Orb などを書きます。

例えば、次のように書く

version: 2.1

description: >
  Build images and push them to the Amazon Elastic Container Registry.
  See this orb's source: https://github.com/circleci-public/aws-ecr-orb
orbs:
  aws-cli: circleci/aws-cli@0.1.13

Orbのページでは次のように表示されます。

実際のところ、@orb.yml じゃなくても orb.yaml で動作します。 私は orb.yml にしていますが、公式はみんな @orb.yml なのでそっちにしておけばいいでしょう。

src/commands/

commandsフォルダの中に置いたファイル名がコマンド名になります。 いいですね、この割り切り。

ecr-login というコマンドなら、ecr-login.yml というファイル名にします。

description: "Authenticate into the Amazon ECR service"

parameters:
  region:
    type: env_var_name
    default: AWS_REGION
    description: >
      Name of env var storing your AWS region information,
      defaults to AWS_REGION
steps:
  - run:
      name: Log into Amazon ECR
      command: |
        # aws ecr get-login returns a login command w/ a temp token
        LOGIN_COMMAND=$(aws ecr get-login --no-include-email --region $<<parameters.region>>)
        # save it to an env var & use that env var to login
        $LOGIN_COMMAND

すると、ecr-login としてコマンド定義が公開される。

src/examples/

コマンドのサンプルを定義します。 examplesフォルダの中に置いたファイル名がExample名になります。

なのでコマンドごとにファイルを用意したり、Workflow として一連の流れを定義したりです。

たとえば Workflow simple-build-and-push-image を定義して、それを Orb画面で simple-build-and-push として表示したいなら次の定義になります。

description: Log into AWS, build and push image to Amazon ECR

usage:
  version: 2.1

  orbs:
    aws-ecr: circleci/aws-ecr@x.y.z

  workflows:
    build_and_push_image:
      jobs:
        # build and push image to ECR
        - aws-ecr/build-and-push-image:

            # required if any necessary secrets are stored via Contexts
            context: myContext

            # AWS profile name, defaults to "default"
            profile-name: myProfileName

            # name of env var storing your AWS Access Key ID, defaults to AWS_ACCESS_KEY_ID
            aws-access-key-id: ACCESS_KEY_ID_ENV_VAR_NAME

            # name of env var storing your AWS Secret Access Key, defaults to AWS_SECRET_ACCESS_KEY
            aws-secret-access-key: SECRET_ACCESS_KEY_ENV_VAR_NAME

            # name of env var storing your AWS region, defaults to AWS_REGION
            region: AWS_REGION_ENV_VAR_NAME

            # name of env var storing your ECR account URL, defaults to AWS_ECR_ACCOUNT_URL
            account-url: AWS_ECR_ACCOUNT_URL_ENV_VAR_NAME

            # name of your ECR repository
            repo: myECRRepository

            # set this to true to create the repository if it does not already exist, defaults to "false"
            create-repo: true

            # ECR image tags (comma separated string), defaults to "latest"
            tag: latest,myECRRepoTag

            # name of Dockerfile to use, defaults to "Dockerfile"
            dockerfile: myDockerfile

            # path to Dockerfile, defaults to . (working directory)
            path: pathToMyDockerfile

Orb画面は、simple-build-and-push とファイル名になります。

tests

テストを定義しておきます。

ここは CircleCI 上で解釈されて実行されるので、いい感じにファイルを置きます。 もちろん CircleCI 上で config.yaml を走らせることもできて、その場合はconfig.yaml の記法に沿っておく必要があります。

公式Orbは案外tests フォルダを持っていないのですが、devに挙げたorbで挙動をテストするようにしています。

testsフォルダを設けている例として、mafuyuk さんや私のOrb を例にします。

github.com

github.com

例えば、mafuyuk/terraform-orb は terraform 操作を行う Orbです。 その test.yml は次のようになっています。

  version: 2.1

jobs:
  build:
    executor:
      name: terraform/default
      tag: 0.11.11
    steps:
      - checkout
      - run:
          name: Create Sample Terraform
          command: |
            mv test/backend.tf backend.tf
            mv test/main.tf main.tf
            mv test/provider.tf provider.tf
            mv test/variables.tf variables.tf
#      - terraform/init
#      - terraform/plan
#      - terraform/apply:
#          use-plan: false

コメントアウトされていますが、ニュアンスはわかります。

テストのときは、cache のようなファイル操作ができないのは circleci cli の制約を食らうのでそこは注意です。 なんだそれ感はある。

もし、外部リポジトリをクローンするなどSSH Key を渡したりといった込み入ったことをする必要があるなら、こっちのOrbが参考になるでしょう。

github.com

ポイントは、テストをどう走らせるかです。

  test:
    # ref: https://github.com/ganta/git-orb/blob/master/.circleci/config.yml
    # Workaround for passing a SSH key with orb-tools/local-test-build command
    # https://github.com/CircleCI-Public/orb-tools-orb/blob/330d11bb0cdef3c2f24cb4e2c595ca01e55bfd8c/src/%40orb.yml#L107-L134
    commands:
      local-test-build:
        parameters:
          path:
            type: string
        steps:
          - run: cp << parameters.path >> tmp-config-src/config.yml
          - run: mkdir -pv $(dirname tmp-config-src.yml)
          - run: circleci config pack tmp-config-src > uncompiled-config.yml
          - run: cat uncompiled-config.yml
          - run: circleci config process uncompiled-config.yml > config.yml
          # Cannot access "~/.ssh" from working directory.
          # pass spin up env's CIRCLE_TAG to local circleci command.
          - run:
              command: |
                cp ~/.ssh/id_rsa ./id_rsa
                circleci local execute --checkout-key ./id_rsa -c config.yml -e CIRCLE_TAG=${CIRCLE_TAG} | \
                  tee local_build_output.txt /dev/stderr | \
                  tail -n 1 | \
                  grep "Success"

Orb のCI/CD をする

Orbを作ったら、それをいい感じでCircleCI 上で Orb のCI/CD をしたいでしょう。

CI/CDでは当然、Orb のLint、テストをしたり、Orb Dev に挙げて動作を事前テストしたり、Devから Production に Promote したりしたいです。 Promote はGitHub Tag に準じるといいでしょう。

つまりこれ。

  • CircleCI Orbで提供する処理を定義する
  • CircleCI Orbで何ができるのかDescriptionやExampleを定義する
  • Orb のCIを行う
  • Orb のDevへのCDを行う
  • Orb のProduction への CD (Promote) を行う

CircleCI-Public/orb-tools-orb

Orbリリースをするためのツールとして CircleCI が用意しているのが CircleCI-Public/orb-tools-orb です。

github.com

これを使うと、YAML のLintチェックから、パッケージング、テストの実行、GitHub Release 連動、DevへのCD、ProductionへのCD まで一通りできます、便利! ドキュメントがなく Example だけで動作もわかりにくいですが、がんばれ。

qiita.com

9.x 系

orb-tools-orb ですが、9.0.0でコマンドを悉く変えています。 9系はコミットでの制御に切り替える方針に伴って破壊的変更をしていて、コマンド自体が消えたりパラメーターが丸っと変わっています。

9.0.0 をやってるケースもあるので、気が向いたらあげよう。

qiita.com

CircleCI 公式の各種Orb は8.27.3 以前のバージョンで止まっていたりします。 対応確定するまでは 8.27.3 をターゲットで私は書いています。(8.27.6時点でもうダメだったりする)

基本的なパターン

公式Orb を参考にするといいでしょう。

circleci-orbs/config.yml at master · CircleCI-Public/circleci-orbs

slack-orb/config.yml at staging · CircleCI-Public/slack-orb

aws-ecr-orb/config.yml at master · CircleCI-Public/aws-ecr-orb

8.27.3 をターゲットにします。

定義

公式Orb 各種がそうですが、概ね次の流れです。

slack-orb/config.yml at staging · CircleCI-Public/slack-orb

lint_pack-validate_publish-dev

PR へのプッシュでトリガーします。

  • orb-tools/lint
  • orb-tools/pack
  • orb-tools/publish-dev
  • orb-tools/trigger-integration-workflow
  • orb-tools/trigger-integration-workflow

integration_tests-prod_deploy

テストはintegration タグやmaster-タグでトリガーします。 dev-promote-prodは、各種master-patch / master-minor / master-major のタグでトリガーされます。

  • 各種テスト
  • orb-tools/dev-promote-prod (patch)
  • orb-tools/dev-promote-prod (minor)
  • orb-tools/dev-promote-prod (major)

挙動は config.yaml だけ見ても全然分からず、動かしたりCircleCI-Public/orb-tools-orb をみるしかないでしょう。

リリースの流れ

PR を作って、CI と dev への CD が走るので通るのを確認、でマージすると Orb にpush されます。

Renovate を使うという手も。

www.kaizenprogrammer.com

Orbのテンプレートにする

適当に guitarrapc/chatwork-orb あたりはシンプルなのでテンプレートにしやすいでしょう。

github.com

Orbのnamespace を用意したら、これを fork したり適当にベースにして、OrbのコマンドとExample と orb.yml を変えてテスト書けば行けるはずです。(orb名やテストの置換はしましょう)

TIPS

既存の Orb で時々使いにくいやつがあるので、そうならないようにメモ。

  • Jobとしての提供なら、Orb でExecutor 指定しよう
    • 案外こういうのは多いので、どう使いたいか次第でまず決めるといい
  • Stepsとしての提供なら、Orb はなるべく依存小さくするほうがいい
    • Bash依存とか避けたほういいのは間違いない
    • コマンドある前提で組んでしまって、コマンドないならサクッとエラーになるのでユーザーに任せるほうがユーザーにとっても幸せ

REF

qiita.com

www.kaizenprogrammer.com

sue445.hatenablog.com

2019年を振り返って

毎年やっている昨年の振り返りをしてみます。

2018年はこれ。

tech.guitarrapc.com

目次

総合

2019年の初めにこう書きました。

会社としては、2019年は作りたいサービスを形にして何本かリリースするため働き方をシフトします。*8 個人は、会社のサービスリリースと収益化です。注力する言語的にはC# / Golang 、ツールはTerraform + Kubernetes + GCP/AWS/Azure + Unityです。

2019年は2018年より、さらに(自他に)求められるレベルが高くなっており、天井知らずを感じつつ楽しみたいと思います。

2019年は想定に基づいて働き方をシフトを進めました。 が、想定よりもクライアントとの密着した動きが必要になってしまって、結果そっちにフルコミットしていました。 つまり、サービスリリースのための余力0でそっちに全振り。 個人の目標からは乖離しておりよくない、けど経営計画で予想していた結果の1つで、途中でこっちに振ったので納得はあります。

今年は夏から完全にサーバーサイドに振っていて、Kubernetes での構築に完全シフトでした。前半はHoloLens、Vue.js に携わっていました。 サーバーサイド/インフラは、C#/Kunernetes が主で、おもにAWSがほとんどでした。2018年とは全然違う動きになったのですが、私のスキルがそっち側に伸びているので、まぁそんなものかと。一年を通して幾つか感じましたが、Kubernetes むずかし、たのしいのでよしとします。

2019年は、わからないことへの挑戦がかなり多く、知ってることの応用はあまり利かず前提に過ぎない状況をよく感じました。 もともと挑戦が多いのですが、結構苦しんだ感覚があります。

経営

会社としては、OSS は1つだけです。 会社としてメンテするもの、というのを公開していく方針なので来年はもう少し増やしていきたいので、増やせるように努力しよう。 サービスは後は実装なので、粛々と書きます、考えます。

一年を過ぎたので、税、会計回りも一通りすぎました。 経理、会計が税理士先生のおかげで負荷小さいので、感謝しかないです。 引き続き法に則って粛々と進めたいところ。

弁護士先生とのやり取りを通して、弁護士って法に基づいてうまく振る舞う方なのだなというのは少し面白かったです。 公正ではなく、利益を追求する側の人間なのは、なるほどそういうものかという気づきがありました。

興味深かったのは、中小企業庁の動きでした。 消費税増税で、転嫁拒否に対する法律上問題ある行動の有無に関して調査票が来たのですが、素直にうれしかったです。 弊社のお客様にそういった動きはなくスムーズに移行したのですが、転嫁拒否に対する是正の姿勢を見せてもらえるのは、経営者としてはうれしいものがありました。

プログラミング

2019年は、C# がかなり多かったです。 また、Terraform を普遍的に広く使うことが多かったものの、後半ではPulumi の調査と投入をしていて、AWS CDK よりいい感触でした。 Pulumi dotnet Advent Calendar やってましたが、Pulumiの利用悪くない感じがあります。

Pulumi dotnet Advent Calendar 2019 - Qiita

GitHub コミットは、ほどほどにこんなものでしょう。GitHub じゃないコミットが見えないので、少なく感じますが。

2019年GitHub コミット

なんか CircleCI 対応や Docker イメージの公開が想像の倍以上行うことになって、ひたすら必要な部品を作っては組み立ててました。

CSharp

お仕事でやっていた HoloLens + Unity でのお仕事が一通り構築してリリースを迎えられたのはよかったです。

C# はUnityを除き .NET Core のみでした。後半は、 .NET Core 2.1/2.2 を .NET Core 3.0/3.1 に対応とかありましたが、幸いコンテナ化していたので何も問題なく進んでよかった。

Serverless から一番遠ざかった年だったかもしれない、というのもたいていのものを ECS Faraget/Kubernetes 側に振ったというのもあります。 デプロイ、監視を含めた全体の流れからすると、Serverless を選択しない選択が結構増えました。 自分の会社では選ぶんですが、お手伝い先では選ばないということが結構多かったです。

C# のビルドは、割り切った結果、あんまり頑張らない方向に倒してうまくいっています。 dotnet CLI 的には頑張りようが小さいので、そこで外から頑張るよりは頑張らないように済む方向に。 UWP から離れたというのが大きい気がしますが、.NET Framework で SDK Style の csproj をハンドルできることに気づいたのがよかったです。

シングルバイナリは来ました、案の定CI/CD、コンテナでいい感じでした。 ただ、リフレクションは結構鬼門でリフレクションするならランタイム込みでビルドしても動作環境にdotnet ランタイムは必要。 リフレクション、明らかに使う機会はちょくちょくあるけどアプリの動作環境的には年々厳しい制約になりつつある気がする。

あとシングルバイナリでも .NET Core のICU はめんどくさいです。Invaliantでない限りは .NET Core は ICU ライブラリに依存してグローバリゼーション対応しているので仕方ないのですが。 これは Microsoft Docs にも載っていますが、実際にコンテナ回りでの動作を組むときに思ったよりツライ。

.NET Core アプリケーション展開 - .NET Core | Microsoft Docs

C# なんか年々難しい度が上がってるので、がんばろ。

CircleCI で感じるんですけど、C# というか dotnet CLI の Linux での操作なんか面倒、というか癖強い。

Golang

書くより読むことが多かった。 1つ必要だったのを書き上げましたが、素直だなという側面と書きにくさも感じるのでもうしばらく慣れまで必要そう。

VSCodeで書いててつらかったので Goland 入れました。

自社の言語は Golang を選んでいます。 しばらく自分の言語は二軸になりそう。

PowerShell

クロスプラットフォームで動く PowerShell Core とは裏腹に、お手伝い先で書く機会はなるべく減らしほぼ0にしていました。 なるべく選択に入らないようにしていたというのもあります。 代わりに Bash、C#を多く選びました。(可能なところなら Golang を選択しました)

これはアプリケーションエンジニアが同じものを触るときに、いかに違和感すくなくするかを考慮した結果です。 正確に言うと、アプリケーションエンジニアというよりPowerShell に興味がない人が、です。 PowerShellで書くだけで、そこに触れたくないという意識が働くケースをこれまでも多く見ていたので、なるべくその意識を起こさせたくなかった。 案の定、予想していた状況に近づいているので、選択はずれてなかったように思います。

個人では書いていて、guitarrapc/ScoopPlaybook や guitarrapc/dotfiles-win/setup.ps1 で使っています。 dotfiles-win のセットアップは、guitarrapc/dotfiles/setup.sh で書いたBash の動作を PowerShell で忠実に再現したものなので、書いてて面白かったです。

PowerShell 実践ガイドブックは、おかげ様で第三版まで重版されました。 次の機会があれば、PowerShell 7対応かな。

海外のコミュニティを見ていても、PowerShellではないコミュニティを見ていても、PowerShell 7になってもWindowsがない環境で標準的に使われることは恐らくないのだろうと感じます。 Windows では標準的な位置づけでいいのですが。 素直に「組み込みにくい」のは最大のハードルであり続けるのでしょう。

ShellScript

思った通り多かった、多くしました。 macOS だけ挙動が違うコマンドがところどころ出てくるのがうざいのですが、シカタナイ? もう少しコマンドのシミュレート、変換がいい感じにできないかなぁと思いつつ、粛々と書いています。

インフラ

お手伝いはこれが多かった。 Kubernetes 回りを組んでいます、ECS ともちょくちょくバトルしていました。

ECS は Mutlti Target Group サポートが来てだいぶんよくなりました。 しかし Code Deploy がひたすらツライ、Code Pipeline もアレですが、Code Deploy やばい、使いたくない、頑張って使ったけど、Kubernetes にたおす過程で使わないようにした。

Kubernetes はClient APIに手を付けていますが、仕様の変更の影響受けやすくて、うーんという感じが。 幸せになる世界はまだ先な感じがすごいある。

Terraform

Terraform は一度組んでおけば、結構使いまわし聞くのでそこはよかったです。 特に Terraform Cloudが来て Atlantis も使わずいい感じで管理できるようになったので、よかったよかった。

0.12 はすぐに対応したのですが、なかなかはじめのバグり方が盛大でさすが HashiCorp、引き続き警戒が必要という感じがあります。 とはいえ、Terraform Cloud の動きを見ていても、0.12 の後半のアップデートを見ていても少しずつ期待する方向に向いてきた気配もあるのかな。

Pragmatic Terraform on AWS がいい本でした。いくつか気になる内容はあるものの、概ね同意。

Pulumi

Terraform 以外の選択肢としてみてた時にちょうど GA してたので、検証から投入までしました。

結論からいうと使える、けどその言語で書かれているからと言って読めても意味は読めないというのは間違いなくあります。 AWS に限らず、GCP やKubernetes でなんでこういうリソースが必要なのか、こういう組み方が必要なのかはコードで読めても、リソースの意味や制約を知らないとできないようにです。

C# は今年GA なので、別State 参照が来たらオススメしてもいいかなぁ。 Provider を複数持ってもいいけど、別State はほしいかな。 チームで使うには高いので、なんかそこがずっとハードルになりそう。

Terraform から移行もしたのですが、移行するかどうかは Pulumi で、その言語で書きたいかに強く依存しそうです。 言語のとっつきにくさが消えるのはめちゃめちゃいいので、価値はあります。

Pulumi、公式ページが最大のリファレンスで特に .NET に関しては全然いないので頑張るしかない。コミュニティの規模はかなり小さいですね。

Kubernetes

ECS との選択、Kubernetesでの運用を考えた時に、実際にKubernetesでいくぞにするためにずっとやってました(ます)。 小さいチームだからこそ選択するという選択をしたのですが、結果は2020年に出るので引き続き正面から取り組みます。(つまり2019年初とは逆の判断をした)

しかし分散は得意だけど、特定の一台への接続を制御しようとすると工夫を凝らす必要があるので、そこはまだ頑張るしかない感触。 Agones を今のコンセプトのまま、ほどほどにいい感じで使えるように組んでいます。

比較的 Helm よりも Kustomize に振っています。

Kubernetes 完全ガイドが本当に良書でよかったです。

記事

78本、久々にちょっとはかけました。 Pulumi dotnet Advent Calendar で盛った感はあります。

C# が意識して多めです。 お手伝い先ではザクザク書いているのですが、手を動かしつつなので記事にするほどまとめてないというのもあり結構ブログに書こうとまでならないのですね。 2020年も同程度を維持したいです。

ライフスタイル

徐々に改善が見えてきましたが道は長そう。

睡眠時間が年間平均3時間14分と4分伸びました。11月、12月は4時間と伸びているのでちょっとずつ調整しています。 6時間寝るとかなり快適なのは前々からわかっていても達成できていないのですが、少しずつ意識的に週の中頃などに8時間程度寝れないか試みています。

ランチは抜くと夕方ごろに集中力が持たなくなってきたので意識して食べるようにしています。 糖質は意識的に少し差し引きつつ、たんぱく質でおなかに入った感じがあるように。

「個人に依存することはエンジンがかかるのが遅い」課題はなかなか解消できてないものの、すぐにやらなくても予め開いておくと手を付けやすいので意識的にそうしています。 個人に依存しないことは、Google Calendar でこまめにスケジュールに組むことでうまく維持できているので、どうやら自分に興味がないっぽい。

集中って私は最も大事なことと考えています。 で、見直した結果、椅子に座っててツライと感じるシーンがあったので先日7年ぐらい使ってたエルゴヒューマンを、アーロンチェアリマスターに変えました。 椅子って結構影響あるんですね、アーロンチェアの座り心地があってて結構集中しやすくなった感じがあります。 座り心地がいいというか、座っててつらくない、しっかり前を向ける。

最近は考え方を短いスパンで変化させることを意識させるようにしています。 結果として、数日前と言ってることが全然違っていたりするのですが、それでもいいとみなすようになったのは少し変わったかもしれません。

ゲーム

たまにはゲームのことも。 2020年のFINAL FANTASY7 REMAKEを楽しみにしています。(振り切るのか、考慮するのかが一番の注目として)

スマホ

モンストが好きで結構ずっとやっているのですが、ドラクエウォークが出てからこっちにシフトしました。 全キャラ全職業のレベルが50を超えたので、55の旅をしていて二週目。 冒険者レベルも50になって、お出かけレベルしか残ってないのでそろそろ何かこないかな。

マリオカートは相変わらずの任天堂な施策で、結構興味深く週一ぐらいで開いてはプレイしています。 任天堂のゲーム設計、運営って素直にすごいと思います。

Nintendo Switch

今年は、Nintendo Switch の利用が多かったです。

ゼルダの伝説夢を見る島は、小さいころにやったゲームでしたがリメイクを楽しみにやりました。2Dをスイッチでどう再構築するかが楽しみで、実際すごかった。 案外覚えててサクッとクリアしてしまったのですが、ハードモードむずかしいのでよいですね。 ただコントローラーのボタン配置は、やはり厳しいものがあって、Yで攻撃はやめてほしい感じがあります。どうしてこうしたんだろう。

Blood Stained が出たのでやってて案の定面白かったです? バランスが相変わらず壊せるので、終盤に行くほど楽になってしまうのも含めてまぁいいのでは。 結局銃最強だった。(終盤しか使わない)

PS4

ドラクエ11をやり忘れていたのでクリアしました。ドラクエは新しいタイトルほど面白いのでいいですね。一番面白かった。

そういえば私はFF15 が好きなんですが、売り上げ、本数が最も少ないのはゲーム性がどんどん変わってて、プレイヤーが置き去りになってるのかもなぁとドラクエをしていて思いました。(ドラクエは根本が変わってない) 私は新しい体験が好きなので、方針に共感はするのですが。

新サクラ大戦は年末やっていたのですが、二の次なのでまだクリアしていません。3D になったのはいいとして、戦闘回りがただの無双になってて本当にこれでいいのか? という感じがあります。

DEATH STRANDING を次にやりたいけど、まずクリアしてから予定。

Steam

Cities: Skylines をちょこちょこやってました。 楽しいけど、やっぱりシムシティ系なので時間をそこまで費やせない(費やす選択をしない) ので、むずかしい。

2020年は?

C# + Golang + Kubernetes + Firebase あたりが注力ポイントです。 サービスリリースと収益化をがんばろう。働き方のシフトよりも頑張りポイントのシフトがよさそう。

分からないことたくさんで人生飽きないな。 できることを1つずつ増やしていきます。

Wi-Fiを Amplifi HD に移行した

最近やってよかったことの1つが、Wi-Fi を入れ替えたことでした。

何がどう変わったのか残しておきます。

目次

TL;DR

  • Amplifi HD、日本ではまだ出荷可能になったばかりですがいい感じでおもしろいし安定はしてる
  • 外出先からアプリで設定変更したり通信テストできるのは人権
  • ミニスクリーンに現在の通信状況が可視化されるのは本当にいい、最高
  • タッチでWPSを有効にできたりするけど、WPS今どき機器がなくていらない感

Wi-Fi をどれぐらい使っているのか

私の環境は 100% Wi-Fiです。 唯一LANを使っているのは、Hue Hub と Yamaha RTX810 - Wi-Fi AP の間のみです。ただ、これも同一ボックス内LANで結んでいるので目に見えません。

私が有線を廃止してすでに5年経ちました。 有線は高速でいいのですが、ケーブルをどこまでも減らしたい気持ちが強くネットワークは無線を前提にしています。 常にWi-Fiが稼働するので少しの問題でもすぐに気づいたり手を打つ気になるので、「普段からドッグフーディングする」方針とよくマッチしています。

常時Wi-Fi で問題になるのが、通信の安定性です。 私自身、安定性が最優先、速度はその中でかのなかぎり高速にという方針ですが、案外これが満たされません。 速度が出ても、不安定なAPが多いのが残念です。 色々なメーカーや機器を試した結果、3年前の時点では最終的に Aterm が安定していたのでこれを使ってきました。

子機となるデスクトップはASUS PCE-AC88 を使っています。 多くのWi-Fi拡張カードはWindows 10 の起動時やドライバー問題が多く Intel もそれは同様でしたが、PCE-AC88は安定したドライバーと速度が両立していてとてもいいです。

PCE-AC88 | ネットワーク機器 | ASUS 日本

動機

Atermは長年変化がなく面白くないWi-Fiです。

  • 管理画面がWebのみ
  • Webの管理画面の変更の変更に都度時間がかかる + 再起動が毎度求められる
  • 同一ネットワークからのアクセスしかできない
  • 規格が古い

通信が安定していてよいのですが、さすがにここまで進化ないのは飽きたので変えます。

選定基準

条件を満たすものを探します。

  • 面白そうなやつ
  • アプリでの設定を前提にする
  • メッシュ対応
  • TP Link、Synology、ASUS は避けたい (尊敬するエンジニアがツライいってる....)
  • Buffalo は避けたい (良かったことがほぼない)

一方であればいいけどなくてもいい条件も定めます。

  • Wi-Fi 6 (あればうれしいけど)
  • WPA3 対応
  • トライバンド
  • IPoE 対応 (ルータがあるのでそっちで対応する)

価格は Nest Wifi 基準で20000円前後で探しましょう。

候補の絞り込み

いい感じのメッシュルータの一覧はありますが、これだけだと選びようがないのでスペックや利用感を調べて絞ります。

日本で入手できるメッシュWi-Fiシステム19種+2の比較【2019年12月】 | 24Wireless

  • Nest Wifi (Google)
  • Orbi (NetGear)
  • Velop (Belkin)
  • Sila (Razer)
  • Amplifi HD (Ubiquiti)

Nest Wifi

Nest Wifi - 高速で快適な Wi-Fi ネットワークをご自宅で - Google ストア

Google Wifi よりは面白そう。 見た目はつまらないけど、ほしい機能は一通りあるしまぁよさそう。 ただ、Google のアプリ微妙で好きじゃないので、「最悪これ」という位置づけ。

Orbi

RBR20 - AC2200 OrbiトライバンドメッシュWiFiルーター | NETGEAR

RBK20やRBK50、AC3000とか面白そうだけど、サテライト経由で不安定になるのが微妙そう。 2018年と古い。

なし。

Velop

Velop Whole-Home Mesh WiFi

機能は全部満たしてそう。 2018年と古い。ちょっとお高め。

なし。

Sila

Gaming Router - Razer Sila

4万円台で利用者が少なすぎ (情報が全然ない) 、見た目がつまらない。

なし。

Amplifi HD

AmpliFi | Faster, Whole-Home Wi-Fi

比較表で不明だらけで逆に興味深い。

Ubiquitiが出している個人向けのメッシュルータが Amplifi シリーズです。 一方で、企業向けのシリーズがUnifi で、こちらのほうがピンと来る人もいそうです。

他のメーカーと違ってディスプレイがあり、タッチ対応で通信状況とか見れます。 StackOverflow の中のエンジニアとかが使ってて、いい感じそうです。

日本で試せないかと思っていたら発売もしているし、Amplifiよさそうとはじめから前向きになれます。 サイトを見るとAmplifi Alien が出たばかりです。スペック、見た目からして面白そうなのでこれをしたいところですが、日本ではまだ取り扱いないので Amplifi HD とします。

購入前の機器判断は公式が提供しています。

AmpliFi Help

スペックはPDFで公開されています、内容は雑です。 Dual-Band、SU-MIMO(3x3 Chain, 18)、5Ghz で1300 Mbps、2.4GHz で450Mbps はあります。 MU-MIMO がないんですが、Amplifi Alien が対応しているのでいずれ載せ替えたいところ。 とはいえ、デバイスが 15台なので今のところは特に影響も感じず問題になっていません。

PDF: AmpliFi Datasheet

Unifi もどこかで試したいですね。 企業でのWifiも今ならUnifi が選択候補に入れたいところで、Yamaha などはそろそろ古い感じが半端なくなってきました。

AmpliFi vs. UniFi Review and Comparison [December 2019]

Amplifi HDを設置する

日本向けストアがあり、日本国内から発送されます。

AmpliFi HD Mesh Router – store-ui-japan

2日でさくっと届いたので、開けてみます。 ディスプレイからもわかりますが、見えるところにある前提のルータです。

開封

設定をしていきます。 ルータがすでにあるのですが、ルータからのLANは Amplifi の WAN に刺します。

デフォルトではDouble NAT になりますが、構成後は設定で Bridge に変更できます。

既にルータがあるので Bridge に変更していますが、Double NAT でも特に速度低下が顕著ではなかったので気づかず使っても大きな問題にはなりにくいでしょう。 ただし、ルータとして利用しているときに使える Teleport という簡易VPNは使えなくなります。 ルータある環境でこの機能いらないからいいんですけど。 https://help.amplifi.com/hc/en-us/articles/220979347-Enabling-Bridge-Mode

設定はアプリやWebから行えますが、基本アプリになるでしょう。 Web画面 はIP か http://amplifi.lan/ でアクセスできます。(Bridge だとIPのみになります。)

ユーザー認証をして、SSIDを設定すればもう使えます。

5GHz、2.4GHz で同一SSID が利用できるので、基本Wifi接続は一本化されます。 SSID を分離もできますがしないほうがメッシュではいいでしょう。

Guest Wifi も設定可能なので、必要な時だけ有効にすればWifiを提供するときに便利。

WPSも可能です、タッチスクリーン長押しでWPS有効化ができるのは面白く便利感あります。(WPS使わないけど)

アプリはユーザー認証するので、外出先からでも設定できます。

Wifi一覧

外出先から設状況が確認できるのはうれしみがあります。

設定

デバイス一覧

今どきのメッシュルータっぽく、速度検査もアプリからできます。

ステータス

速度検査

クライアント1つ1つの接続状況をアプリで確認しつつ、接続の一時停止もできるのでケイオスモンキーになりきることができて便利。

タッチスクリーンからは、時計、通信量、リアルタイム通信状況、ポート状況などが確認できます。 Night Mode があり、特定の時間はLED をオフにできるので、夜でも目に優しい。

通信量

通信状況

ポート状況

もともと集合住宅のインターネット回線で、下り100Mbps 程度なので速度も特に低下なく過ごしています。 そろそろ IPoE に切り替えよう。

REF