概要

項目内容
案件IDMAS-096
カテゴリDevOps
PhaseP1
優先度★★★
所要時間15分
対象ファイル.claspignore

問題

2026-04-13 に発生した実障害。Roo Code が生成した check_links.js(Node.js スクリプト)がプロジェクトルートに残存しており、clasp pushGAS にデプロイされた。このファイルは require('fs') を含むため GAS 上でエラーとなり、onOpen() の実行が妨げられてカスタムメニューが表示されなくなった。

現在の .claspignore

node_modules/**
package.json
package-lock.json
tsconfig.json
.clasp.*.json
.github/**
.git/**
README.md
CLAUDE.md
.claspignore
tests/**
_site/**
scripts/**
docs/**
check_links.js          ← 個別ファイル指定(場当たり的)
final_output.md
inconsistencies.md
_all_docs_for_review.txt

現在の .claspignore の問題点

  1. ルート直下のファイルが個別指定: 新たに AI ツール等がファイルを生成するたびに .claspignore に追記が必要
  2. creds.json が未記載: .gitignore で Git からは除外されているが、.claspignore は独立しているため clasp push 対象になりうる
  3. 包括的な除外パターンがない: *.js*.md のグロブ指定がなく、想定外のファイルが漏れるリスクがある

clasp push の対象とすべきファイル

リポジトリルート
├── appsscript.json        ← GAS マニフェスト(必須)
├── 000_infra/**/*.js      ← GAS ソース
├── 100_config/**/*.js
├── 200_data/**/*.js
├── 300_ui/**/*.js
├── 400_domain/**/*.js
├── 500_import/**/*.js
├── 600_report/**/*.js
├── 800_ops/**/*.js
├── 900_test/**/*.js       ← dev のみ(prod は CI で削除)
└── templates/**/*.html    ← HTML テンプレート(page.html)

上記以外はすべて .claspignore で除外する。

修正方針

個別ファイル指定ではなく、GASソースディレクトリ以外を包括的に除外する ルールに変更する。

案1: ホワイトリスト方式

GASソースの 000_infra/900_test/templates/ のみを対象とし、それ以外を除外。ただし clasp はホワイトリスト方式をサポートしていないため、この方式は不可。

案2: グロブ除外 + 否定パターンで GAS ディレクトリを復元(推奨)

ルート直下の非GASファイルをグロブで包括除外し、GAS ソースディレクトリを否定パターンで復元する:

# ルート直下の非GASファイルを包括除外
*.js
*.md
*.txt
*.json
*.html

