何もしないスクリプトが実現する徐々に進化する自動化の秘訣とは
引用元:https://news.ycombinator.com/item?id=42976698
このアプローチ大好き!プロセス周りのインターフェースを定義する別の方法だと思うんだ。手動でも自動でもプロセスは同じインターフェースを使えるから、自動化のステップにとても強力。Google Sheetsを手動で入力してスクリプトで自動化したり、Jiraチケットを自動で処理するのに使ったことがある。面倒な部分を自動化しても、完全にやらなくて済むのがいいよね。
自分的には、プロセスをスクリプトとして徐々に組み込むことで、プロセスを食べるシステムじゃなくて、プロセスの周りに構築されたシステムになると思ってる。共通のタスクを自動化するスクリプトのカタログには賛成だけど、それが本番サービスに呼ばれ始めた瞬間、大量の技術的負債が蓄積されるんだよ。人間中心のプロセスがシステムにコーディファイされるから、分割するのが不可能になるからね。
あなたが想像してることがよくわからないよ。>”本番サービスでスクリプトが呼ばれることはない”って、手動ステップのスクリプトは無理じゃない?それに、システムの変更は全然可能だよ。パッケージのスクリプトと同じことだから。完全自動化は問題を増やすだけだし、ゼロ自動化も変だと思うんだ。
>”本番サービスで呼ばれることはない”って言ってるけど、使い方として手順に組み込むことはできるよ。自動化の入り口として、ワークフロー管理システムに組み込んでユーザーや他のシステムイベントと連携して、タスクを管理できるようにするのが自然な流れだよ。人間の作業もコンポーネント化できて、リファクタリングが楽になるよ。
記事のポイントは、後で実際にそのコマンドを実行するようにスクリプトを修正できることだよ。自立した良いスクリプトなら、本番サービスから呼ばれることになると思う。プログラマーは退屈な作業を嫌がるから、次世代のために複雑にする方が面倒なんだ。
自動化や修正は賛成だけど、スクリプトが本番サービスから呼ばれる時点で不安だな。部分的自動化の選択肢はゼロか完全自動化しかないから、完全自動化も問題だよね。自動化した部分が本番で使われるリスクが気になるんだ。
どうやってドゥ・ナッシングスクリプトが本番から呼ばれるの?手動じゃ無理でしょ。まあ、OPのブログはプログラマー版のSOPだと思うよ。SOPはいいけど、不要になったら変えればいいだけ。
Bashスクリプトは、ビルドオーケストレーションシステムよりも問題が少ないよ。ポータブルで、依存関係も少ない。大体、インストールの時にはコマンドをBashスクリプトにして実行すればいいし、分けたいなら好きなように分けられる。LinuxやMacOSの人に渡すのも良いことだね。
前のアプローチはこうだった:1)プロセスをそのままキャッチする 2)プロセスをテストクリアさせる 3)自動化できるようにする。3と4と並行して、- プロセスをできるだけ多くの人に使ってもらう - 実際の誤用を見てプロセスを調整する 4)自動化する。ステップ1と2はみんな賛成だし、ほとんどの人が4に賛成するけど、3をやると4への理解が増える。
>”プロセスの頭かお尻を自動化できるならいいけど…”って、もう少し自分のアプローチを説明すればよかったね。SheetsとかJiraとかCLIの選択は、今のプロセスに合わせるだけなんだ。開発環境はCLIだけど、ビジネスプロセスはJiraって流れだから。人にCLIツールをインストールさせる必要はないし、手動のステップをやるのは彼らじゃないからね。プロセスを一連の明確なステップにして、自動化できるようにするのがポイントだよ。
ギグルテストって何?
SEI能力成熟モデルでは、プロセスを書いてるだけでレベル1に達成できるんだよね。ギグルテストはビジネス用語の一つで、”これを真顔で言える?”ってやつ。意外に多くのことを排除できる。書くのは簡単でも、目を合わせて言うのは難しい。
censoriousは他人に厳しい批判的な意味みたい。彼らが言いたかったのはおそらく”censoriously”で、要は他人の反応を気にしておかしなプロセスを取り除いたり修正したりすることだと思う。
彼らは”scenario”と言いたかったんじゃないかな。
そう、それはオートコンプリートのバグで、修正が間に合わなかったんだ。”scenarios”なんだよね。
反復作業には無限の金は必要ないし、こういう仕事はそれ以上の価値を生むよ。最近使った時、チームを解放してテックデット問題に取り組ませたんだ。大人のプログラマは、自分が何も指示されてない時に取り組むべきことを四つは考えられるべきだと思う。これはその一部で、目に見える改善が見えたときにはストーリーをもらえることが多い。プロセスの修正は斧を研ぐ作業だよ。文句を言うだけの人には同情する。
俺にとってこれはJupyterノートブックを使って共有するチャンスでもあるね。物事を説明したり、雛形や例を提供するのがいい。ノートブックを使う文書システムがあれば最高だと思うけど、Cloud SaaSのConfluenceには重すぎて新しいレイヤーとして追加できないし、現状でもエスカレーションの機会が多すぎる。
‘Zen and the Art of Motorcycle Maintenance’が見えてきた感じだ。アプローチはConfluenceの指示ページを半インタラクティブなウォークスルーに置き換えて、テスト自動化は過剰に調整されたXpathや文書化されていないステップの塊から始まるんだ。アプリが変わるたびに再発見されるから、早く実行できて、どうしてそうなったかも理解できるところまで行きたいね。
スクリプトが既にコマンドのことをやる方がいいな。ユーザーに‘コマンドを実行しますか?(y/N)?’って確認すればいいし、端末間のコピペなんてやりたくない。手動でやることがコマンドになってない時は‘fooのメールアドレスを探してここにペーストして’みたいに促してほしいな。
そのポイントを自動化できればいいんだ。やらないことを選べるのが、do nothingスクリプトの重要なセールスポイント。‘やりすぎスクリプト’は1Passwordの管理に追われてしまって、ドキュメントは単なる何もしないスクリプトでチェックリストを進めないから。
要するに、始めるための心理学的なトリックなんだ。これを使うことでコマンドを実行しなくても助けになるってことが言いたいんじゃない。確かにコマンドができた瞬間に実行させてもいいんだけど、記事はそれが間違ってるとは言ってないよ。 すぐに‘機能的’だけど‘最適’ではないところにたどり着くことがあるね。その改善は、違う人が必要だと感じた時に少しずつ追加できるから。 しばしば最適である必要はないんだ。機能的プロセスが月に1回5分かかるだけなら、最適化に5時間以上かけられないよ。 文化の変化を望んでる時とか、‘誰でもこれができるし、奨励されている’って文化を伝えたい時には、時間を節約しないことを自動化する意味がある場合もあると思う。 >端末間でコピペなんてやりたくない。これがこのアプローチのポイントなんだ。予算が足りないメンテナンス手順をスクリプトにするインセンティブを提供することだと思う。Jupyter notebooksの方が、この役割に向いてると思うよ。Markdownのウィキをスクリプトにして1クリックで実行できるから。 面白いアプローチだね。ただ、SSHキーのProvisioningの例は、その会社でのやり方が不安全だったことを示している。ユーザーが自分で秘密鍵を生成して、公開鍵だけをsysadminに渡すべきだよ。1Passwordのステップ自体が不要なんだ。 未熟なユーザーに自身で鍵を管理させるのは、あまり安全とは言えないし、それがスクリプトに移行する理由なんだよ。 実際、ユーザーは自分でプライベートキーを生成すべきで、公開キーを管理者に渡してシステムにアクセスを許可してもらうんだ。これは実装が面倒だと思ってたけど、SSHの証明書認証に切り替えたら、公開キーを移動させる必要がなくなって、すごくシンプルになったよ! 証明書にはプライベートキーと公開キーがあって、プライベートキーは秘密に、公開キーは配るってことは、技術的にも組織的にもどう違うのかな?実際はどうやってやってるの? サーバーにはたった一つの公開キーしかインストールされていなくて、そのキーがどこでも同じなんだ。ユーザーには短命の証明書を生成する自己サービスシステムがある。 もう少し具体的に教えてよ。サーバーにはどの公開キーがインストールされてて、どんな自己サービスシステムがあって、どうやって証明書を生成するの?ユーザーはどうやってそれを使うの?自己サービスシステムへの認証はユーザー名とパスワード?SSHサーバーに直接それを使えばよくない? 企業の証明書をサーバーに入れるんだ。管理者がユーザー用のキーを手動で生成して送るか、自己サービスシステムが生成してユーザーがダウンロードする。ユーザーは通常通りSSHキーを使い、サーバーはそのキーが署名されているかチェックする。自己サービスシステムは会社のシングルサインオンを使ってるけど、SSHサーバーはできないし、LDAPを設定するのはすごく面倒なんだ。 普通のSSH公開キーをLDAPに入れることもできるし、これはかなり広くサポートされてるよ。 それが本当に基準なの?ITはプライベートキーを持つ仕事用のマシンの全てを管理してると思うけど。パスワードとは違うけど、プライベートキーはマシンに保管されてるんだよ。 去年初めて試してみたんだけど、ツールチェーンにバグがあって、ホットフィックスのためのランブックが普通のリリースプロセスの倍の複雑さになっちゃった。もっと簡単に使えるようになったし、頑張ってた信用もあまりなかったけど、世代1の問題だけでなく、エピックの最終段階でも使われた。たくさんのテクニカルデットに取り組めたし、自動化を進められたんだ。 タスクの自動化のためのエネルギーのハードルを下げるってことなんだよね。それならDo-nothingスクリプトは最終的には何かをする自動化ステップを持つべきなの?将来の自動化のためのプレースホルダーって感じだけど、手軽に初めて取り組むにはいいバランスだと思う。共有してくれてありがとう! うん。”各ステップが関数にカプセル化されてるから、特定のステップのテキストを自動的に動作するコードに置き換えられる。” class Foo(object): だけど、ウザい抽象化なしでどう生き残るの? 元のアプローチの利点は、後でプライベートなメソッドを追加できるところだよ。こっちのアプローチだと、新しい関数をグローバルレベルで追加することになって、関数が増えると依存関係が分かりにくくなるよ。 それは関数でもできるし、__call__を持つクラスにすればいい。必要ないけど、そういうスクリプトには。 関数内部でプライベートな関数を作ることもできるけど、 こんなのやめとけ、bar()のテストが大変になるだけだ。最初のコードはユニットテストに入れとけ、何度でも実行できるように。テストを捨てるな! そうそう、あんまりちゃんと説明できてなかったかも。インラインバージョンを推奨してるだけで、一般的にはネストした関数はあんまりオススメじゃないと思う。小さすぎてユニットテストする価値がない時や、barがfooから返される場合は大丈夫だけど。 笑っちゃう、Brain Willの動画思い出すわ。 すごいけど、中断できないのがね。事前に全ステップを示して、それを進めながらチェックできたらいいな。大きな視点で準備するのも時には良いし、ファイルにログを残せたらサマリーになる。もっと改善の余地がある、だから一番シンプルな解決策が一番いいかも。 もっと良いCLIライブラリを使えば、チェックリストや各ステージの実行出力を表示できるのがいいよね。でもさ、何もしないシェルスクリプトは始めやすくて、すぐに完成できるから、そっちに時間を使う価値があると思う。TUIライブラリを選んだり、どう構造化するかで、楽しいけど生産的じゃない泥沼にハマるかも。 >でも中断できないってのが問題だよね! 今は、実際にはただの小さいスニペットが集まったMakefileのために、Justを使ってるんだけど、それがすごく良い感じだよ。 Justって何? 毎年のタスクに対して、途中で中断できるように永続的な状態を保持してるんだ。たとえば、 この記事への実際の批判なの?それとも単なる疑問?一番シンプルな解決策は何なのか気になるな。 シンプルな解決策は、記事に書いてあることをそのままやって、余計なことはしないことだと思う。それがそのコメントの終わりにも意味されてたと思うよ。 そう、これが私の言いたかったこと。明確にしてなくてごめんね。でも、これをObsidianでやるかな。 なるほど、その通りだね。部分的な自動化を設定することを考えると、シンプルに保って機能させることを常にリマインドしてる。特に似たようなフレームワークが他のプロセスにあったりすると、新しいプロセスにそれを使わせるのが、最初から始めるよりもずっと時間がかかるのは本当に難しい。 うん、誤って違うメールアドレスを入れるとどうなるのって感じだよね。その場合、スクリプトを最初からやり直さなきゃいけないの?スクリプトのロックインって痛いポイントになることがある。 過去の議論(コメントたくさん): このアプローチのファンだよ!いろんなプロジェクトで成功してる。特にお気に入りは、3千万ドルの手術ロボットで、”人間の要因”で失敗したやつだね。 具体例とか経験やアドバイスをもう少しシェアしてもらえないかな?他の人も興味あると思うし、法律事務所でもこのアプローチをどう使えるか考えたい! これって主にコードベースのセットアップスクリプトとかだと思うんだけど、READMEに指示を書いたりして、チェックリストを使って進めるといいよね。自動化は全然難しくないし、まずはチェックリストから始めて、少しずつ忙しい作業を減らすことができる。 このアプローチ好きだなー。一段階ずつ開発して一つずつテストするのに役立つ気がするんだ。スクリプトContextでは型の整合性が難しいけど、順次実行されるから問題ないと思う。 理論的にはいいけど、実際にはうまくいかないかも。繰り返し同じ作業をする人がいると、何もしてないスクリプトはすぐに使わなくなるかも。実際の業務で使わせるのは難しいよね。 自動化できる部分もあったり、確認できる手作業もあるから、急に”何かをするスクリプト”になるかも。 このドキュメントでは期待される出力も記載しておくといいと思う。そうすれば、プロセスがズレたときに分かりやすいし、自動化してもテスト可能になる。 私はこれに近い形でSOPを書いてきた。今後は、「Quick Run」セクションを追加して、細かい説明抜きで作業できるようにしたい。また、プロセスの擬似コードを共有するドキュメントも作りたいな。 ヘッドレスでインタラクティブじゃないGentooインストーラーを作ったよ。Gentooハンドブックに従って変更して、それを元に同僚が全部まとめたんだ。今でもAWSのGentooイメージをブートストラップできると思う。 この手法は、新しいプログラマーを教える時にも使われる擬似コードとも呼ばれるんだ。残念ながら、初学者のイメージが強いせいで擬似コードはあまり評価されないけど。全てのエンジニアリングは英語をコードに翻訳する作業だし、複雑な操作も英語とコードの間にあるステップで分かりやすくできるんだ。この記事ではPythonが使われてるけど、重要な部分は英語を使ってる。実際のところ、「何もしない」スクリプトは擬似コードをそのまま残してprintで包んだものなんだ。 あなたの言いたいことは分かるけど、賛成できないな。擬似コードはコンパイルできないテキストで、コンピュータの機能を説明するためのもの。一方で、これは人間の機能を説明するために使われるコンパイル可能なコードなんだ。つまり、逆の問題を解決していることになるね。 擬似コードが悪く言われるのは聞いたことがないな。アーキテクチャの議論や決定文書、コメントなどに役立つし、名前が出ることは少ないけど。Geohotが『Pythonは擬似コードを書いているように感じるから人気がある』と言ってるのも同意だよ! この手法はいろいろな名前で呼ばれてるね。元々はチェックリストって呼ばれていたみたい。昔の人たちは紙に書いて一歩ずつ作業を進めていたんだ。npmパッケージが待ちきれない。/s これいいね!メンタルでステップを定義するのを促してくれる。次のステップは各ステップの「入力」と「出力」を定義することかな。次には各ステップが失敗した時の「対処法」の定義も重要だと思う。それができれば、実際の自動化に向けてちゃんとしたアウトラインが出来上がるはず。これがあれば、回避するために一つの長い関数をリファクタリングする必要も少なくなるんだ。 著者は俺の友達Jackのトークを観るべきだね:Stop Writing Classes: https://youtu.be/o9pEzgHorH0?si=FgZqFGQNQUU2iREQ 動画を見る価値はないよ、長いブログの延長みたいなものだから、数文で要約できるし、15分を無駄にしたと後悔してる。GPが言いたいことに関係する部分は、>「一つのメソッド(またはメソッドとinitをラップするクラスを使うな)」だね。これはこの記事には無関係だけど、クラスは成長することが期待されているんだ。クラスを使うことで、他の手順に移動しやすくなって、各クラスは同じrunメソッドを持つことでインターフェースとして機能する。と言いたいことは理解できるけど、文脈に応じて考えるべきだね。 これはそのコードに関係ある?キャリアの中で、潜在的な将来の使用ケースに対する過剰設計があまりにも多く、結局痛みと苦しみを引き起こしてきた経験があるよ。その未来の使用ケースは実際には起こらないことが多いし、友達のRaymondが言ってた『罪を犯すのを止めろ』って言葉を思い出す。 このケースでは関係ないかな。スクリプトは最終的にもっと統合されて、何かをするようになるはずだから、その時にはメインの機能をあまり変えずに、それぞれのクラスの中で作業したいからね。じゃあ、直接関数を使わないのは何で?時にはClean-Codeに従った関数にするには複雑すぎることもあるし、標準化すればメンテナンスが少なくて済むし、機能がシンプルだと思ったけど、実はそうじゃなかったとわかった時の再作業も減るから。 タイトルは要点をしっかり伝えてると思う! うん、これ、特に経験が少ない開発者には役立つかもね。抽象化を入れがちな人にはぴったり。実際、2人の開発チームにこれを勧めたら、かなり価値があったみたい。2人とも経験者だけど、一人は手続き型、もう一人はオブジェクト指向に偏ってて、もめてたから、これをきっかけにオブジェクト指向が適切な場面について話せたんだ。 One Note がこういうのに役立つね。必ずしも無作為なスクリプトである必要はなくて、チェックボックスを使ったりプロセスのテンプレートページを作って、右クリックで複製したり、プロセスの進行具合を追跡するのに使えるんだ。自分の場合、ほとんど何かをじっくり終わらせることができないから、短時間で終わらせられるものじゃないと無理だから、助かるよ。もっとコメントを表示(1)
def run(self, context): …
Pythonには実行するためだけのメソッドを持つオブジェクトがあって、それが関数だよ。
def foo(context): …もっとコメントを表示(2)
def foo(context):
def bar(x):
return x*2
baz = bar(context)
これって高階関数によく使われるけど、他のケースでも適度に使うと役立つ。ただし、特定の関数からしか呼ばれないなら、そのコードをインライン化した方がいいかも。
https://www.youtube.com/watch?v=QM1iUe6IofM
彼は要らない抽象化について文句言ってるところがあるよ。単純なコードを示したりもしてる。
この点に触れてくれて嬉しい!私はBashスクリプトの代わりにMakefileを使ってるんだ。各ステップがルールであり、*.doneファイルを生成してて、いつでも中断して修正できるし、make
で再開できる。けどMakefileを書くのが面倒なんだよね。もっと良い解決策ってある?./do-the-thing.sh 2025
って実行して、2025のディレクトリを作って、進捗を管理する。最初のステップが終わったら、2025/first-stepファイルを触るんだ。スクリプトが落ちたり中断したら、そのファイルをチェックして、もしスクリプトに変更があったら、状態を失わず修正できるのがいいね。
https://news.ycombinator.com/item?id=29083367
- 3年前(230件のコメント)
https://news.ycombinator.com/item?id=20495739
- 6年前(124件のコメント)もっとコメントを表示(3)
2. ランブックを自動化する
3. ランブックを削除する
これって#2を繰り返し実現するための手法なんだ。