Skip to content

feat(traQ): inject config during deployment#1315

Open
uni-kakurenbo wants to merge 5 commits intomainfrom
feat/traq-config
Open

feat(traQ): inject config during deployment#1315
uni-kakurenbo wants to merge 5 commits intomainfrom
feat/traq-config

Conversation

@uni-kakurenbo
Copy link
Copy Markdown
Contributor

@uni-kakurenbo uni-kakurenbo commented Jan 1, 2026

  • 動くかわからない
  • config.json から config.js を生成して app/overried/config.js に差し込みたい

ref:

Summary by CodeRabbit

  • 新機能
    • フロントエンドの外部設定を導入しました:Firebase設定、機能フラグ(例:Qall/Search)、外部サービスリンク、認証リンク、既定チャンネルなどをカスタマイズ可能になりました。
    • 実行時に構成ファイルを上書きできる仕組みを追加し、環境ごとの設定差分を容易に反映できます。

@uni-kakurenbo uni-kakurenbo requested a review from a team as a code owner January 1, 2026 03:23
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jan 1, 2026

Diff

@@ (root level) @@
# v1/ConfigMap/preview-traq/preview-traq-config
! + one document added:
+ ---
+ apiVersion: v1
+ data:
+   config.json: |
+     {
+         "$schema": "https://raw.githubusercontent.com/traPtitech/traQ_S-UI/refs/heads/master/config.schema.json",
+         "firebase": {
+             "apiKey": "AIzaSyDee_VkrRtByJCrCZAX3nTSDPl8AaHlWfY",
+             "appId": "1:993645413001:web:b253ea3776d6cf85163c58",
+             "projectId": "traq-r",
+             "messagingSenderId": "993645413001",
+             "vapidKey": "BPHegiDotHG7TlKhoW1qvwUYjOQj1C7RgKjvw3etUJZ_4x3LWUtFVXtRANWwckJX4G2w3CVj4zwi5QNThg7DZH4"
+         },
+         "enableQall": true,
+         "enableSearch": true,
+         "services": [
+             {
+                 "label": "Portal",
+                 "iconPath": "portal.svg",
+                 "appLink": "https://portal.trap.jp/"
+             },
+             {
+                 "label": "Official Website",
+                 "iconPath": "traP.svg",
+                 "appLink": "https://trap.jp/"
+             },
+             {
+                 "label": "Wiki",
+                 "iconPath": "crowi.svg",
+                 "appLink": "https://wiki.trap.jp/"
+             },
+             {
+                 "label": "Blog Admin",
+                 "iconPath": "ghost.svg",
+                 "appLink": "https://blog-admin.trap.jp/"
+             },
+             {
+                 "label": "Drive",
+                 "iconPath": "nextcloud.svg",
+                 "appLink": "https://drive.trap.jp/"
+             },
+             {
+                 "label": "Gitea",
+                 "iconPath": "gitea.svg",
+                 "appLink": "https://git.trap.jp/"
+             },
+             {
+                 "label": "NeoShowcase",
+                 "iconPath": "neoshowcase.svg",
+                 "appLink": "https://ns.trap.jp/"
+             },
+             {
+                 "label": "HackMD",
+                 "iconPath": "hackmd.svg",
+                 "appLink": "https://md.trap.jp/"
+             },
+             {
+                 "label": "anke-to",
+                 "iconPath": "anke-to.svg",
+                 "appLink": "https://anke-to.trap.jp/"
+             },
+             {
+                 "label": "booQ",
+                 "iconPath": "booq.svg",
+                 "appLink": "https://booq.trap.jp/"
+             },
+             {
+                 "label": "knoQ",
+                 "iconPath": "knoq.svg",
+                 "appLink": "https://knoq.trap.jp/"
+             },
+             {
+                 "label": "BOT Console",
+                 "iconPath": "bot-console.svg",
+                 "appLink": "https://bot-console.trap.jp/"
+             },
+             {
+                 "label": "Jomon",
+                 "iconPath": "jomon.svg",
+                 "appLink": "https://jomon.trap.jp/"
+             },
+             {
+                 "label": "traPortfolio",
+                 "iconPath": "traPortfolio.svg",
+                 "appLink": "https://portfolio.trap.jp/"
+             },
+             {
+                 "label": "tpf-admin",
+                 "iconPath": "traPortfolio-admin.svg",
+                 "appLink": "https://portfolio-admin.trap.jp/"
+             },
+             {
+                 "label": "rucQ",
+                 "iconPath": "rucq.svg",
+                 "appLink": "https://rucq.trap.jp/"
+             },
+             {
+                 "label": "traP Collection",
+                 "iconPath": "traPCollection.svg",
+                 "appLink": "https://collection.trap.jp/"
+             }
+         ],
+         "ogpIgnoreHostNames": [
+             "wiki.trap.jp",
+             "git.trap.jp",
+             "md.trap.jp",
+             "drive.trap.jp",
+             "anke-to.trap.jp",
+             "booq.trap.jp",
+             "knoq.trap.jp",
+             "wiki.trapti.tech",
+             "git.trapti.tech",
+             "md.trapti.tech",
+             "drive.trapti.tech",
+             "jomon.trap.jp",
+             "ns.trap.jp",
+             "portfolio-admin.trap.jp",
+             "rucq.trap.jp"
+         ],
+         "wikiPageOrigin": "https://wiki.trap.jp",
+         "blogPagePrefix": "https://trap.jp/author/",
+         "auth": {
+             "resetLink": "https://portal.trap.jp/reset-password",
+             "changeLink": "https://portal.trap.jp/me/change-password",
+             "changeName": "traPortal"
+         },
+         "isRootChannelSelectableAsParentChannel": false,
+         "tooLargeFileMessage": "大きい%sの共有にはDriveを使用してください",
+         "showWidgetCopyButton": true,
+         "inlineReplyDisableChannels": [
+             "#general",
+             "#general/schedule",
+             "#general/meeting",
+             "#random",
+             "#random/wasure",
+             "#services"
+         ],
+         "iosPwaInfoLink": "https://wiki.trap.jp/SysAd/docs/traQ-S/PWA",
+         "defaultChannelId": [
+             "04ad2c18-fdcb-4c43-beef-82e8ba26ac98", // #general of q.trap.jp
+             "83afc6cc-737d-4868-9a2f-aeb7c199260e" // #general of q-dev.trapti.tech
+         ],
+         "fallbackChannelPath": "general"
+     }
+     
+ kind: ConfigMap
+ metadata:
+   name: preview-traq-config
+   namespace: preview-traq

