📘 HubSpot CMS 組み込み構築 教科書
Chapter 9 — CLI · Deploy · MCP

開発環境・CLI・デプロイワークフロー

HubSpot CLI の全コマンドと設定・複数ポータルの管理戦略・ローカル開発の進め方・GitHub Actions による CI/CD パイプライン・チーム開発のベストプラクティスまで。プロジェクトを安全・高速に運用するための体系を整理します。

🎯 対象レベル:中級〜上級
⏱ 読了目安:60〜90分
🔗 前章:第8章 パフォーマンス・SEO・アクセシビリティ
🆕 2026年3月版 — CLI v8 / Node 20 / Developer MCP Server 対応

この章の内容

  1. HubSpot CLI のセットアップと認証 v8対応
  2. CLI 全コマンドリファレンス v8対応
  3. ローカル開発フロー(watch モード)
  4. 複数ポータルの管理戦略(開発・本番分離)
  5. .hsignore による同期除外設定
  6. hubl.config.yml の詳細設定
  7. GitHub との連携と GitHub Actions CI/CD v8対応
  8. デプロイワークフローのベストプラクティス
  9. HubSpot Developer MCP Server — AIエージェントで開発を加速する NEW
  10. チーム開発のベストプラクティス
  11. 第9章まとめ
Section 9-1

HubSpot CLI のセットアップと認証

HubSpot CLI(コマンドラインインターフェース)は、 ローカルのファイルシステムとHubSpotポータルを双方向に同期するツールです。 デザインマネージャーをブラウザ上で操作するより、 エディタとターミナルで高速に開発できるのが最大のメリットです。

① Node.js とCLIのインストール

⚠️ 2026年2月〜 CLI v8.0.0:Node.js 20 が必須

HubSpot CLI v8.0.0(2026年2月9日〜有効)より、最低 Node.js バージョンが Node 20 に引き上げられました。 Node 18 は HubSpot サーバーレス関数・CLI 両方で 2025年10月1日にサポート終了済みです。 nvm(Node Version Manager)を使っている場合は nvm install 20 && nvm use 20 で切り替えてください。 また v8 では 旧コマンド(hs upload/hs watch など)が完全削除され、 hs cms upload/hs cms watch への移行が必須です(Section 9-2 参照)。

ターミナル — HubSpot CLI インストール(Node 20 必須)
# Node.js 20以上が必要(v8.0.0以降は必須)。バージョン確認
$ node --version
v20.x.x  ← 20以上であること(18.x は NG)

# npmでHubSpot CLIをグローバルインストール
$ npm install -g @hubspot/cli

# インストール確認(v8.0.0以上を推奨)
$ hs --version
8.x.x

# または npx で都度実行(インストール不要)
$ npx @hubspot/cli --version

② 認証の設定(初回のみ)

ターミナル — HubSpot ポータルへの認証
# プロジェクトルートで初期化
$ hs init

# 対話形式で設定が進む
? Enter a name for this account (e.g. "my-sandbox"): my-company-dev
? Enter your HubSpot portal ID: 12345678
? How would you like to authenticate your account?
  ❯ Personal Access Key (recommended)
    OAuth2

# Personal Access Key を選択すると、ブラウザが開き
# HubSpot管理画面で Personal Access Key を発行できる
# Developer Accounts → アカウント → Personal Access Keys から取得

? Enter your personal access key: eu1-xxxx-xxxx-xxxx-xxxx
✔ Authenticated account: my-company-dev (12345678)
✔ Config file created: ~/.config/@hubspot/cli/config.yml

③ プロジェクト用の設定ファイル確認

hs init を実行すると、プロジェクトルートに hubspot.config.yml が生成されます。 このファイルがCLIの設定の起点になります。

hubspot.config.yml — 初期生成される設定ファイル
defaultPortal: my-company-dev
portals:
  - name: my-company-dev
    portalId: 12345678
    authType: personalaccesskey
    personalAccessKey: eu1-xxxx-xxxx-xxxx-xxxx
    auth:
      tokenInfo:
        accessToken: CJa...
        expiresAt: '2024-12-31T00:00:00.000Z'
⚠️ hubspot.config.yml は .gitignore に追加必須

