Conversation
config に vercel.projects[] / github.repos[] を追加し、1 つの定義ファイルから 複数の Vercel プロジェクト・複数の GitHub リポジトリへ一括同期できるようにした。 - config: VercelProjectConf/GitHubRepoConf 型と ResolveVercelTargets/ ResolveGitHubTargets を追加。token/team_id は per-target を最優先し、 空ならトップレベル config・環境変数へフォールバック - マージ: project 側が非空なら global を置き換え - CLI: --vercel-project / --github-repo で対象を 1 件に絞り込み - provider: Sync を複数ターゲットのループへリファクタし、ターゲットごとに 見出し・新規/更新分類を表示。1 ターゲット失敗でも残りを試行し、ループ後に 失敗集約して os.Exit 判定(Vercel/GitHub 統一) - 分類結果を再利用し既存確認 API の二重呼び出しを回避 - バリデーション: 複数定義時の project_id/repo 必須、name 必須・重複検出、 projects/repos 未定義時の selectName 指定はエラー - 後方互換: 単一 project_id/repo・環境変数・.vercel/project.json・git remote フォールバックは従来どおり単一ターゲットとして動作 - README / env-sync.yaml コメント / usage に設定例を追記 - ユニット・統合テスト追加(go test -race ./... green) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUNfaHdh77j6ZEA2v8oieH
There was a problem hiding this comment.
Pull request overview
モノレポ構成で「複数 Vercel プロジェクト」「複数 GitHub リポジトリ」へ 1 回の実行で環境変数を同期できるようにするため、config スキーマ拡張とターゲット解決 API、CLI 絞り込みフラグ、provider の複数ターゲット送信ループ化、関連ドキュメント/テスト追加を行う PR です。
Changes:
- config に
vercel.projects[]/github.repos[]を追加し、ResolveVercelTargets/ResolveGitHubTargetsで解決済みターゲット配列を返すように変更 - CLI に
--vercel-project/--github-repoを追加し、provider 側を複数ターゲット同期のループへリファクタ - README / env-sync.yaml コメント /
--helpusage とテストを拡充(複数ターゲット挙動と失敗集約関連のテスト追加)
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | 複数ターゲット(モノレポ)設定例と CLI オプション表を追記 |
| env-sync.yaml | 複数同期先は認証 config 側で定義する旨をコメント追記 |
| cmd/env-sync/main.go | --vercel-project / --github-repo の usage とスキーマ例を追記 |
| internal/config/appconfig.go | projects/repos スキーマ追加、マージ方針、ターゲット解決・env ref 展開の適用範囲拡張 |
| internal/config/appconfig_test.go | projects/repos のロード・マージ・解決・展開・バリデーションのテスト追加 |
| internal/config/config.go | --vercel-project / --github-repo のフラグパース追加 |
| internal/config/config_test.go | 新規フラグのパーステスト追加 |
| internal/provider/provider.go | provider.Options にターゲット絞り込み用フィールドを追加 |
| internal/provider/vercel/vercel.go | 複数 Vercel ターゲットの一覧表示・確認・送信ループ化、送信処理の関数分離 |
| internal/provider/vercel/vercel_test.go | syncOneVercelTarget の送信/集計/継続性テスト追加 |
| internal/provider/github/github.go | 複数 GitHub ターゲットの一覧表示・確認・送信ループ化、owner/repo 解決と送信処理の関数分離 |
| internal/provider/github/github_integration_test.go | syncOneGitHubTarget の token 反映・継続性・存在確認二重呼び出し防止のテスト追加 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+242
to
+247
| pfields := []*string{ | ||
| &cfg.Vercel.Projects[i].Token, | ||
| &cfg.Vercel.Projects[i].ProjectID, | ||
| &cfg.Vercel.Projects[i].TeamID, | ||
| } | ||
| for _, f := range pfields { |
Comment on lines
+256
to
+260
| rfields := []*string{ | ||
| &cfg.GitHub.Repos[i].Token, | ||
| &cfg.GitHub.Repos[i].Repo, | ||
| } | ||
| for _, f := range rfields { |
Comment on lines
+95
to
+99
| for i, tgt := range targets { | ||
| // トークン未設定チェック(per-target) | ||
| if !opts.DryRun && tgt.Token == "" { | ||
| return fmt.Errorf("VERCEL_TOKEN が未設定です(プロジェクト %q: 環境変数 VERCEL_TOKEN または config ファイルの token で指定してください)", tgt.Name) | ||
| } |
Comment on lines
+162
to
166
| // per-target トークンを決定 | ||
| targetToken := tgt.Token | ||
| if !opts.DryRun && targetToken == "" { | ||
| return fmt.Errorf("GITHUB_TOKEN が未設定です(リポジトリ %q: 環境変数 GITHUB_TOKEN または config ファイルの token で指定してください)", tgt.Name) | ||
| } |
Copilot レビュー指摘対応(ラウンド1): - vercel.go: 複数 targets 時に token 未設定ターゲットを tokenMissing フラグで記録し、 残りターゲットを継続。送信フェーズで失敗として集計する - github.go: 複数 targets 時に token 未設定ターゲットを skipped フラグで記録し、 残りターゲットを継続。送信フェーズで失敗として集計する - 単一ターゲット時は従来通り即エラー返却 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUNfaHdh77j6ZEA2v8oieH
| return cfg.GitHub.Repo | ||
| } | ||
|
|
||
| // resolveVercelToken はトークンの解決優先順位(per-target > top-level config > 環境変数)を実装する。 |
| return cfg.ResolveVercelToken() | ||
| } | ||
|
|
||
| // resolveVercelTeamID はチーム ID の解決優先順位(per-target > top-level config > 環境変数)を実装する。 |
| return cfg.ResolveVercelTeamID() | ||
| } | ||
|
|
||
| // resolveGitHubToken はトークンの解決優先順位(per-target > top-level config > 環境変数)を実装する。 |
Copilot レビュー指摘対応(ラウンド2): - resolveVercelToken / resolveVercelTeamID / resolveGitHubToken のコメントが 「per-target > top-level config > 環境変数」と誤記していたのを 「per-target > 環境変数 > top-level config」(実装と一致)に修正 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUNfaHdh77j6ZEA2v8oieH
Comment on lines
+372
to
+377
| // name の必須チェックと重複チェック(selectName の有無によらず常に実施) | ||
| if err := validateVercelProjectNames(cfg.Vercel.Projects); err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| var targets []VercelTarget |
Comment on lines
+431
to
+436
| // name の必須チェックと重複チェック(selectName の有無によらず常に実施) | ||
| if err := validateGitHubRepoNames(cfg.GitHub.Repos); err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| var targets []GitHubTarget |
Comment on lines
179
to
183
| if len(targets) > 1 { | ||
| fmt.Printf("上記を Vercel の %d プロジェクトに登録します(既存は上書き)。続行しますか? (y/N) ", len(targets)) | ||
| } else { | ||
| fmt.Print("上記を Vercel に登録します(既存は上書き)。続行しますか? (y/N) ") | ||
| } |
Comment on lines
244
to
248
| if len(resolved) > 1 { | ||
| fmt.Printf("上記を GitHub の %d リポジトリに登録します(既存は上書き)。続行しますか? (y/N) ", len(resolved)) | ||
| } else { | ||
| fmt.Print("上記を GitHub に登録します。続行しますか? (y/N) ") | ||
| } |
Copilot レビュー指摘対応(ラウンド3): - appconfig.go: validateVercelProjectConfs / validateGitHubRepoConfs を追加し、 projects/repos が定義されている場合は絞り込み後の件数に関わらず 全エントリの project_id / repo を必須チェックする (--vercel-project / --github-repo で 1 件に絞っても .vercel/project.json や git remote フォールバックが動かないようにする) - vercel.go / github.go: 送信フェーズの複数ターゲット表示・全体完了メッセージを activeCount / activeResolved(スキップ除外数)で判定するよう修正 - 確認プロンプトの件数表示を実際に送信されるターゲット数に合わせる - 新規バリデーションのテストを追加(project_id 空・repo 空、絞り込み時も全エントリ検証) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUNfaHdh77j6ZEA2v8oieH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
タスク
turborepo などのモノレポ構成では 1 リポジトリに複数アプリが存在し、Vercel プロジェクトや GitHub リポジトリも複数になる場合がある。現状は単一ターゲットにしか同期できなかったため、複数ターゲットへ環境変数を配れるようにする。
変更内容
config (
internal/config/appconfig.go)vercel.projects: [{ name, project_id, team_id, token? }]/github.repos: [{ name, repo, token? }]を追加ResolveVercelTargets(selectName)/ResolveGitHubTargets(selectName)を追加。解決済みターゲットのスライスを返す${VAR}/${VAR:-default}展開を per-target フィールドにも適用project_id/repo必須、name必須・重複検出、projects/repos未定義時に--vercel-project/--github-repo指定はエラーCLI (
internal/config/config.go,internal/provider/provider.go)--vercel-project <name>/--github-repo <name>を追加(特定ターゲットのみ同期 / 未指定なら全件)provider (
vercel.go,github.go)Syncを複数ターゲットのループへリファクタ。ターゲットごとに「対象プロジェクト/リポジトリ」見出しと新規/更新分類を表示os.Exit判定(Vercel/GitHub 統一).vercel/project.json/ git remote フォールバックは単一ターゲット時のみドキュメント
env-sync.yamlコメント・--helpusage に設定例を追記完了条件
Vercel
.vercel/project.json)が従来どおり動作--vercel-project指定分)へ同期GitHub
GITHUB_REPO、git remote フォールバック)が従来どおり動作--github-repo指定分)へ同期共通
go test ./...green動作確認
gofmt -l差分なし /go vet ./.../go build ./...)受け入れテスト結果(dry-run)
--vercel-project admin→ 1 件 / 存在しない名前 → エラーGITHUB_REPOのみ → 1 件 / 複数 repos 2件 → 2 件表示 /--github-repo infra→ 1 件 / 重複 name → エラー品質チェック結果
🟡 Warning(PR 進行可・既存パターン踏襲)
Syncが失敗でos.Exit(1)すると GitHub が実行されない。これは本 PR 以前からの既存挙動(各Syncが直接os.Exit)の踏襲であり、本 PR の新規退行ではない。provider 横断での集約が必要なら別途os.Exitをrun()側へ寄せるリファクタが必要。🔵 Info
--provider gcp時は--vercel-project/--github-repoを無視(GCP にモノレポ対応がないため妥当)パフォーマンス診断(静的解析・非ブロッキング)
vercelFetchExistingKeys)は upsert のため送信に使われず表示専用。確認・表示が不要な経路ではターゲット数分の API 呼び出しを省略できる余地(将来最適化)🤖 Generated with Claude Code
https://claude.ai/code/session_01MUNfaHdh77j6ZEA2v8oieH