@@ spec.template.spec @@
# apps/v1/Deployment/traq-dev/traq-frontend
! + one map entry added:
+ volumes:
+ - name: config-json
+   configMap:
+     name: traq-frontend-config-dt8g76ft5c

@@ spec.template.spec.containers.traq-frontend @@
# apps/v1/Deployment/traq-dev/traq-frontend
! + one map entry added:
+ volumeMounts:
+ - name: config-json
+   mountPath: /app/override/config.json
+   subPath: config.jsonc

@@ (root level) @@
# v1/ConfigMap/traq-dev/traq-frontend-config-dt8g76ft5c
! + one document added:
+ ---
+ apiVersion: v1
+ data:
+   config.jsonc: |
+     {
+         "$schema": "https://raw.githubusercontent.com/traPtitech/traQ_S-UI/refs/heads/master/config.schema.json",
+         "firebase": {
+             "apiKey": "AIzaSyDee_VkrRtByJCrCZAX3nTSDPl8AaHlWfY",
+             "appId": "1:993645413001:web:b253ea3776d6cf85163c58",
+             "projectId": "traq-r",
+             "messagingSenderId": "993645413001",
+             "vapidKey": "BPHegiDotHG7TlKhoW1qvwUYjOQj1C7RgKjvw3etUJZ_4x3LWUtFVXtRANWwckJX4G2w3CVj4zwi5QNThg7DZH4"
+         },
+         "enableQall": true,
+         "enableSearch": true,
+         "services": [
+             {
+                 "label": "Portal",
+                 "iconPath": "portal.svg",
+                 "appLink": "https://portal.trap.jp/"
+             },
+             {
+                 "label": "Official Website",
+                 "iconPath": "traP.svg",
+                 "appLink": "https://trap.jp/"
+             },
+             {
+                 "label": "Wiki",
+                 "iconPath": "crowi.svg",
+                 "appLink": "https://wiki.trap.jp/"
+             },
+             {
+                 "label": "Blog Admin",
+                 "iconPath": "ghost.svg",
+                 "appLink": "https://blog-admin.trap.jp/"
+             },
+             {
+                 "label": "Drive",
+                 "iconPath": "nextcloud.svg",
+                 "appLink": "https://drive.trap.jp/"
+             },
+             {
+                 "label": "Gitea",
+                 "iconPath": "gitea.svg",
+                 "appLink": "https://git.trap.jp/"
+             },
+             {
+                 "label": "NeoShowcase",
+                 "iconPath": "neoshowcase.svg",
+                 "appLink": "https://ns.trap.jp/"
+             },
+             {
+                 "label": "HackMD",
+                 "iconPath": "hackmd.svg",
+                 "appLink": "https://md.trap.jp/"
+             },
+             {
+                 "label": "anke-to",
+                 "iconPath": "anke-to.svg",
+                 "appLink": "https://anke-to.trap.jp/"
+             },
+             {
+                 "label": "booQ",
+                 "iconPath": "booq.svg",
+                 "appLink": "https://booq.trap.jp/"
+             },
+             {
+                 "label": "knoQ",
+                 "iconPath": "knoq.svg",
+                 "appLink": "https://knoq.trap.jp/"
+             },
+             {
+                 "label": "BOT Console",
+                 "iconPath": "bot-console.svg",
+                 "appLink": "https://bot-console.trap.jp/"
+             },
+             {
+                 "label": "Jomon",
+                 "iconPath": "jomon.svg",
+                 "appLink": "https://jomon.trap.jp/"
+             },
+             {
+                 "label": "traPortfolio",
+                 "iconPath": "traPortfolio.svg",
+                 "appLink": "https://portfolio.trap.jp/"
+             },
+             {
+                 "label": "tpf-admin",
+                 "iconPath": "traPortfolio-admin.svg",
+                 "appLink": "https://portfolio-admin.trap.jp/"
+             },
+             {
+                 "label": "rucQ",
+                 "iconPath": "rucq.svg",
+                 "appLink": "https://rucq.trap.jp/"
+             },
+             {
+                 "label": "traP Collection",
+                 "iconPath": "traPCollection.svg",
+                 "appLink": "https://collection.trap.jp/"
+             }
+         ],
+         "ogpIgnoreHostNames": [
+             "wiki.trap.jp",
+             "git.trap.jp",
+             "md.trap.jp",
+             "drive.trap.jp",
+             "anke-to.trap.jp",
+             "booq.trap.jp",
+             "knoq.trap.jp",
+             "wiki.trapti.tech",
+             "git.trapti.tech",
+             "md.trapti.tech",
+             "drive.trapti.tech",
+             "jomon.trap.jp",
+             "ns.trap.jp",
+             "portfolio-admin.trap.jp",
+             "rucq.trap.jp"
+         ],
+         "wikiPageOrigin": "https://wiki.trap.jp",
+         "blogPagePrefix": "https://trap.jp/author/",
+         "auth": {
+             "resetLink": "https://portal.trap.jp/reset-password",
+             "changeLink": "https://portal.trap.jp/me/change-password",
+             "changeName": "traPortal"
+         },
+         "isRootChannelSelectableAsParentChannel": false,
+         "tooLargeFileMessage": "大きい%sの共有にはDriveを使用してください",
+         "showWidgetCopyButton": true,
+         "inlineReplyDisableChannels": [
+             "#general",
+             "#general/schedule",
+             "#general/meeting",
+             "#random",
+             "#random/wasure",
+             "#services"
+         ],
+         "iosPwaInfoLink": "https://wiki.trap.jp/SysAd/docs/traQ-S/PWA",
+         "defaultChannelId": [
+             "04ad2c18-fdcb-4c43-beef-82e8ba26ac98", // #general of q.trap.jp
+             "83afc6cc-737d-4868-9a2f-aeb7c199260e" // #general of q-dev.trapti.tech
+         ],
+         "fallbackChannelPath": "general"
+     }
+     
+ kind: ConfigMap
+ metadata:
+   name: traq-frontend-config-dt8g76ft5c
+   namespace: traq-dev