hubspot.config.yml には Personal Access Key(アクセストークン)が含まれます。 絶対に Git リポジトリにコミットしてはいけません。 プロジェクト作成直後に .gitignore に追加し、 チームメンバーには各自で hs init を実行してもらいます。 本番CI/CD環境では環境変数経由でトークンを渡す設計にします(後述)。


Section 9-2 ★ CLI v8 対応

CLI 全コマンドリファレンス

⚠️ CLI v8(2026年2月〜):コマンド体系が変わりました

2025年10月より CMS 関連コマンドが hs cms ネームスペース に移動しました。 CLI v8.0.0 では旧コマンド(hs uploadhs watch 等)が完全削除されています。 CI/CD パイプラインや package.json の scripts に旧コマンドが残っている場合は早急に更新が必要です。 下表で新旧対応を確認してください。

旧コマンド → 新コマンド 対応表

旧コマンド(v8で削除済み)新コマンド(現在の正式コマンド)用途
hs uploadhs cms uploadファイル・ディレクトリをHubSpotにアップロード
hs watchhs cms watch変更を監視して自動アップロード(開発中に常時使う)
hs fetchhs cms fetchHubSpotからローカルにファイルをダウンロード
hs linths cms lintHubL構文チェック
hs lisths cms listHubSpot上のファイル一覧表示
hs mvhs cms mvHubSpot上のファイル移動・リネーム
hs removehs cms deleteHubSpot上のファイル・フォルダ削除
hs create themehs cms app / npx create-cms-themeテーマ雛形の生成
hs create modulehs cms moduleカスタムモジュール雛形生成
hs theme previewhs cms theme previewテーマのプレビュー起動
hs theme marketplace-validatehs cms theme marketplace-validateマーケットプレイス向けバリデーション
hs function ...hs cms function ...サーバーレス関数の操作全般
hs logshs cms function logsサーバーレス関数のログ確認

主要コマンド一覧(v8 新体系)

hs cms upload <src> <dest>
ローカルのファイル・ディレクトリをHubSpotにアップロードする
--portal=名前 --overwrite
hs cms watch <src> <dest>
ファイル変更を監視し、変更があれば自動でアップロード(開発中に常時使う)
--portal=名前 --remove
hs cms fetch <src> <dest>
HubSpotからローカルにファイルをダウンロード(初回取得や差分確認に使う)
--portal=名前 --overwrite
hs cms lint <src>
HubL構文エラー・警告をチェックする。デプロイ前に必ず実行する
--portal=名前
hs cms list <path>
HubSpot上の指定パス配下のファイル一覧を表示する
--portal=名前
hs cms mv <src> <dest>
HubSpot上のファイル・フォルダを移動またはリネームする
--portal=名前
hs cms delete <path>
HubSpot上のファイル・フォルダを削除する(旧: hs remove)
--portal=名前
hs cms module <name>
カスタムモジュールの雛形(5ファイル)を生成する
--path=配置先パス
hs cms theme preview
テーマのローカルプレビューを起動する
--portal=名前
hs cms function logs
デプロイ済みサーバーレス関数のログを確認する(旧: hs logs)
--portal=名前 --follow
hs project upload
Projectsフレームワーク(React/v2025.2)のビルド&アップロード
--portal=名前
hs auth
認証情報の追加・更新・確認を行う

コマンドの実践的な使い方(v8 対応)

ターミナル — よく使うコマンドパターン(v8 新体系)
# ===== テーマ全体のアップロード =====
$ hs cms upload ./src/my-theme @my-theme --portal=my-company-dev

# ===== 開発中のwatchモード起動 =====
$ hs cms watch ./src/my-theme @my-theme --portal=my-company-dev
Watcher started, watching "./src/my-theme"
Uploaded "templates/page.html" to "@my-theme/templates/page.html"
Uploaded "modules/hero-banner.module/module.html"

# ===== HubSpotから最新を取得(差分確認前)=====
$ hs cms fetch @my-theme ./src/my-theme-remote --portal=my-company-prod --overwrite

# ===== デプロイ前の lint チェック =====
$ hs cms lint ./src/my-theme --portal=my-company-dev
✔ No lint errors found

# ===== 特定のファイルのみアップロード =====
$ hs cms upload ./src/my-theme/modules/hero-banner.module @my-theme/modules/hero-banner.module

