Diary of a Perpetual Student

Perpetual Student: A person who remains at university far beyond the normal period

GitHub Actions の workflow の lint を Github Actions で動かす

GitHub Actions で色々なコードの test や lint を動かしていると思います。

その際に workflow を yml で定義するのですが、この workflow ファイルはちゃんとチェックしてますか?

  • 「見よう見まねで yml を書いて push したけど、キー名が間違っていて動かなかった」
  • ::set-output などの deprecated な機能を今更使ってしまった」

こんな経験はありませんか?

Github Actions に関するその問題、Github Actions を使えば解決できます!

解決策

actionlint という Github Actions の workflow ファイルをチェックしてくれる lint ツールがあります。

github.com

こいつを Github Actions 上で動かすだけです。

動作させてみた例を以下に載せておきます。

github.com

deprecated な機能を利用して怒られた例

やり方

以下のように 2 つのファイルを用意して push しましょう。

.github/workflows/ci-actions.yml

on:
  push:
    paths:
      - .github/workflows/*.yml
      - .github/actionlint.yml
      - .github/actionlint-matcher.json

name: actionlint
jobs:
  actionlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install actionlint
        shell: bash
        run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
      - name: Add problem matcher
        run: echo "::add-matcher::.github/actionlint-matcher.json"
      - name: run actionlint
        run: ./actionlint
        shell: bash

.github/actionlint-matcher.json

以下からコピーして配置してください。

github.com

{
  "problemMatcher": [
    {
      "owner": "actionlint",
      "pattern": [
        {
          "regexp": "^(?:\\x1b\\[\\d+m)?(.+?)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*: (?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)* \\[(.+?)\\]$",
          "file": 1,
          "line": 2,
          "column": 3,
          "message": 4,
          "code": 5
        }
      ]
    }
  ]
}

解説

この workflow は以下のような流れで実行されます。

  1. github から actionlint を install するコマンドを実行
  2. actionlint の出力から annotation (この行がエラーだよという表示)を作るためのテンプレートを設定する
  3. actionlint を実行する

上級 Tips

手元では検出されないエラーが GHA 上で動かすと検出される

actionlint は手元でもインストール実行できるコマンドで、VSCode の拡張として使っている人たちもいるでしょう。このとき、手元環境だとエラーが検出されないのに、Github Actions 上で動かすとエラーが表示されることがあります。

この原因は、shellcheck というコマンドがインストールされているかどうかの差異にあります。

actionlint は、shellcheck がインストールされているなら、run: などで yml 上に書いているシェルスクリプトに対して shellcheck を適用した結果を教えてくれます。

shellcheck は Github Actions の ubuntu-latest runner にデフォルトでインストールされているのに対し、手元環境ではインストールしてない人もいるでしょう。

If you want to enable shellcheck integration, install shellcheck command. Note that shellcheck is pre-installed on Ubuntu worker.

actionlint/usage.md at main · rhysd/actionlint · GitHub より引用)

custom runner や self-hosted runner の名前がエラー扱いになる

基本 runs-on: ubuntu-latest として用意された runner を用いて動かすことが多いですが、大規模なプロジェクトでは custom runner や self-hosted runner を利用している場合もあるでしょう。

このとき、runs-on: hoge のように、デフォルトで用意されていない runner を指定すると、以下のように怒られます。

label "hoge" is unknown. available labels are "windows-latest", "windows-2022", ...

これをエラーとして検出しないようにするには、actionlint の設定ファイルを以下のように設置する必要があります。

.github/actionlint.yml

self-hosted-runner:
  labels:
    - hoge

cf.) actionlint/config.md at main · rhysd/actionlint · GitHub

まとめ

GitHub Actions のチェックが GitHub Actions でできました!!


余談

このエントリは社内でやっている技術勉強会「忘年LT大会」向けのものですが、せっかくなので public な場で書き留めておきました。

id:arthur-1ウロボロス的なものが好きで、はてなエンジニア Advent Calendar に「Advent Calendar の監視をする」というネタで投稿したのですが全くウケませんでした。今回もまた懲りずに同じ過ちを繰り返したわけであります。

blog.arthur1.dev

Mackerel Advent Calendar 2022 完走したので全部読む

Mackerel Advent Calendar 2022 の運営をしておりました、 id:arthur-1 です。この度は、Advent Calendar にご参加いただき、もしくは閲覧していただき、ありがとうございました。

qiita.com

25日分の記事が集まり、最後まで完走することができました。自分が設定したエントリ数の監視もちゃんと動いていました。

blog.arthur1.dev

総括というには素朴なのですが、書いていただいたエントリを読み、個人の感想としてコメントさせていただきます。

※社内・外関係なく統一して敬称をつけさせていただいております

全部読む

Day 1

blog.arthur1.dev

自分のエントリです。単位追加は細かい改修を除けば新卒初仕事だったのですが、自分が想像していた以上に社内外で反響があってよかったです。

Day 2

blog.stenyan.jp

id:stefafafan さんのエントリです。Mackerel はドッグフーディングを売りにしている割には、はてな社内での使い方を最近あまり発信できていないように思うので、ありがたい記事でした。

Day 3

yseto.github.io

yseto さんのエントリです。自分も snmp を喋れるルータを持っているので試してみました。システムメトリックとして投稿されている様子が確認できます。connectivity 監視応用は面白いアイデアですね。

Day 4

tech.buty4649.net

id:buty4649 さんのエントリです。こちらも手元に常時稼働している Raspberry Pi 4 があったので試してみました。残念ながら Mackerel には ℃ 単位がないのですが、メトリックはバッチリ見えてます。

Day 5

k1low.hatenablog.com

id:k1LoW さんのエントリです。コードメトリクス収集ツールのデータストアに Mackerel を追加していただきました。テスト実行時間は徐々に伸びていきがち。それが妥当か判断できるように自分の個人開発でも可視化してみようかなと Todo に加えました。

Day 6

qiita.com

tomotomobooks さんのエントリです。Meraki は持ってないので試せませんでした。書き出しが大変良い話だと Mackerel チームで話題になっていました。メトリックを集めやすい・とっつき易いという面は引き続き伸ばしていきたい!

Day 7

techblog.kayac.com

id:ikeda-masashi さんのエントリです。アラートの重要度は固定されずエラーバジェットによって変動する、確かに!と思いました。アラートのメモを API から編集できる機能は最近のリリースですのでぜひご活用ください。

Day 8

hktngch.hatenablog.com

Mackerel 開発チームのディレクター id:HKtngch さんのエントリです。Mackerel チームの現状の暮らし方が、アジャイルスクラムと違う路線を歩みつつあるのは自分も感じていて、色々な機会で啓蒙していただいています。

Day 9

ryuichi1208.hateblo.jp

id:ryuichi1208 さんのエントリです。自分の個人開発も MySQL を自前で立てて運用しているものがあるので、 MySQLで使用しているメモリが徐々に増え続けているので調べたメモ - 地方エンジニアの学習日記 と合わせて読ませていただきました。バグ修正の contribute もありがとうございました(私がやりとりさせていただきました)。

Day 10

blog.3qe.us

id:Windymelt さんのエントリです。Page Speed Insights 満点取りたい人間としてはぜひ監視したいメトリックです。Scala Native よくわからなくて手元の Apple Silicon Mac で build できなかったので宿題に……

Day 11

c4se.hatenablog.com

id:Kureduki_Maari さんのエントリです。mackerel-agent の plugin を作るための最低要件はこれだけですよという紹介と、例として「生命、宇宙、そして万物についての究極の疑問の答え」をメトリックとして投稿するシェルスクリプトプラグインの作り方を掲載していただきました。

Day 12

techblog.forgevision.com

id:matsuo1017 さんのエントリです。Mackerel の機能のうち、Web コンソールからできることに絞って最新のスクリーンショット付きで紹介していただきました。organization の分け方が色々あるよというのは Mackerel を始める上でとても大切なポイントですね。

Day 13

inommm.hatenablog.com

id:inommm さんのエントリです。画面の解像度が上がるに従ってリニアに負荷が大きくなると思っていたので、面白い情報でした。オーガニゼーションに対して標準でついてくるサービスメトリック数の範囲であれば料金を気にせず色々なものを手軽に可視化できるので、ちょっとした実験にもぜひご活用ください。

Day 14

isekatsukun.hatenablog.com

Mackerel セールスチームのディレクター id:isekatsun さんのエントリです。MSP セールスをやっていた時代の経験から、オンプレ→クラウドへの移行が進み始めた時代に、構築や監視運用のあり方が大きく変わってきた話を語っています。変化を恐れないために Mackerel を選んでもらえるようになりたいし、そのためには Mackerel が変化に対してフィットするプロダクトでなければならないですね。

Day 15

wafuwafu13.hatenadiary.com

id:wafuwafu13 さんのエントリです。mackerel-agent の configtest を機能拡張し、「もしかして、このキーと間違って typo してませんか?」という情報を出すようにしていただきました。その実装の解説をしてくださっています。レーベンシュタイン距離を用いた suggestion では Terraform でも同様にやっているんですね。

Day 16

blog.arthur1.dev

再び自分のエントリです。Telemetry API でログも取得できるので、Lambda 関数で定型のログを出して extension 側で取得することで、実行環境ごとに分かれたカスタムメトリック集計・投稿機能を作れたな〜と今更思っています。

Day 17

dev.classmethod.jp

kidapan さんのエントリです。インターン生に取り組んでもらったホスト一括退役機能をはじめとする Mackerel の 2022 年の主なアップデートを紹介していただきました。来年は、あれもこれも紹介したくなって困ってしまうぐらいにアップデートしていきたいですね。

Day 18

zenn.dev

sogaoh さんのエントリです。CIOps 的な内容で、デプロイと、それに伴って Mackerel による監視にダウンタイムを設定するのを CircleCI 上で同時にやってしまおう、というものでした。デプロイフロー改善に取り組んでいる我々にとって参考になりました。

Day 19

dev.classmethod.jp

cm-watanabeseigo さんのエントリです。カヤックさんが公開している OSS ツール shimesaba を使って、外形監視を SLO モニタリングする、という内容でした。Mackerel 単体で SLO 運用しにくいのも個人的には結構気になりポイントで、まずは我々の運用をアップデートさせないとな、と思っています。

Day 20

blog.stenyan.jp

id:stefafafan さんのエントリです。Github Actions から Mackerel を利用したい時のメジャーなケースがサービスメトリック投稿だと思うので、それだけの機能を持つシンプルな action は使いやすくて良いですね。action のメンテがされず朽ちていくのはあるあるなので、mackerelio の organization でこういったものも維持できると良いのかもしれない。

Day 21

tech.buty4649.net

id:buty4649 さんのエントリです。年末といえば大掃除・棚卸し、ということで、Mackerel に蓄積した情報を用いてインベントリ管理するというネタは 12月にピッタリですね。mackerel-agent を mipsel で動かすのも面白かったです。変わった OS や プロセッサ向けにも簡単に build できるのは Go 製の大きな強みです。

Day 22

genkiroid.github.io

genkiroid さんのエントリです。自分も TOML あんまり知らなくてヘルプ読みながら見よう見まねで書いていたので、なるほどと思いました。実装を知っていると TOML の Parser に渡してるだけなので等価なら大丈夫、となるのですが、それをユーザ全員が知るのは無茶な話ですし……

Day 23

kmuto.hatenablog.com

id:kmuto さんのエントリです。Mackerel CRE として入社して1ヶ月の様子をまとめていただきました。特に、Mackerel の開発合宿に飛び入り参加して作っていただいたデモは発表会で大好評でした。今後ともよろしくお願いします。

Day 24

tukaelu.hatenablog.jp

id:tukaelu さんのエントリです。カスタムダッシュボードにアラート一覧のウィジェットを力技で出すやり方を紹介していただきました。ダッシュボードが「この画面 1ページみたら良い」という存在になるために、公式として提供が必要な機能なのかもしれませんね。

Day 25

mackerel.io

id:wtatsuru さんのエントリです。見られるメトリックはたくさんありますが、パフォーマンスに影響しない下位レイヤーのメトリックに過度に敏感になったり、年々とシステムの利用状況が変化するにも関わらず監視ルールをそのままにしたり、といった悪い例を避け、監視の原則を守っていきたいものです。この思想は RDS だけでなく一般に役立つはずです。

最後に

改めて、Mackerel Advent Calendar 2022 にご参加いただきありがとうございました。

来年もより一層価値提供できるよう頑張りますので、id:arthur-1 と Mackerel をどうぞよろしくお願いします。

買って良かったものランキング 2022

ランキングと銘打っていますが特に順位はつけていません。悪しからず。

ガジェット編

YAMAHA のヘッドセット

軽い!聴こえる音が良い!マイクの音質も良好!ということでおすすめです。長時間つけていてもあまり苦ではないのでリモートワークにピッタリ。廃盤になると嫌なので予備も買っておきたいです。

DellKVM 機能つき 4K モニタ

私物の Windows と業務用の Macbook で USB 機器をいちいち繋ぎかえる必要がなく、入力切り替えに連動して繋ぎ変わるのは最高に便利です。

あと 4K に目が慣れきっていて、フル HD の PC モニタだと文字が読めなくなってしまっています。

家電編

スマートスポットライト

ダクトレールにつけるタイプのやつ。見た目がシンプルで部屋をスタイリッシュに照らせるだけでなく、スマートスピーカーで制御できるので良かったです。

ただし、買うならこれではなく上位機種を選ぶことをおすすめします。上位機種であれば別売りのリモコンからの制御にも対応しています。

アパレル編

PlayStation のパーカー

www.gu-global.com

急遽お泊まりすることになって近くの GU で買ったパーカー。会社の人にめちゃくちゃウケが良かったです。素材が軽めなので春秋におすすめ。

シューズ

www.nike.com

お店で見た瞬間にこれめっちゃカッコ良い!となって買いました。ポップとクールの狭間でありたい。

技術書編

実用 Go言語 ―システム開発の現場で知っておきたいアドバイス

A Tour of Go を一通りやったものの Go 言語の文化に慣れなかった自分が入門する本としては非常に良かったです。色々な topic が雑多に書かれていて少しとっつきにくい印象はあります。

学園祭のWeb開発を語る: 具象編2 開発体験・保守性を投げ捨てる

遠い昔に学園祭の Web 開発をしていた話をするシリーズもの

  1. 具象編1: 講習会と砂場遊びで支える組織
  2. 具象編2: 実際に使っていた技術や開発の仕方について語る ←イマココ
  3. 抽象編: 学園祭の開発部署という組織や、学園祭Webサイトというプロダクトの性質から語る

今回は泥臭い技術の話をしていく。


インフラ

当時はさくらのレンタルサーバで、 PHP でできた Web アプリケーションを動かしていた。レンタルサーバが設けた制約により、言語の選択肢はないに等しかった。

レンタルサーバを脱出して VPS にしようという話も出ていたが、我々の代でそれを行うことはしなかった。インフラ、サーバ管理に関して知識がある人間があまりにも少なかったからである。自分は個人で VPS を借りて遊び倒していたが、それを組織に展開するには運用持続性の面で疑義があった。

サーバは本番環境と開発環境の 2 つがあった。開発環境は、各自が実装したものを動作確認するために気軽に利用されていた。

ローカルの開発環境を用意していたのは自分の学年では自分だけだったと思う。Windows PC 上に XAMPP を立てて動かしていた。Docker は知らない子だった。自分は動的な部分(フォームなど)の開発を任されていたので、ローカル環境がないととてもやってられなかった。

Web アプリケーション

HTML をサーバ上で動的に組み立てて吐き出す、という古来のサーバサイドレンダリングであった。2015,16年というと Vue.js の v1 が出た、ぐらいの世界で、フロントとサーバサイドを分離するという思想は広く浸透していなかった。

フレームワークには FuelPHP を用いていた。なぜこのマイナーフレームワークを選定したかは分からない。昔のサイトがこれでできているから使った、という程度のものである。一応、Laravel が今ほどに人気になるより前の時代ではあった。

基本的な機能は備えていたので、下手なことをしなければ XSS や SQLi を回避できるようにはなっていた。

コードは MVC アーキテクチャで作られていた。後にリッチな View に引きづられて Controller が肥大化することを問題視し、Presenter 層を生やしている。

ちなみにテストは誰も書いていなかった。

git を使わないという選択

今思えば大分大胆なのだが、git は一切使っていなかった。サイト公開まではファイルをローカルの思い思いのエディタ(vim派、SublimeText派、atom派で分かれていた)で編集し、それぞれが本番環境に FTP でアップロードして更新していた。コードレビューなんてものもなかった。

GW には大学に集まって集中して開発を行っていたのだが、その時は衝突しないようにデプロイできる権利カードを物理的に受け渡していた。

ソースコードはサーバ上にあるものがマスタであったので、定期的にバックアップを取って切り戻せるようにはしていた。

バージョン管理を取り入れられなかったのは、やはり持続的にみんなが運用できるかというところに不安があったからだ。

前回講習会の話をしたが、1年間で HTML, CSS, JavaScript, PHP, SQL ... を詰め込むだけで相当頑張っていた。ネットワーク局は「一からでも上級生に教えてもらえるから大丈夫」ということで勧誘をする。技術的に長けているサークルは他にたくさんあるので、元からできる人はむしろ入部してこないのだ。

そこで、お客さんや学生にサイトを届けるという目標に直接関連しないバージョン管理の優先度は落とされることとなった。一応、1年間これで何もインシデントを起こさずにやってこれた。

維持するより建て直す方が楽

学園祭サイトの賞味期限は短い。毎年テーマに合わせたデザインにしているし、企画も毎年異なる。よって、サイトは毎年一から作り直していた。

他人のコードを読むという行為は本当につらい。増して、プロでもない学生のコードであればなおさらである。

また、Web アプリケーションエンジニアなら分かってもらえると思うが、ライブラリやフレームワークのアップデートというのは本当に toil で、積み重なり負債になりやすいものである。

1年に1回、その時の最新のバージョンでモノを作るから、その後は重大なセキュリティに関連しない限り更新しなくて良いね、というスタンスだった。

一度、継続して運用していくという前提で受験生応援サイトというものを開発した。合格体験記をどんどん蓄積していく CMS のようなアプリケーションで、データベースに体験記のレコードを追加すればページが勝手に増えるものであった。

自分がいなくなった後どうなったかというと、きちんと引き継がれることなく放置され、現在は作り変えられて消滅している。引き継ぎ資料としてドキュメントも作ったし、そんなに難解なコードでもなかったと思うが、サイトに新たな記事が追加されることはなかった。

毎年人が入っては消え、3年間で全員入れ替わる組織で、何かを継続して運用するというのは本当に難しいのだ。

ページスピードにこだわる

概ね poor な運用への言い訳になりつつあるので、技術的に頑張っていたこともあるんだよ、という話をする。

我々は Pagespeed Insights (現代で言うと Lighthouse)の得点をすべて 100点にすることに魂を燃やしていた。

例えば jQuery を意地でも使わないためにタブの切り替えやハンバーガーメニューの動作を CSS だけで実装したり、CSS を圧縮してインライン化したり、といったの工夫を行っていた。当時の取り組みを、学生時代の自分がブログに output していたので貼り付けておく(現在非公開)。

CSS だけでタブを実装してパフォーマンス比較する話

CSS インライン化の話

Google Analytics で取れるデータや、 Pagespeed Insights や Lighthouse が指摘してくる事項を眺めて、閲覧者の体験をよくするために何かできるか、ということをよく考えていた。数字が目に見えるものは、目標が明確で取り組みやすい。

まとめ

技術的な取捨選択の判断をメンバーの総意で行えていたことは、振り返ると学生集団としては意外とすごいことかもしれないと思う。明確な理由を持って提案し、多角的に評価して採択・棄却を行うという仕草は、社会人として雇われエンジニアをしている今もかなり役立っている。大学生の4年間というリソース*1は有限ではない。

一方で、いつ何か起きてもおかしくない綱渡り状態だったのは事実である。最近の学園祭サイトは、広告を載せて協賛企業からお金をもらい学園祭開催の資金としているものも多いだろう。企業と書面を交わし契約をしている立場なのだから、 availability にはもう少しシビアになるべきかもしれない。

次回は、具体的なエピソードではなく、現代の Web 開発のトレンドも踏まえた上でもう少し一般論の話をしようと思う。

*1:id:arthur-1 は学部で7年間過ごした

学園祭のWeb開発を語る: 具象編1 講習会と砂場遊びで支える組織

学園祭の Web サイト開発に関する良いエントリが出たので読んでいた。

zenn.dev

これを読んで、色々な学園祭のWeb開発がどういう組織形態で、こういう取り組みをして成功/失敗した、という話をもっと聞きたいと思った。

アウトプットが進めば、学園祭Webサイト業界(?)全体として互いに学び高め合うことができる。その伸び代があるなと感じている。

他の学園祭の開発部門にもぜひこのようなエントリを書いてほしいと思ったので、まずは自分が書く。というのも、id:arthur-1 は学生時代に学園祭実行委員会に所属して Web 開発に携わっていたからだ。

長くなりそうなので何 part かに分割して書く。現状、以下の3本立てで考えている:

  1. 具象編1: 自分が実際に生きてきた過去を振り返り、組織の運営について語る
  2. 具象編2: 実際に使っていた技術や開発の仕方について語る
  3. 抽象編: 学園祭の開発部署という組織や、学園祭Webサイトというプロダクトの性質から語る

まずは具象編。

これからする話は実在する組織に関する話になるわけが、今現在もこう!というわけではないことにご留意いただきたい。


工大祭の Web 開発してました

2015 年〜2017 年の間、id:arthur-1 は工大祭実行委員会のネットワーク局という部署に所属していた。企業で例えると、開発部門 & 情シス部門といったところで、主たる仕事はやはり Webサイトの開発と運用であった。

工大祭の Web サイトは当時年間 50 万PV ほどあるものだった。これを毎年テーマに合わせたデザインに作り替えている。自分が作った時代のものがもう見れなかったので、一番近かった頃のものを置いていく。

2017.koudaisai.jp

工大祭実行委員会には 3年間しか居られないのだが、ネットワーク局 3学年で以下のような役割分担をしていた:

  • 1年: とにかく学ぶ
  • 2年: 実働部隊として Web サイトを開発
  • 3年: マネジメント・後輩への教育、支援

僕がいた当時のネットワーク局の取り組みをいくつか紹介していく。

講習会

自分は小学生の頃にロボットコンテストに出場したり、今は亡き geocitiesFTPeuc-jp のファイルを送って黒歴史個人 Webサイトを公開したりしていた。中学高校では他の文化・芸能的活動に勤しんでいたので、大学生になった当時も、それ以上の知識はない、という状態で入部した。他の同期もめちゃくちゃWeb開発できる、という感じではなかった。

そんな自分たちを育ててくれた 2本柱のうちの 1つが講習会である。

前述の通り、3年生は開発のために手を動かすことをあまりせず、後輩を育てることに集中していた。ネットワーク局に入ってから1年弱の間、講習会を受講して Web 開発を身につけていくことになる。

おいおい React じゃなくて jQuery かよとか色々ツッコミはあるかもしれないが、当時はそういう時代だったのである。

3年生になると、2年生のうちに実際開発していて分かった「これは勉強してほしい!」というポイントを資料に反映させて講習会を作り変えていく。そういうサイクルが回っていて、情報が古びず良い仕組みだった。また、最終学年で次がないとはいえ、自分の知識をアウトプットすることで曖昧な理解が確かなものへと変化していったのも良かった。

自分が実際にどんなことを話していたのかを公開しようと思ったが、あいにく手元にもうデータが残っていなかった。参考までに、他のサークルで自分が話していた内容を一部紹介する。

エンジニアにはググり力が必要

semantic coding 啓蒙のために意味からタグを覚えさせる

HTML と CSS の責務について

冪等性最高!一番好きな性です

また、この講習会を通して、ネットワーク局でのキャリアパスが見えてきたのも面白ポイントだった。フォームの実装難しいけどデザインなら頑張れる、みたいな得意不得意を知り、それぞれが得意な部分の専門性を独自に磨くことができた。そして、それを講習会を通して集合知として組織に還元することができた。

工大祭実行委員会に閉じない活動も行っていた。学園祭の実行委員会は互いに交流する外交関係にあるのだが、Web の部署で勉強に困っているという他の委員会の話を聞いた時に、講習会資料の共有をしていた。

砂場遊び

講習会は良い仕組みだったと思っているが、座学はやはり飽きるものである。やはり手を動かしてこそ。

ネットワーク局の 1年生を育てる柱その2は、遊びサイト作りである。

HTML と CSS を学んだ 1年生は、次のステップに行く前に合宿用のWebサイトを作ることになる。合宿とは学園祭実行委員会全体の旅行で、夏の合宿は新入委員との懇親を深めるチャンスなのである。工大祭実行委員会には当時 3学年で 180 人ほど在籍していた。大所帯のため、合宿で居合わせた人がどこの部署のどんな人か分かるように、部員名簿を Web サイトにして部内公開するのだ。

1年生が各自が割り振られた部署の部員名簿サイトを、学んだことをもとに作っていく。作ったものは委員会全体で使われ、フィードバックがもらえる。自分の生み出したプロダクトがたくさんの人に使われるという経験を最初のスモールステップとして得ることになる。

合宿は年2回あり、2回目の冬の合宿サイトを作る頃には 1年生も大きく成長している。フレームワークを使ってサイト全体のテンプレートを管理していたり、外に出しても遜色ないクオリティのデザインになっていたりする。

世間一般に公開する初仕事は実行委員会の新歓サイトなのだが、いきなりそれを作ろうとすると行き詰まってしまうだろう。適度なタイミングで「時間制限下で決められた目的を達成するプロダクトを作る」というプロジェクトを複数回経験することで、技術力と企画進行力、そして自信を高めることができる。

また、面白いことはモチベーションが上がる、というのも大事な要素である。どうしたら他の委員がたくさんWebサイトを見てくれるかを考えながら、面白要素やイースターエッグを仕込んでいく。そのためならば学習も徹夜コーディングも全く苦ではなかった。

局員が自由に使えるサーバのリソースがあったのもポイントである。こういう節目以外にも、技術的な検証をしたり、個人で作ったものを委員会に展開するために個人が自由に使っていいサーバがあった。個人でサーバを借りたり建てたりするのは大変なので、とてもお世話になった。

自分のいる会社でもこうした技術検証に使えるクラウドの砂場が用意されていて、僕もよく活用している。これはスキルアップのために組織が払う必要経費なのだと思う。児童の創造力を高めるために、粘土を買ったり公園に砂場を作ったりするのと同じである。


次回は具象編2 ということで、泥臭いテクノロジーの話をする予定。

URL から profile を自動判別する Smart Google Chrome を作ろうとした

結論

URL を見て profile を自動判別して開くアプリ、もうあるってよ

brew install --cask choosy

Chrome の profile

Google Chrome の profile 機能を使っていますか? これは、ブックマークや履歴などの情報や設定を使い分けることができるものです。

support.google.com

例えば、仕事用と私用で使い分けるのが良くあるパターンですね。 id:arthur-1 は計4つの Google アカウントを持っているので、それぞれに対応した profile を Chrome に登録しています。

こいつが便利なんですが、痒い所に手が届かないのです。

複数の profile のウィンドウを同時に立ち上げている時に問題が起こります。Slack のアプリなどに表示されるリンクを踏んだとき、自分が開きたい profile のウィンドウでページが開かないことがあるのです。

挙動としては一貫性があり、直近でアクティブだったウィンドウの profile にタブが追加されます。しかし、サイトを開く前に開きたいウィンドウをアクティブにするのは面倒です。業務システムへのアクセスをプライベートな profile のブラウザでしてしまうことになりかねません。

profile を指定してページを開く方法

MacGoogle Chrome で、特定のWebページを特定の profile で開きたい場合はこのスクリプトを実行すれば良いです。

open -na "Google Chrome" --args "https://example.com/" --profile-directory="Profile 1"

"https://example.com/" のところには開きたいページを、 --profile-directory オプションには profile ディレクトリ名を指定しましょう。

profile ディレクトリ名は chrome://version/ というページを開くと分かります。下の図のような表示であれば "Profile 2" と指定すれば良いです。

「プロフィールパス」の末尾に注目

smart-google-chrome.sh

URL を見て開きたい Profile を判別させるために、こんなシェルスクリプトを書いてみました。

#!/bin/zsh

p1_website_regexs=(
  '^[http?s://]?blog\.arthur1\.dev'
)

# 引数指定がない場合は通常通り Chrome を開く
if [[ $# -eq 0 ]]; then
  open -na "Google Chrome"
  exit 0
fi

# 引数がある場合には p1_website_regexs にマッチするなら Profile 1 で開く
for regex in $p1_website_regexs; do
  if [[ $1 =~ $regex ]]; then
    open -na "Google Chrome" --args $1 --profile-directory="Profile 1"
    exit 0
  fi
done

# どれにもマッチしなかったので、profile を指定せず開く
open -na "Google Chrome" --args $1

以下のようにスクリプトを指定すると、引数に渡した Web ページが Chrome で開きます。

smart-google-chrome.sh https://blog.arthur1.dev

このとき、URL が p1_website_regexs 配列に指定した正規表現にマッチするならば、Profile 1 を明示的に指定して開く、という挙動になります。

Automator でアプリ化も...

macOS には、Automator という地味に便利な仕組みがあります。Automator を使うと、シェルスクリプトをアプリケーションのように動かすことができます。

これにより、作ったスクリプトをアプリ化したものをデフォルトブラウザとして指定すれば、URL をクリックした時に自分が開きたい profile でページを開く最高体験ができるのでは、と考えました。

しかし、作ったものをデフォルトブラウザに指定することはできませんでした。Xcode を使ってきちんと mac のアプリとして作らないとブラウザとして認識してもらえないようです。

stackoverflow.com

車輪の再開発回避

仕方ないから Swift 入門するか、と思って諦めていたとき、社の先輩が「それ、Choosy というアプリでできそう」と教えてくれました。

choosy.app

これがまさに自分が欲しかったものそのものでした。どのアプリから開いたリンクか、URLの文字列が何から始まるか、などの条件に応じて、どのブラウザ(profile 指定も可能)で開くかというルールを自由に設定できます。

また、ルールにマッチしなければ、ブラウザを開く前にポップアップが表示されどのブラウザかを選択する、といったことも可能です。

Choosy はブラウザのプロキシアプリケーション的な存在なので、これをデフォルトブラウザにして生活します。

シェアウェア($10)ではありますが、自分は気に入ったので課金しようと思います。

まとめ

profile を使い分けている方は choosy を使うとペインが解消されるかも?という情報でした。