@@ spec.template.spec @@
# apps/v1/Deployment/traq/traq-frontend
! + one map entry added:
+ volumes:
+ - name: config-json
+   configMap:
+     name: traq-frontend-config

@@ spec.template.spec.containers.traq-frontend @@
# apps/v1/Deployment/traq/traq-frontend
! + one map entry added:
+ volumeMounts:
+ - name: config-json
+   mountPath: /app/override/config.json
+   subPath: config.jsonc

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements config injection during deployment for the traQ frontend, enabling runtime configuration through Kubernetes ConfigMaps instead of build-time configuration. This follows the referenced issues about improving the deployment configuration pattern.

Key Changes:

  • Introduces an initContainer that converts JSON config to JavaScript at deployment time
  • Adds ConfigMap generation for both production (traq) and preview environments
  • Implements volume mounting strategy to inject the converted config into the frontend container

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
traq/frontend/kustomization.yaml Adds ConfigMap generator for traq-frontend-config from config.json
traq/frontend/deployment.yaml Adds initContainer to convert JSON config to JS and volume mounts to inject it into the frontend
traq/frontend/config.json New configuration file containing Firebase credentials, services list, and UI settings
preview-traq/kustomization.yaml Adds ConfigMap generator for preview environment using the same config.json and deployment patch
preview-traq/deployment-patch.yaml Patch to add the same config conversion initContainer and volume mounts for preview deployments

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread preview-traq/deployment-patch.yaml Outdated
Comment thread traq/frontend/config.jsonc
Comment thread traq/frontend/deployment.yaml Outdated
Comment thread preview-traq/deployment-patch.yaml Outdated
Comment thread traq/frontend/deployment.yaml Outdated
Comment thread preview-traq/deployment-patch.yaml Outdated
Comment thread traq/frontend/deployment.yaml Outdated
Comment thread preview-traq/kustomization.yaml Outdated
Comment on lines +19 to +24
patches:
- path: deployment-patch.yaml
target:
kind: Deployment
name: preview-traq-.*
namespace: preview-traq
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このpatchはkustomize build実行時に行われるため、preview-uiが生成するArgoCD Applicationにおいては行われないと思います。
これをやる場合、.common/preview-ui-templateDeploymentinitContainersをHelm Valueで指定できるようにするとできそうです。