# ===== 新しいモジュールの雛形生成 =====
$ hs cms module pricing-table --path=./src/my-theme/modules
✔ Created "pricing-table.module" at ./src/my-theme/modules/pricing-table.module

# ===== ポータルのファイル一覧確認 =====
$ hs cms list --portal=my-company-prod
@my-theme/
├── templates/
├── modules/
├── css/
├── js/
└── theme.json

hs cms lint の活用

ターミナル — lint エラーの確認と対応
$ hs cms lint ./src/my-theme

✖ Error in "templates/blog-post.html" line 42:
  Unexpected tag: endmodule (did you mean end_module?)

⚠ Warning in "modules/card-grid.module/module.html" line 18:
  Variable "module.subtitle" used but not defined in fields.json

Lint complete: 1 error, 1 warning

# エラーを修正後に再実行
$ hs cms lint ./src/my-theme
✔ No lint errors found (1 warning)

Section 9-3

ローカル開発フロー(watch モード)

実務での開発は hs cms watch を起動した状態でエディタを使います。 ファイルを保存するたびに自動でHubSpotにアップロードされ、 ブラウザをリロードすれば即座に確認できます。

推奨ディレクトリ構成

プロジェクトルート構成
my-project/
├── src/                         # ← CLIで同期するファイル群
│   └── my-theme/               # テーマ本体
│       ├── theme.json
│       ├── templates/
│       ├── modules/
│       ├── css/
│       ├── js/
│       └── images/
├── .gitignore
├── .hsignore                    # CLIが無視するファイルを定義
├── hubspot.config.yml           # 認証設定(.gitignoreに追加)
├── package.json                  # npm scripts で開発コマンドを定義
└── README.md                    # セットアップ手順のドキュメント

package.json でコマンドを整理する

package.json — 開発コマンドの定義
{
  "name": "my-company-hubspot",
  "version": "1.0.0",
  "scripts": {

    // ===== 開発コマンド =====
    "dev": "hs cms watch src/my-theme @my-theme --portal=dev",
    // npm run dev で watch モード起動(devポータルに同期)

    // ===== デプロイコマンド =====
    "deploy:dev"  : "hs cms upload src/my-theme @my-theme --portal=dev --overwrite",
    "deploy:prod" : "hs cms upload src/my-theme @my-theme --portal=prod --overwrite",

    // ===== チェックコマンド =====
    "lint"       : "hs cms lint src/my-theme --portal=dev",
    "fetch:prod"  : "hs cms fetch @my-theme src/my-theme-remote --portal=prod --overwrite",

    // ===== 複合コマンド =====
    "predeploy:prod": "npm run lint"
    // deploy:prodの前にlintを自動実行(エラーがあればデプロイを中断)
  },
  "devDependencies": {
    "@hubspot/cli": "^8.0.0"
    // CLI v8以上を指定(Node.js 20必須)
  }
}
ターミナル — 開発の日常コマンド
# === 毎日の開発開始時 ===
$ npm run dev
Watcher started, watching "src/my-theme"
# エディタでファイルを編集 → 保存 → 自動アップロード → ブラウザでリロード確認

# === 作業が終わったら watch を Ctrl+C で停止 ===

# === 本番デプロイ前のチェック ===
$ npm run lint
✔ No lint errors found

# === 本番デプロイ(lintが通った場合のみ実行される)===
$ npm run deploy:prod
Uploading "src/my-theme" to "@my-theme" on portal "prod"...
✔ Done uploading 48 files

Section 9-4

複数ポータルの管理戦略(開発・本番分離)

実案件では開発用ポータル(Sandbox/Developer Account)本番ポータルを分離して管理します。 本番環境に直接 watch することは事故の原因になるため厳禁です。

ポータル構成の全体像

💻
ローカル
src/ ディレクトリ
🧪
開発ポータル
Developer Account / Sandbox
🚀
本番ポータル
クライアントの本番環境

複数ポータルの hubspot.config.yml 設定

hubspot.config.yml — 複数ポータルの設定
# デフォルトポータル(hs cms upload で --portal を省略した場合に使われる)
defaultPortal: dev

