GAEのデプロイが成功したらGopherが飛ぶようにして開発モチベーションを維持しよう!


まとめ

  • 趣味開発のモチベーション維持のため、デプロイ時に通知してくれるプログラムを作った。
  • ただ通知するだけだと愛想ないので、Gopherを飛ばしてみました。
  • Gopher 可愛い! コミットするのが楽しみになった!気がする

はじめに

開発のモチベーションを維持するのは難しい。

はじめは発想と情熱に任せてガリガリコードを書いていても、ある程度進んでくると
次第にモチベーションが低下してしまうものです。
恒常性維持機能の為せる業か、理由はわかりませんが、開発者なら経験したことがあるでしょう。

現在、私は趣味で Google App Engine 上で動くバックエンドAPIサーバを作成していますが
モチベーションや集中力の低下を感じていました。


そこで以前何かの雑誌で読んだ、開発メンバーのモチベーションを高める方法を実践しました。
方法はいたって簡単です。

進捗や変化を大袈裟に見える化する

記事では、開発チームのモチベーション維持のため、以下のような方法が紹介されていました。

  • 不具合発見時にパトライトを光らせる
  • リリース時に音楽を流す

大袈裟に見える化することで、リフレッシュ効果や同じ作業の繰り返し感をなくせるとのことでした。

そこで、GAEへのデプロイが成功したら、Windowsの画面上にGopherを飛ばそうと思いつきました。

The Go gopher was designed by Renée French.

やることが決まったら実装です。

実装

環境
Windows 10

Cloud Buildの実行状況を取得する

GAEへのデプロイにはCloud Buildを利用しているので、Cloud Buildの実行状況を取得します。
実行状況はCloud Pub/Subcloud-buildsというトピックにメッセージが送られます。

詳細は公式ドキュメントに詳しく書いてあります。
ビルド通知の送信 | Cloud Build

公式ドキュメントでは cloud-builds は自動で作成されるとありましたが
私のプロジェクトでは作成されていませんでした。
同名で作成したところ、メッセージが配送されるようになりました。

Pub/Subからメッセージを取得する

Cloud Pub/Sub からメッセージを取得するプログラムを作成します。
言語はGolangで作成しました。
書いたプログラムが基本的にWindowsでもLinuxでも動くのがGolangの良さですね。
pubsub - GoDoc

ドキュメントを参考に書きました。 まごうことなき糞コードです


package main

import (
    "os/exec"
    "context"
    "google.golang.org/api/option"
    "cloud.google.com/go/pubsub"
    "encoding/json"
    "fmt"
)

const ProjectName string = ""        // GCP プロジェクト名
const KeyPath string = ""            // 鍵ファイルパス
const SubscriptionName string = ""   // Pub/Subのサブスクリプション名
const RepositoryName string = ""     // ビルドを実行するリポジトリ名

// 成功時に実行するコマンド
const SuccessCommand string = "../fly.exe"
// 失敗時に実行するコマンド
const ErrorCommand string = "../panic.exe"

type BuildMessage struct {
    Id        string `json:"id"`
    ProjectId string `json:"projectId"`
    Status    string `json:"status"`
    Source    Source `json:"source"`
}
type Source struct {
    RepoSource RepoSource `json:"repoSource"`
}
type RepoSource struct {
    ProjectId  string `json:"projectId"`
    RepoName   string `json:"repoName"`
    BranchName string `json:"branchName"`
}

func main() {
    // pubsub clientの呼び出し
    ctx := context.Background()
    client, _ := pubsub.NewClient(
        ctx,
        ProjectName,
        option.WithCredentialsFile(KeyPath),
    )
    sub := client.Subscription(SubscriptionName)
    // メッセージの受信待ち受け処理
    sub.Receive(context.Background(), MessageHandler)
}

// メッセージ受信時の処理
func MessageHandler(ctx context.Context, m *pubsub.Message) {
    var message BuildMessage
    json.Unmarshal(m.Data, &message)

    // 受信確認
    m.Ack()

    // 意図したリポジトリかどうか
    if message.Source.RepoSource.RepoName != RepositoryName {
        fmt.Println("飛ばない")
        return
    }

    if message.Status == "SUCCESS" {
        fmt.Println("飛べ!!")
        exec.Command(SuccessCommand).Run()
    }

    if message.Status == "FAILURE" {
        // 失敗処理
        fmt.Println("パニック")
        exec.Command(ErrorCommand).Run()
    }
}

Gopherを動かす

Windowsのデスクトップ上でGopherを動かすコマンドはこちらを参考にしました。
本物の golang を... 本物の Gopher を、お見せしますよ。

今回はほとんどこの記事から着想を得ているといっても過言ではありません。
作者に感謝します。
デスクトップ上で飛び回るGopherも可愛いですが、
GAEへのデプロイ感を演出するため、プログラムを一部書き換え、動きを変更しました。

絵を描く

さらにデプロイ感を出すために、Gopherも飛びそうな絵に変更します。
絵を描くのには FireAlpaca を利用しました。
フリーのペイントツールですが、レイヤー機能があり初心者でもそれっぽい絵が描けました。

ゴーファー とぶ!

ついに完成したのがこちら

成し遂げたぜ!

大体一週間くらいあれこれして、ついに完成しました。
絵を書くのに大半の時間を使いました。マウスで絵を書くの難しいですね…

最後に

おわかりいただけただろうか。

大体一週間くらいあれこれして、ついに完成しました。

プログラム開発のモチベーションを高めるために一週間プログラム開発を止めているのだ。
かくも開発モチベーションを維持することは難しい……


しかし、モチベーションが上がらないときはいっそ振り切って別のことをしてしまうのも悪くないです。
その後は集中して開発に取り組めました。納期が迫っただけ