Comment thread traq/frontend/kustomization.yaml Outdated
Comment on lines +6 to +9
configMapGenerator:
- name: traq-frontend-config
files:
- config.json
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

良さそうですが、先にtraq-devでテストして欲しいです🙏

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 076ff88a-5e45-488e-832d-c777068ac73d

📥 Commits

Reviewing files that changed from the base of the PR and between ae1a6b3 and 57de4db.

📒 Files selected for processing (2)
  • preview-traq/kustomization.yaml
  • traq/frontend/deployment.yaml
✅ Files skipped from review due to trivial changes (1)
  • preview-traq/kustomization.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • traq/frontend/deployment.yaml

📝 Walkthrough

Walkthrough

ConfigMapベースのフロントエンド設定導入と、それをマウントするためのKustomize生成・Helmテンプレート条件付きvolumeMount/volumes追加。新規設定ファイルtraq/frontend/config.jsoncを追加し、複数のデプロイ定義を更新してConfigMapをマウントするようにした。

Changes

Cohort / File(s) Summary
フロントエンド設定ファイル
traq/frontend/config.jsonc
フロントエンド用の新規設定ファイルを追加(Firebase設定、機能フラグ、外部サービスリンク、認証/チャネル関連など)。
Kustomizeジェネレータ
preview-traq/kustomization.yaml, traq-dev/frontend/kustomization.yaml
configMapGeneratorを追加し、それぞれpreview-traq-configおよびtraq-frontend-configconfig.jsonc/config.jsonから生成。disableNameSuffixHash: trueを設定。
Helmテンプレート/values
.common/preview-ui-template/templates/dashboard-deployment.yaml, preview-traq/values.yaml
.Values.containers.volumeMounts.Values.volumesが設定されている場合にのみvolumeMountsおよびpodvolumesを出力する条件を追加(ConfigMapベースのマウントをサポート)。
Kubernetesデプロイメントパッチ/マニフェスト
traq-dev/frontend/deployment-patch.yaml, traq/frontend/deployment.yaml
traq-frontendコンテナにConfigMap由来のvolumeMount/app/override/config.jsonsubPath: config.jsonc)を追加し、対応するpod-level volumesconfig-json)を追加。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed プルリクエストのタイトルは「feat(traQ): inject config during deployment」で、デプロイ時に設定を注入するというこの変更セットの主要な目的を正確に反映しており、簡潔で明確です。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/traq-config

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
.common/preview-ui-template/templates/dashboard-deployment.yaml (1)