portals:
  # ===== 開発ポータル(日常開発用)=====
  - name: dev
    portalId: 11111111
    authType: personalaccesskey
    personalAccessKey: eu1-dev-key-xxxxxxxxxx

  # ===== 本番ポータル(デプロイ時のみ)=====
  - name: prod
    portalId: 22222222
    authType: personalaccesskey
    personalAccessKey: eu1-prod-key-xxxxxxxxxx

  # ===== クライアント検証用(任意)=====
  - name: staging
    portalId: 33333333
    authType: personalaccesskey
    personalAccessKey: eu1-staging-key-xxxxxxxxxx

ポータル別の運用ルール

ポータル使用場面watch の使用管理画面編集
開発ポータル(dev) 日常的な開発・動作確認 ✅ 推奨 自由に可
ステージング(staging) クライアントへの確認依頼・QA ⚠️ 慎重に 限定的に
本番ポータル(prod) 最終デプロイのみ 🚫 禁止 原則禁止
⚠️ 本番への watch は絶対に禁止

hs cms watch を本番ポータルに向けて起動すると、 開発中の未完成なコードが即座に本番に反映されてしまいます。 本番へのアップロードは必ず hs cms upload コマンドで手動実行し、 デプロイ内容を意識的に確認してから行ってください。
package.json の dev スクリプトが常に開発ポータルを向いているか定期的に確認する習慣をつけましょう。


Section 9-5

.hsignore による同期除外設定

.hsignore ファイルは .gitignore と同じ形式で、 hs cms uploadhs cms watch で同期しないファイル・ディレクトリを指定します。

# ===== .hsignore ===== # HubSpot CLI が無視するファイルを定義する(.gitignore と同じ書式) # システムファイル .DS_Store Thumbs.db desktop.ini # エディタ設定 .vscode/ .idea/ *.swp *~ # 開発用ファイル(アップロード不要) *.md *.txt package.json package-lock.json node_modules/ # ローカル開発専用ファイル(テスト・モック等) __tests__/ *.test.js *.spec.js mock-data/ # ビルド出力(SCSSなど使う場合) .sass-cache/ *.map # バックアップファイル *.bak *.orig
💡 *.md を ignore することでREADMEはリポジトリのみに残せる

*.md.hsignore に入れておくと、 README.md や CHANGELOG.md といったドキュメントファイルがHubSpotにアップロードされません。 同様に package.jsonnode_modules/ も ignore することで、 HubSpot上のファイル構成をクリーンに保てます。


Section 9-6

hubl.config.yml の詳細設定

hubspot.config.yml には認証情報以外にも、 CLIの動作を細かくカスタマイズするオプションがあります。

hubspot.config.yml — 詳細設定オプション
defaultPortal: dev

# ===== CLIのグローバル設定 =====
httpTimeout: 30000
# APIリクエストのタイムアウト時間(ミリ秒)
# 大きなテーマをアップロードする際はこの値を増やす

allowUsageTracking: false
# HubSpotへの使用状況データ送信の許否

portals:
  - name: dev
    portalId: 11111111
    authType: personalaccesskey
    personalAccessKey: eu1-dev-key

    # ===== ポータル個別設定 =====
    defaultMode: write
    # write(アップロード優先)/ read(ダウンロード優先)

  - name: prod
    portalId: 22222222
    authType: personalaccesskey
    personalAccessKey: eu1-prod-key
    defaultMode: write

Section 9-7

GitHub との連携と GitHub Actions CI/CD

Git リポジトリと GitHub Actions を連携させることで、 「mainブランチにマージされたら自動で本番デプロイ」 という CI/CD パイプラインを構築できます。

ブランチ戦略

📋 推奨ブランチ戦略
🌿
feature/xxx
機能ごとに切る
ローカル開発
→ PR →
🔀
develop
開発ポータルへ
自動デプロイ
→ PR →
staging
ステージングへ
自動デプロイ
→ PR →
🚀
main
本番ポータルへ
自動デプロイ

GitHub Secrets の設定

Personal Access Key を GitHub リポジトリの Secrets に登録します。 GitHub のリポジトリページ → Settings → Secrets and variables → Actions から設定します。

Secret 名
HUBSPOT_PORTAL_ID_DEV開発ポータルのポータルID
HUBSPOT_ACCESS_KEY_DEV開発ポータルの Personal Access Key
HUBSPOT_PORTAL_ID_PROD本番ポータルのポータルID
HUBSPOT_ACCESS_KEY_PROD本番ポータルの Personal Access Key

GitHub Actions ワークフローの実装

.github/workflows/deploy-dev.yml — develop ブランチへのデプロイ
name: Deploy to Dev Portal

on:
  push:
    branches:
      - develop

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install HubSpot CLI
        run: npm install -g @hubspot/cli

      - name: Create HubSpot config
        # Secretsから hubspot.config.yml を動的生成
        run: |
          cat > hubspot.config.yml << EOF
          defaultPortal: dev
          portals:
            - name: dev
              portalId: ${{ secrets.HUBSPOT_PORTAL_ID_DEV }}
              authType: personalaccesskey
              personalAccessKey: ${{ secrets.HUBSPOT_ACCESS_KEY_DEV }}
          EOF

      - name: Lint check
        run: hs cms lint src/my-theme --portal=dev

      - name: Deploy to Dev
        run: hs cms upload src/my-theme @my-theme --portal=dev --overwrite

      - name: Notify Slack on success
        if: success()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "✅ 開発環境へのデプロイ完了: ${{ github.event.head_commit.message }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
.github/workflows/deploy-prod.yml — main ブランチへの本番デプロイ
name: Deploy to Production

on:
  push:
    branches:
      - main

jobs:
  lint:
    name: Lint Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm install -g @hubspot/cli
      - name: Create config
        run: |
          cat > hubspot.config.yml << EOF
          defaultPortal: dev
          portals:
            - name: dev
              portalId: ${{ secrets.HUBSPOT_PORTAL_ID_DEV }}
              authType: personalaccesskey
              personalAccessKey: ${{ secrets.HUBSPOT_ACCESS_KEY_DEV }}
          EOF
      - run: hs cms lint src/my-theme --portal=dev

  deploy:
    name: Deploy to Production
    needs: lint        # lint job が成功した場合のみ実行
    runs-on: ubuntu-latest
    environment: production   # GitHub Environments で承認ゲートを設定可能

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm install -g @hubspot/cli

      - name: Create production config
        run: |
          cat > hubspot.config.yml << EOF
          defaultPortal: prod
          portals:
            - name: prod
              portalId: ${{ secrets.HUBSPOT_PORTAL_ID_PROD }}
              authType: personalaccesskey
              personalAccessKey: ${{ secrets.HUBSPOT_ACCESS_KEY_PROD }}
          EOF

      - name: Deploy to Production
        run: hs cms upload src/my-theme @my-theme --portal=prod --overwrite

      - name: Notify on success
        if: success()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "🚀 本番デプロイ完了!\ncommit: ${{ github.event.head_commit.message }}\nby: ${{ github.actor }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

      - name: Notify on failure
        if: failure()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "❌ 本番デプロイ失敗!確認が必要です。\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
✅ GitHub Environments で本番デプロイに承認ゲートを設ける

GitHub の Settings → Environments で production 環境を作成し、 Required reviewers(承認者)を設定すると、 main へのマージ後・デプロイ実行前に指定メンバーの承認が必要になります。 ワークフローの environment: production がこれと連動します。 意図しない本番デプロイを防ぐ安全装置として非常に有効です。


Section 9-8 ★ New(2026年2月 GA)

HubSpot Developer MCP Server — AIエージェントで開発を加速する

2026年2月19日、HubSpot Developer MCP Server が正式GA(一般公開)されました。 MCP(Model Context Protocol)は、AIツールが外部サービスと連携するための標準規格です。 HubSpot の Developer MCP Server をローカルにインストールすることで、 VS Code・Claude Code・Cursor などのAIエディタが HubSpot の開発者ドキュメントを参照しながら、自然言語でCMSアセットの生成・デプロイ・デバッグを実行できるようになります。

🛠️ Developer MCP Server(ローカル)

CLIを通じてインストールし、ローカルで動作するサーバー。HubSpotの開発者プラットフォームに接続し、プロジェクトのスキャフォールド・CMS資産の管理・サーバーレス関数のデバッグを自然言語で実行できる。CLI v8.0.0以上・Platform v2025.2が必要。

🌐 HubSpot MCP Server(リモート)

mcp.hubspot.comに接続するリモートサーバー。HubSpot CRMデータへのリアルタイムアクセスを提供し、「このコンタクトの最新アクティビティを取得して」などのクエリに対応。OAuth 2.0認証を使用。

セットアップ手順

ターミナル — Developer MCP Server のインストール
# 前提:CLI v8.0.0以上がインストール済みであること
$ hs --version
8.x.x

# MCP Server をセットアップ(対話形式)
$ hs mcp setup

# ↓ 対話式で接続するMCPクライアントを選択
? Which clients would you like to add the MCP server to?
  ❯ ◉ VS Code
    ◉ Claude Code
    ◯ Cursor
    ◯ OpenAI Codex
(Use arrow keys and spacebar to select, Enter to proceed)

✔ HubSpotDev MCP server has been added to: VS Code, Claude Code
Restart your client to apply the changes.

MCPサーバーでできること

タスクAIへのプロンプト例
モジュール生成 「pricing-tableというReactモジュールを作って。価格プラン3列を表示するグリッドレイアウトで、各列にタイトル・価格・特徴リストを表示できるフィールド設計にして」
テンプレート生成 「Product Landingというページテンプレートを新規作成して。ヒーローセクション・特徴グリッド・CTAセクションの3ブロック構成で、全てdnd_area対応にして」
エラーデバッグ 「NewCard.tsxでローカル開発中に 'Unable to initialize extension' エラーが出ている。ファイルを確認して修正案を提示して」
CLIの使い方確認 「HubSpot CLIのv8で削除されたコマンドと、その代替コマンドを教えて」
デプロイ 「変更を確認したらdevポータルにアップロードして」
サーバーレス関数 「POST /api/submit-form のエンドポイントを持つサーバーレス関数を生成して、フォームデータをHubSpot CRMに登録するロジックも含めて」
✅ MCPサーバー活用のベストプラクティス

最も効果が高い使い方は「モジュール・テンプレートの初期スキャフォールド」です。 フィールド設計の雛形生成・サーバーレス関数のボイラープレート生成など、 繰り返し作業をAIに委ねることで開発速度が大きく上がります。

なお、HubSpotドキュメントには 「Claude Sonnet 4 以上を使うと最も安定した結果が得られる」 と記載されています。 MCPサーバーとClaude Codeの組み合わせが現時点での推奨構成です。

注意点:MCPサーバーは Developer Platform v2025.2 が必要です。 古いプロジェクトは hs project migrate コマンドで移行してください(サーバーレス関数を含む場合は手動移行が必要)。


Section 9-9

デプロイワークフローのベストプラクティス

デプロイ前チェックリスト

🚀 本番デプロイ前の確認フロー
🔍
hs cms lint
構文エラーなし
🌐
クロスブラウザ
Chrome/Safari/Edge
📱
レスポンシブ
SP/Tab/PC
Lighthouse
90点以上
🚀
deploy:prod
本番デプロイ

ロールバック手順

HubSpotのデザインマネージャーにはバージョン履歴機能があり、 各ファイルの変更履歴から過去のバージョンに戻せます。 ただし、CLIによる一括アップロードではすべてのファイルが上書きされるため、 「Gitタグ + hs cms upload」によるバージョン管理が安全なロールバック手段になります。

ターミナル — タグを使ったバージョン管理とロールバック
# === 本番デプロイ時は必ずGitタグを打つ ===
$ git tag v1.2.0 -m "ヒーローバナーリニューアル"
$ git push origin v1.2.0

# === デプロイ後に問題が発覚した場合のロールバック ===

# ① ロールバックしたいバージョンのタグをチェックアウト
$ git checkout v1.1.0
HEAD is now at abc1234 v1.1.0

# ② 旧バージョンのファイルを本番にアップロード
$ hs upload src/my-theme @my-theme --portal=prod --overwrite
✔ Rollback complete: v1.1.0 deployed to production

# ③ 作業ブランチに戻る
$ git checkout main

# ④ 問題のある変更を修正してから再デプロイ

大規模変更時のデプロイ戦略


Section 9-10

チーム開発のベストプラクティス

