AllTips & 裏技·

ローカル環境はもう要らない — フォークしてプライベート化、git push で本番デプロイ

Shudesuのプロフィール画像

Shudesu

Author

ローカル環境はもう要らない — フォークしてプライベート化、git push で本番デプロイ

LINE Harness と IG Harness は GitHub Actions 自動デプロイ対応済み。 OSS をフォークしてプライベート化し、main に push するだけで Cloudflare に反映される。 Mac Mini も wrangler deploy も要らない。

こうなる

  • 毎回 wrangler deploy を叩かなくていい
  • チームで触るとき PR レビューがそのまま効く
  • ローカルが死んでてもデプロイできる
  • D1 マイグレーションも自動(LINE Harness の deploy-worker.yml が処理)

やり方

1. OSS をフォーク → プライベート化

GitHub Web UI のフォークは public のままなので、Import 経由で private を作る方が綺麗:

  1. GitHub の New repositoryImport a repository
  2. Source URL: https://github.com/Shudesu/line-harness-oss(IG なら Shudesu/ig-harness-oss
  3. Privacy: Private
  4. Repository name: 任意(例: my-line-harness
  5. Begin import

CLI 派なら:

gh repo create my-line-harness --private --clone
cd my-line-harness
git remote add upstream https://github.com/Shudesu/line-harness-oss.git
git pull upstream main
git push origin main

2. GitHub Secrets / Variables を設定

Repo → Settings → Secrets and variables → Actions

LINE Harness — Secrets:

Secret用途
CLOUDFLARE_API_TOKENwrangler 認証用
CLOUDFLARE_ACCOUNT_IDCloudflare アカウント ID
D1_DATABASE_NAME例: line-harness
D1_DATABASE_IDD1 の UUID
NEXT_PUBLIC_API_URLWorker URL(Admin Panel が叩く)

LINE Harness — Variables:

Variable用途
VITE_LIFF_IDLIFF ID
VITE_BOT_BASIC_IDBot Basic ID(@xxx 形式)
VITE_CALENDAR_CONNECTION_IDカレンダー連携 ID(任意)

IG Harness — Secrets:

Secret用途
CLOUDFLARE_API_TOKEN同上
CLOUDFLARE_ACCOUNT_ID同上
NEXT_PUBLIC_API_URLWorker URL

IG Harness — Variables:

Variable用途
VITE_LIFF_IDLIFF ID(LINE 連携用、無ければ空)
VITE_BOT_BASIC_IDBot Basic ID(同上)
VITE_CALENDAR_CONNECTION_IDカレンダー連携 ID(同上)

3. workflow YAML を .github/workflows/ に置く

ファイル2つ作る(worker 用 + admin panel 用)。

LINE Harness — .github/workflows/deploy-worker.yml

name: Deploy Worker

on:
  push:
    branches: [main]
    paths:
      - 'apps/worker/**'
      - 'packages/db/**'
      - 'packages/shared/**'
      - 'packages/line-sdk/**'
      - '.github/workflows/deploy-worker.yml'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - run: pnpm install --frozen-lockfile
      - run: pnpm --filter @line-crm/shared --filter @line-crm/line-sdk --filter @line-crm/db build

      - name: Run pending D1 migrations
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
        run: |
          npx wrangler d1 execute ${{ secrets.D1_DATABASE_NAME }} --remote --command \
            "CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at TEXT NOT NULL)"
          for f in $(ls packages/db/migrations/*.sql | sort); do
            name=$(basename "$f")
            applied=$(npx wrangler d1 execute ${{ secrets.D1_DATABASE_NAME }} --remote \
              --command "SELECT name FROM _migrations WHERE name = '${name}'" --json \
              | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));console.log(d[0]?.results?.length||0)")
            if [ "$applied" = "0" ]; then
              echo "Applying: $name"
              npx wrangler d1 execute ${{ secrets.D1_DATABASE_NAME }} --remote --file="$f"
              npx wrangler d1 execute ${{ secrets.D1_DATABASE_NAME }} --remote --command \
                "INSERT INTO _migrations (name, applied_at) VALUES ('${name}', datetime('now'))"
            else
              echo "Skipped (already applied): $name"
            fi
          done

      - name: Build Worker + LIFF assets
        run: pnpm --filter worker build
        env:
          VITE_LIFF_ID: ${{ vars.VITE_LIFF_ID }}
          VITE_BOT_BASIC_ID: ${{ vars.VITE_BOT_BASIC_ID }}
          VITE_CALENDAR_CONNECTION_ID: ${{ vars.VITE_CALENDAR_CONNECTION_ID }}

      - name: Patch wrangler.json for production
        run: |
          cd apps/worker
          sed -i \
            -e 's|"account_id":"[^"]*"|"account_id":"${{ secrets.CLOUDFLARE_ACCOUNT_ID }}"|g' \
            -e 's|"database_name":"[^"]*"|"database_name":"${{ secrets.D1_DATABASE_NAME }}"|g' \
            -e 's|"database_id":"[^"]*"|"database_id":"${{ secrets.D1_DATABASE_ID }}"|g' \
            dist/line_harness/wrangler.json

      - name: Deploy to Cloudflare Workers
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          workingDirectory: apps/worker
          command: deploy --config dist/line_harness/wrangler.json --name line-crm-worker

LINE Harness — .github/workflows/deploy-web.yml

name: Deploy Admin Panel

on:
  push:
    branches: [main]
    paths:
      - 'apps/web/**'
      - 'packages/shared/**'
      - '.github/workflows/deploy-web.yml'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - run: pnpm install --frozen-lockfile
      - run: pnpm --filter @line-crm/shared build

      - name: Build Admin Panel
        run: pnpm --filter web build
        env:
          NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}

      - name: Deploy to Cloudflare Pages
        run: npx wrangler pages deploy apps/web/out --project-name=line-crm-admin
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

IG Harness — .github/workflows/deploy-worker.yml

name: Deploy Worker

on:
  push:
    branches: [main]
    paths:
      - 'apps/worker/**'
      - 'packages/db/**'
      - 'packages/shared/**'
      - 'packages/ig-sdk/**'
      - '.github/workflows/deploy-worker.yml'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - run: pnpm install --frozen-lockfile
      - run: pnpm --filter @ig-harness/shared --filter @ig-harness/ig-sdk --filter @ig-harness/db build

      - name: Build Worker + LIFF assets
        run: pnpm --filter worker build
        env:
          VITE_LIFF_ID: ${{ vars.VITE_LIFF_ID }}
          VITE_BOT_BASIC_ID: ${{ vars.VITE_BOT_BASIC_ID }}
          VITE_CALENDAR_CONNECTION_ID: ${{ vars.VITE_CALENDAR_CONNECTION_ID }}

      - name: Deploy to Cloudflare Workers
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          workingDirectory: apps/worker
          command: deploy --config dist/ig_harness/wrangler.json --name ig-harness

IG Harness — .github/workflows/deploy-web.yml

name: Deploy Admin Panel

on:
  push:
    branches: [main]
    paths:
      - 'apps/web/**'
      - 'packages/shared/**'
      - '.github/workflows/deploy-web.yml'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - run: pnpm install --frozen-lockfile
      - run: pnpm --filter @ig-harness/shared build

      - name: Build Admin Panel
        run: pnpm --filter web build
        env:
          NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}

      - name: Deploy to Cloudflare Pages
        run: npx wrangler pages deploy apps/web/out --project-name=ig-harness-admin
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

4. main にプッシュ

git add .github/workflows/
git commit -m "chore: add deploy workflows"
git push origin main

5. Actions タブで確認

GitHub Repo → Actions タブで進捗を見る。緑になれば本番反映済み。

ローカル fallback

GitHub Actions が落ちてる時の手動コマンド。

LINE Harness:

pnpm --filter @line-crm/shared --filter @line-crm/line-sdk --filter @line-crm/db build
cd apps/worker && npx wrangler deploy

IG Harness:

pnpm --filter @ig-harness/shared --filter @ig-harness/ig-sdk --filter @ig-harness/db build

# Web (Pages)
pnpm --filter web build
CLOUDFLARE_ACCOUNT_ID=YOUR_ACCOUNT_ID \
  npx wrangler pages deploy apps/web/out --project-name=ig-harness-admin --branch=main

# Worker
cd apps/worker && npx wrangler deploy

X Harness について

X Harness は現状 GitHub Actions 自動デプロイ未対応。npx create-x-harness の CLI デプロイで動かす。詳細は 1コマンドでX Harnessをデプロイする 参照。

こんなときに使える

  • チーム運用: 配信担当者が PR を出して、レビューしてマージ → 自動反映
  • 複数案件の使い分け: 案件ごとにフォーク作って、それぞれ Cloudflare アカウントに紐付け
  • ローカル開発しない人: 案件オーナーがダッシュボードからしか触らない場合、最初の設定さえすれば後はノータッチで OK
#deploy#github-actions#ops#fork
この記事が役に立ったら投票してください

コメント (0)

コメントするにはログインしてください。

ローカル環境はもう要らない — フォークしてプライベート化、git push で本番デプロイ — Harness Wiki