こちらの記事でまとめたように、 kintone のアプリに対してカスタマイズファイルをアップロードできます。
ですが、自分の場合だと、普段は Live Server 設定で VSCode 上でデバッグして、ある程度開発が終わったら、一度カスタマイズファイルとしてアップロードして、動作確認&本番環境への反映、となるので、カスタマイズファイルアップロード後に不具合があると Live Server 設定で再度デバッグ等を行うことになります。
ということで、複数アプリのカスタマイズファイル設定を Live Server を使う設定に戻すための js を作ってみました。
という記事だったんですが、最終的な結論としては、 kintone の customize-uploader が対応してくれていたので、以下の作業は不要になりました。まあ、せっかくなので、残しておきますが、 customize-uploader を使った方法はこちらで紹介しておきます。
作成
アプリの設定を変更するのは kintone REST API client を利用します。
PS D:\work\tmp\kintone_tutorial\revert_live_server> npm install --save-dev @kintone/rest-api-client up to date, audited 301 packages in 2s 71 packages are looking for funding run `npm fund` for details found 0 vulnerabilities PS D:\work\tmp\kintone_tutorial\revert_live_server>
js ファイルの主な処理は、次のようになります。
- 最初に app.getDeployStatus でアプリのステータスを取得します
- ステータスが正しく取得されて、それらがすべて SUCCESS になっていることを確認します
- 確認出来たら、app.updateAppCustomize でアプリのカスタマイズ設定を Live Server のURLに変更します。
- 最後に、 app.deployApp を呼び出して、変更を反映します。
こういう流れになった理由については、後述してある補足もご覧ください。
最終的に作成した js ファイルはこんな感じです(こちらに書いたように ESModule にしています)。
#!/bin/bash/env node "use strict"; import process from "node:process"; import {parseArgs} from "node:util"; import {KintoneRestAPIClient} from "@kintone/rest-api-client"; import {DEV_ENV_APP_ID} from "../src/lib/const/AppIdConfig.js"; const DEV_ENV_URL = "https://kintoneのドメイン名.cybozu.com"; const WEBPACK_DIST_URL = "https://localhost:5500/dist/"; // webpack.config.js の entry のキーに対応したファイル名を記述 const APP_JS_DEV = { sample_app: "kintone-revert-test.js", }; function usage() { console.log("Usage: node kintone_revert_localserver.js [-h] username password"); console.log(" -h: display help"); console.log(" username: kintone login username"); console.log(" password: password for username"); } function parseCliArgs() { const options = { help: { type: "boolean", short: "h", }, }; const {values, positionals} = parseArgs({ options: options, allowPositionals: true, }); // console.log(values); // console.log(positionals); if (values.help) { usage(); return false; } if (positionals.length !== 2) { console.warn("invalid parameters"); usage(); return false; } return positionals; } /** * js カスタマイズ設定を、ローカルサーバーに戻す * @param {*} client */ async function revertCustomizeToLocalServer(client) { Object.entries(APP_JS_DEV).forEach(async (elm) => { const param = { app: DEV_ENV_APP_ID[elm[0]], desktop: { js: [ { type: "URL", url: WEBPACK_DIST_URL + elm[1], }, ], }, }; try { await client.app.updateAppCustomize(param); } catch (error) { console.error("failed to revert js customize to localserver, param:" + JSON.stringify(param)); console.error(error); } }); } /** * アプリの更新状況を取得 * @param {*} client */ async function getDeployStatuses(client) { const app_ids = Object.keys(APP_JS_DEV).map((elm) => { return DEV_ENV_APP_ID[elm]; }); const param = { apps: app_ids, }; try { const status = await client.app.getDeployStatus(param); return status; } catch (error) { console.error("failed to get app deploy status, param:" + JSON.stringify(param)); console.error(error); } return undefined; } /** * 変更したアプリ設定を更新 * * 変更した全てのアプリを同時に指定して、APIを呼び出す * @param {*} client */ async function updateAppSettings(client) { const app_ids = Object.keys(APP_JS_DEV).map((elm) => { return { app: DEV_ENV_APP_ID[elm], }; }); const param = { apps: app_ids, revert: false, }; try { await client.app.deployApp(param); } catch (error) { console.error("failed to update app settings, param:" + JSON.stringify(param)); console.error(error); } } /** ///////////////////////////// */ // 以下、メイン処理 const parsed = parseCliArgs(); if (!parsed) { process.exit(1); } const client = new KintoneRestAPIClient({ baseUrl: DEV_ENV_URL, auth: { username: parsed[0], password: parsed[1], }, }); // アプリのデプロイ状況をチェック console.log("deploy status, before update:"); const status = await getDeployStatuses(client); console.log(JSON.stringify(status)); if (!status) { console.warn("status cannot get. so update process stopped."); process.exit(1); } if ( status.apps.some((elm) => { return elm.status !== "SUCCESS"; }) ) { console.warn("some app is not deploied. so update process stopped."); process.exit(1); } console.log("start process to revert to localserver's URL"); // カスタマイズファイルの設定を localserver に戻す await revertCustomizeToLocalServer(client); // アプリの変更を反映 console.log("update app settings"); await updateAppSettings(client); console.log("deploy status, after update:"); console.log(JSON.stringify(await getDeployStatuses(client))); console.log("finish process to revert");
補足
実は上記の処理において、 getDeployStatus を呼ばずに、 deployApp を適用すると
KintoneRestAPIError: [520] [GAIA_DA02] データベースのロックに失敗したため、変更を保存できませんでした。時間をおいて再度お試しください。 (mlTC5KYXuKy0DOpUvvxs)
といったメッセージが出てきます。
でも、一度 getDeployStatus を実行後に、 deployApp を実行すると、問題なく完了します。 getDeployStatus を呼び出すタイミングは、updateAppCustomize 実行前でも後でも変わらず、大丈夫でした。
ドキュメントのどこを見ても、 deployApp の前に getDeployStatus を実行する必要がある、なんて記述はないようですが、何かあるんでしょうかね?
とりあえず実行できないと困るので、上記のような処理にしています。
試してみる
上記を作成したら、試してみます。
src/lib/const に AppIdConfig.js というファイルを用意して、
/** * アプリケーションID を定義するモジュール */ // 開発環境 const APP_ID_DEV = { sample_app: nnn, }; // ステージング環境 const APP_ID_STAGE = { sample_app: nnn, }; // 本番環境 const APP_ID_PROD = { sample_app: nnn, }; /** * 複数環境におけるアプリ ID のオブジェクト */ export const environments = { "開発環境.cybozu.com": [APP_ID_DEV], "本番環境.cybozu.com": [APP_ID_STAGE, APP_ID_PROD], }; /** * 開発環境のアプリ ID * * 開発環境には1つしかスペースがない前提 */ export const DEV_ENV_APP_ID = environments["開発環境.cybozu.com"][0];
こんな感じに、アプリ名(sample_app)とそのアプリIDを対応させておきます。このようなファイルを利用している理由は、もともとこのファイルは、カスタマイズ時に環境ごとにアプリIDを切り替えるために定義していたものになります(こちらの記事で触れています)。
これを利用して、アプリIDを特定するということを行っています。
実行するには、
PS D:\work\tmp\kintone_tutorial\revert_live_server> node .\bin\kintone_revert_localserver.js ユーザー名 パスワード deploy status, before update: {"apps":[{"app":"nnn","status":"SUCCESS"}]} start process to revert to localserver's URL update app settings deploy status, after update: {"apps":[{"app":"nnn","status":"PROCESSING"}]} finish process to revert PS D:\work\tmp\kintone_tutorial\revert_live_server>
のように呼び出せばできます。
customize-uploader
さあ、これで Live Server に簡単に戻せるな、と思っていたところ、ふと気がついたのですが、 customize-uploader の js ファイルとして URL を指定すれば、切り替えられるんじゃないか?という疑問が出てきました。
早速、試してみます。
dest/customize-manifest-revert.json としてURLを記載しておきます。
{ "app": "nnn", "scope": "ALL", "desktop": { "js": ["https://localhost:5500/dist/kintone-revert-test.js"], "css": [] }, "mobile": { "js": [], "css": [] } }
これをコマンドラインで指定します。
PS D:\work\tmp\kintone_tutorial\revert_live_server> npx kintone-customize-uploader --base-url https://kintoneのドメイン名.cybozu.com --username ユーザー名 --password パスワード dest/customize-manifest-revert.json カスタマイズのアップロードを開始します JavaScript/CSS ファイルをアップロードしました! JavaScript/CSS カスタマイズの設定を変更しました! 運用環境への反映の完了を待っています... 運用環境への反映の完了を待っています... 運用環境への反映の完了を待っています... 運用環境に反映しました! PS D:\work\tmp\kintone_tutorial\revert_live_server>
あ、できてしまいました・・・。kintone 側のアプリの設定を見ても、ちゃんと切り替わっています。
ということで、上記のスクリプトは無駄になってしまいましたが、一応残しておきますね。
まとめ
上記のように customize-uploader で Live Server に戻せるのに気が付いた後、 customize-uploader のリポジトリをみたら、ちゃんとサンプルに URL を含んだものが載ってました。
ドキュメントはちゃんと確認しないといけませんね。