ディレクトリ構成のドキュメント化

README.md — チームメンバー向けセットアップガイド
# my-company-hubspot

## 前提条件
- Node.js 20以上(CLI v8.0.0以降必須)
- @hubspot/cli グローバルインストール
- 開発ポータルへのアクセス権(ポータルIDは別途共有)

## セットアップ手順

### 1. リポジトリをクローン
git clone https://github.com/mycompany/hubspot-theme.git
cd hubspot-theme

### 2. HubSpot CLIの認証設定
hs init
# 開発ポータルID: 12345678 (別途Slackで共有)
# Personal Access Key: HubSpot管理画面から各自で発行
# https://app.hubspot.com/personal-access-key/12345678

### 3. 必要なスコープ(Personal Access Keyの発行時に選択)
# ✅ CMS - Design Manager
# ✅ Content

### 4. 開発開始
npm run dev
# ブラウザで開発ポータルを開き、編集内容を確認
# https://app.hubspot.com/website-pages/12345678

## ブランチ戦略
# feature/xxx → develop(DEVポータルに自動デプロイ)
# develop → main(本番ポータルに自動デプロイ)

Personal Access Key に必要なスコープ

スコープ必要な操作
CMS - Design Managerテンプレート・モジュール・テーマのアップロード・ダウンロード(必須)
Contentページ・ブログ記事の閲覧・編集(テンプレート確認に必要)
HubDBHubDBテーブルの操作(HubDBを使う場合)
Formsフォームの確認・テスト(フォーム開発に必要)

よくある競合問題と解決策

⚙️ 「誰かが管理画面で直接編集してしまった」問題

複数の開発者やマーケターが同時に作業していると、 管理画面からの直接編集と CLI からのアップロードが競合する場合があります。

対処法:
① CLIからのデプロイは常に --overwrite フラグを付けて実行する。
② 管理画面での直接編集は禁止し、変更は必ずローカルコードを通す運用ルールを作る。
③ もし管理画面側で重要な変更がされてしまった場合は、hs cms fetch で取得してローカルに取り込み、コードを更新してからアップロードする。
④ チャット(Slack等)で「今デプロイします」の声がけを行い、同時デプロイを防ぐ。

コードレビューのポイント

Personal Access Key の期限管理

Personal Access Key には有効期限はありませんが、 セキュリティ上、6ヶ月〜1年ごとに定期ローテーションを推奨します。 チームメンバーが退職した場合は即時無効化してください。 GitHub Secrets の更新も忘れずに行います。

📌 この章で押さえるべきポイント(2026年版)

CLI v8:Node 20 必須・コマンド体系が変わった

2026年2月9日よりCLI v8.0.0が有効。Node.js 20以上が必須で、hs upload等の旧コマンドは完全削除。全て hs cms upload / hs cms watch 等の新体系に移行する。

Developer MCP Server でAI開発を活用する

2026年2月GAのHubSpot Developer MCP Serverで、VS CodeやClaude Codeから自然言語でモジュール生成・デプロイ・デバッグが可能に。CLI v8 + Platform v2025.2が前提。

環境を分けて本番事故を防ぐ

開発・本番の2ポータル分離が基本。hs cms watch は開発ポータル専用。本番へのアップロードは hs cms upload で明示的に実行し、GitHub Actions で自動化する。

hubspot.config.yml は絶対にコミットしない

Personal Access Keyが含まれるため必ず .gitignore に追加。CI/CDでは環境変数経由でトークンを渡し、動的にymlを生成する。

GitHub Actions で CI/CD を自動化する

develop push → 開発ポータルへ自動デプロイ、main push → 本番ポータルへ自動デプロイ。デプロイ前に hs cms lint を必ず通す。GitHub Deploy Action は v1.7 以上を使用。

チームルールで競合を防ぐ

管理画面での直接編集を禁止し、変更は必ずローカルコードを通す。デプロイ前にSlack等で声がけ。競合が起きた場合は hs cms fetch でリモートを取得してから解決する。

次章:第10章 保守・運用・引き継ぎ設計

納品後の保守体制の設計・クライアントへの引き継ぎドキュメント・HubSpotアップデートへの対応・長期運用チェックリストを解説します。

第10章へ →