30-37: ⚠️ Potential issue | 🟠 Major

preview 経路では PR 目的の config.js 注入がまだ実現できていません。

ここで追加しているのは ConfigMap の mount だけで、traq/frontend/deployment.yaml に入った convert-config + emptyDir による config.jsonc -> config.js 変換が preview 側にはありません。これだと preview だけ runtime config の適用経路が別になるので、Helm Values から initContainers も渡せるようにして同じ変換フローを通す必要があります。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.common/preview-ui-template/templates/dashboard-deployment.yaml around lines
30 - 37, The preview deployment only mounts the ConfigMap but omits the
init-container conversion flow (convert-config + emptyDir) used in
traq/frontend/deployment.yaml, so add support to pass initContainers from Helm
Values into the preview template and wire the same conversion flow: update the
template to include .Values.containers.initContainers (or a dedicated
.Values.initContainers) so the initContainer named convert-config and its
emptyDir volume are rendered into the preview pod spec, ensure the emptyDir
volume name used by convert-config matches the volumeMount in the main container
(same volume name as in volumes/volumeMounts), and keep existing
volumeMounts/volumes logic but include the initContainers block before
containers so preview follows the identical config.jsonc -> config.js conversion
path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@preview-traq/kustomization.yaml`:
- Around line 7-8: kustomization.yaml currently references a non-existent file
via the files entry (“config.json=../traq/frontend/config.json”); update that
reference to point to the actual file added in this PR (e.g. replace
../traq/frontend/config.json with ../traq/frontend/config.jsonc or the correct
existing path) so kustomize build can find the file; verify the files: entry in
kustomization.yaml matches the real filename and commit the change.

In `@traq/frontend/deployment.yaml`:
- Around line 24-29: The convert-config input name and file path are
inconsistent with the generator's ConfigMap key: update the converter and
volume/ConfigMap usage so both read the same filename (change the read path in
the config.js generation from /config-in/config.json to /config-in/config.jsonc
or rename the generator output key to config.json); ensure the echo line that
writes to /app/override/config.js, the volumeMount name (config-json) and the
source key produced by traq-dev/frontend/kustomization.yaml (config.jsonc) all
match the same key name so config.js is generated from the correct source.

---

Duplicate comments:
In @.common/preview-ui-template/templates/dashboard-deployment.yaml:
- Around line 30-37: The preview deployment only mounts the ConfigMap but omits
the init-container conversion flow (convert-config + emptyDir) used in
traq/frontend/deployment.yaml, so add support to pass initContainers from Helm
Values into the preview template and wire the same conversion flow: update the
template to include .Values.containers.initContainers (or a dedicated
.Values.initContainers) so the initContainer named convert-config and its
emptyDir volume are rendered into the preview pod spec, ensure the emptyDir
volume name used by convert-config matches the volumeMount in the main container
(same volume name as in volumes/volumeMounts), and keep existing
volumeMounts/volumes logic but include the initContainers block before
containers so preview follows the identical config.jsonc -> config.js conversion
path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0e389eac-0102-4215-bad9-ee33eac93714

📥 Commits

Reviewing files that changed from the base of the PR and between a7c1a43 and ae1a6b3.

📒 Files selected for processing (7)
  • .common/preview-ui-template/templates/dashboard-deployment.yaml
  • preview-traq/kustomization.yaml
  • preview-traq/values.yaml
  • traq-dev/frontend/deployment-patch.yaml
  • traq-dev/frontend/kustomization.yaml
  • traq/frontend/config.jsonc
  • traq/frontend/deployment.yaml

Comment thread preview-traq/kustomization.yaml Outdated
Comment thread traq/frontend/deployment.yaml Outdated
- name: preview-traq-config
namespace: preview-traq
files:
- config.json=../traq/frontend/config.jsonc
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここファイル名が合ってなさそうです

Suggested change
- config.json=../traq/frontend/config.jsonc
- config.jsonc=../traq/frontend/config.jsonc

configMapGenerator:
- name: traq-frontend-config
files:
- ../../traq/frontend/config.jsonc
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これpreview-traqと書き方が違うのって理由ありますか?
あと、本番環境の方に無さそうな気がします

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants