自動ビルド

Flmelinkに記事を書いたら、自動でビルドするようにしたい。FlamelinkはWebhookに対応しているのだが無料プランだと使用できない。
しかし、無料プランでもできる方法を考えた。
  1. Flamelinkで書き込み
  2. Firestoreでwriteトリガー発火
  3. CloudFunctionsでビルドトリガー発火
  4. CloudBuildでビルド
  5. FirebaseHostingにデプロイ

図にすると以下のようになる。


  1. Flamelinkで書き込み

普通に書き込みするだけで次のステップに移りたい
  1. Firestoreでwriteトリガー発火

CloudFunctionでwriteトリガーを検知して、ビルドトリガーを発火させる。
 
index.ts
import * as functions from "firebase-functions";
import cloudbuild from "./cloudbuild";

const REGION = "asia-northeast1";

exports.modifyContent = functions.region(REGION).firestore
    .document("/fl_content/{content_id}")
    .onWrite((change, context) => {
        cloudbuild("blog-2bc1d", "build-page", "master");
    });

  1. CloudFunctionsでビルドトリガー発火

CloudBuildでビルドトリガーを発火させている。
https://github.com/googleapis/nodejs-cloudbuild/blob/master/samples/quickstart.js
をちょっと変えただけ。
あとはCloudBuildのコンソールでビルドトリガーを設定すればOK
cloudbuild.ts
"use strict";

// [START cloudbuild_quickstart]
/**
 * @param {string} projectId Your Google Cloud Platform project ID
 * @param {string} triggerId  UUID for build trigger.
 * @param {string} branchName  Branch to run build against.
 */
export default async function setBuildTrigger(
    projectId = "YOUR_PROJECT_ID", // Your Google Cloud Platform project ID
    triggerId = "YOUR_TRIGGER_ID", // UUID for build trigger.
    branchName = "BRANCH_TO_BUILD" // Branch to run build against.
) {
    // Imports the Google Cloud client library
    const { CloudBuildClient } = require("@google-cloud/cloudbuild");

    // Creates a client
    const cb = new CloudBuildClient();

    // Starts a build against the branch provided.
    const [resp] = await cb.runBuildTrigger({
        projectId,
        triggerId,
        source: {
            projectId,
            dir: "./",
            branchName,
        },
    });
    console.info(`triggered build for ${triggerId}`);
    const [build] = await resp.promise();

    const STATUS_LOOKUP = [
        "UNKNOWN",
        "Queued",
        "Working",
        "Success",
        "Failure",
        "Error",
        "Timeout",
        "Cancelled",
    ];
    for (const step of build.steps) {
        console.info(
            `step:\n\tname: ${step.name}\n\tstatus: ${STATUS_LOOKUP[build.status]}`
        );
    }
}
// [END cloudbuild_quickstart]

// quickstartはコマンドラインから実行するため以下コメントアウト
// const args = process.argv.slice(2);
// setBuildTrigger(...args).catch(console.error);

  1. CloudBuildでビルド

  2. FirebaseHostingにデプロイ

以下のビルド構成ファイルをプロジェクトのルートに配置
ビルドとデプロイが行われる
cloudbuild.json
{
  "steps": [
    {
      "name": "gcr.io/cloud-builders/npm",
      "args": [
        "install"
      ],
      "dir": "/workspace/functions"
    },
    {
      "name": "gcr.io/cloud-builders/npm",
      "args": [
        "run",
        "deploy"
      ],
      "dir": "/workspace/functions"
    }
  ]
}