# GASソースディレクトリを復元
!000_infra/**
!100_config/**
!200_data/**
!300_ui/**
!400_domain/**
!500_import/**
!600_report/**
!800_ops/**
!900_test/**
!templates/**

# GAS マニフェスト(必須)
!appsscript.json

# 非GASディレクトリを明示的に除外
node_modules/**
.github/**
.git/**
tests/**
_site/**
scripts/**
docs/**

.claspignore.gitignore と同じ glob 構文を使用し、否定パターン(!)もサポートしている。ただし clasp push --force 等で動作が異なる場合があるため、初回は clasp push 前にドライラン相当の確認を行う。

案3: 個別ファイル追加の継続 + MAS-195 の恒久対策

現在の個別指定を維持しつつ、MAS-195(pre-push フック)で非GASファイルの混入を自動検出する恒久対策を導入する。

推奨: 案2 + MAS-195(二重防御)

案2 で .claspignore を包括的にし、MAS-195 の pre-push フックで最終チェックする二重防御を推奨。

動作確認手順

  1. .claspignore を案2 の内容に書き換え
  2. npm run push:dev で開発 GAS にデプロイ
  3. GAS エディタで意図しないファイル(check_links.js 等)が含まれていないことを確認
  4. onOpen() が正常に動作し、カスタムメニューが表示されることを確認
  5. RPA を1件テスト実行して回帰確認

実装プロンプト(Claude Code 用)

MAS-096 + MAS-195 を二重防御として一括実装する統合プロンプト。

あなたはGAS会計システム(bizlp-gas-accounting)のシニア開発者です。
案件 MAS-096「clasp push 時の意図しないファイル混入防止」と MAS-195「clasp pre-push
自動リントチェック」を二重防御として一括実装してください。

## 背景

2026-04-13 に Roo Code が生成した check_links.js がルートに残存し、clasp push
で GAS にデプロイされ onOpen() がエラーになった実障害がある。現在の .claspignore
は個別ファイル指定で場当たり的。
MAS-096 で .claspignore を包括的に書き換え、MAS-195 で pre-push チェックスクリプトを
追加する二重防御を行う。

## 実行前タスク

以下のファイルを読み込み、現状を把握すること:
- `.claspignore` — 現在の除外ルール(個別指定の問題を確認)
- `package.json` — 現在の push:dev / push:prod スクリプト定義
- `scripts/` ディレクトリ — 既存スクリプトの配置場所確認

## 修正対象ファイル

1. `.claspignore` — 全面書き換え
2. `scripts/pre-push-check.sh` — 新規作成
3. `package.json` — push:dev / push:prod スクリプトの修正

## 実装内容

### Step 1: .claspignore の書き換え(MAS-096)

現在の個別ファイル指定を削除し、以下のグロブ除外 + 否定パターンに全面書き換え:

```
# ルート直下の非GASファイルを包括除外
*.js
*.md
*.txt
*.json
*.html

# GASソースディレクトリを復元(否定パターン)
!000_infra/**
!100_config/**
!200_data/**
!300_ui/**
!400_domain/**
!500_import/**
!600_report/**
!800_ops/**
!900_test/**
!templates/**

# GAS マニフェスト(必須)
!appsscript.json

# 非GASディレクトリを明示的に除外
node_modules/**
.github/**
.git/**
tests/**
_site/**
scripts/**
docs/**
```

### Step 2: pre-push チェックスクリプトの作成(MAS-195)

`scripts/pre-push-check.sh` を新規作成:

```sh
#!/bin/bash
set -euo pipefail

# GASソースディレクトリ以外の .js ファイルを検出
stray_files=$(find . -maxdepth 1 -name "*.js" 2>/dev/null)
if [ -n "$stray_files" ]; then
  echo "❌ ERROR: ルート直下に非GASの .js ファイルが存在します:"
  echo "$stray_files"
  echo "clasp push を中止します。ファイルを削除または移動してください。"
  exit 1
fi

echo "✅ pre-push check passed: 非GASファイルなし"
```

作成後に実行権限を付与: `chmod +x scripts/pre-push-check.sh`

### Step 3: package.json の push スクリプト修正(MAS-195)

push:dev と push:prod の先頭に pre-push-check.sh を追加:

変更前:
```json
"push:dev": "bash scripts/clasp-switch.sh dev && clasp push",
"push:prod": "bash scripts/clasp-switch.sh prod && clasp push"
```

変更後:
```json
"push:dev": "bash scripts/pre-push-check.sh && bash scripts/clasp-switch.sh dev && clasp push",
"push:prod": "bash scripts/pre-push-check.sh && bash scripts/clasp-switch.sh prod && clasp push"
```

## 制約

- GAS コード(000_infra/ 〜 900_test/)は一切変更しない
- .claspignore の否定パターン(!)が期待通り動作しない場合は、個別ファイル指定に戻して
  MAS-195 の pre-push チェックのみで防御する方式にフォールバックする
- creds.json 等の機密ファイルは .claspignore で除外済み(*.json で包括除外 →
  appsscript.json のみ復元)

## 動作確認

1. `npm run push:dev` で開発 GAS にデプロイ
2. GAS エディタを開き、以下を確認:
   - check_links.js 等の非GASファイルが含まれていないこと
   - appsscript.json が含まれていること
   - 000_infra/ 〜 900_test/ の全ディレクトリが含まれていること
   - templates/ が含まれていること
3. GAS エディタで onOpen() を実行し、カスタムメニューが正常に表示されることを確認
4. pre-push チェックのテスト:
   - ルートに `dummy_test.js` を作成 → `npm run push:dev` → エラーで中止されることを確認
   - `dummy_test.js` を削除 → `npm run push:dev` → 正常にデプロイされることを確認

### 拡張思考の使用状況

| フェーズ | 拡張思考 | 備考 |
|---------|:--------:|------|
| Step 1 (.claspignore) | なし | テンプレート通りの書き換え |
| Step 2 (pre-push-check.sh) | なし | シェルスクリプト新規作成のみ |
| Step 3 (package.json) | なし | npm scripts の文字列追加のみ |

推奨実行モデル

工程推奨モデル理由
全工程Claude Sonnet 4.6.claspignore の否定パターンの動作検証とフォールバック判断が必要

関連ドキュメント

仕様書関連箇所
6.0 NFR一覧デプロイの安全性・信頼性に関する非機能要件
2.1 タブナンバリングGASファイルのディレクトリ構成(000_infra 〜 900_test)の定義
D.6 MAS-195 pre-push 自動チェック本案件の恒久対策(MAS-096 の後に実施)

人間が検討すべき事項

なし(設定変更のみ。即対応可)


変更履歴

日付変更内容
2026-04-14 10:33初版作成
2026-04-14不整合修正: push対象ファイル一覧追加、案2にtemplates/appsscript.json復元を追加、creds.json漏れ指摘、実装プロンプト追加
2026-04-15実装プロンプトをMAS-096+MAS-195統合版(案2+二重防御)に更新。推奨実行モデルを追加