Conversation
env-sync 実行時の警告(既存 key 取得失敗: HTTP 404 等)の原因を
self-service で切り分けられるよう、読み取り専用の validate サブコマンドを追加する。
- Validator オプショナルインターフェースを追加し、各 provider が自分の検証を実装・出力
- Vercel: GET /v10/projects/{id}/env で到達確認。404→teamId未設定/projectId不一致、
401→token無効、403→スコープ不足の推定原因を提示
- GitHub: GET /repos/{owner}/{repo} で repo/token の有効性を検証
- token / projectId / teamId / repo の解決値と取得元(env / config / project.json /
git remote)を表示。token は完全マスク(値非表示)
- 書き込み API(POST/PUT/PATCH/DELETE)は一切呼ばない(GET のみ)
- env-sync --help(i18n en/ja)に validate の説明を追加
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new read-only validate subcommand to env-sync so users can self-diagnose common configuration/auth/reachability causes behind Vercel/GitHub sync warnings (e.g., missing teamId, invalid token, wrong project/repo), without performing any writes.
Changes:
- Introduces an optional
provider.Validatorinterface and implementsValidate()for Vercel and GitHub providers. - Adds target “resolved value + source” reporting (env/config/project.json/git remote) and API reachability checks (GET-only) with status-based suspected causes.
- Adds i18n keys/catalog entries, updates
--helpusage text, and adds extensive tests (including httptest-based GET-only verification).
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/provider/vercel/vercel.go | Refactors .vercel/project.json fallback into a helper and adds Vercel API reachability helper. |
| internal/provider/vercel/vercel_validate.go | Implements Vercel Validate() output and GET-only API check flow. |
| internal/provider/vercel/vercel_validate_test.go | Adds httptest-based coverage for Vercel validate and helper behavior. |
| internal/provider/provider.go | Adds optional Validator interface alongside Provider. |
| internal/provider/provider_test.go | Tests optional-interface behavior via type assertions. |
| internal/provider/github/github_validate.go | Implements GitHub Validate() output and GET-only repo reachability checks. |
| internal/provider/github/github_validate_test.go | Adds httptest-based coverage for GitHub validate and helper behavior. |
| internal/i18n/keys.go | Adds i18n keys for validate output. |
| internal/i18n/catalog_ja.go | Adds Japanese catalog strings and updates usage text to mention validate. |
| internal/i18n/catalog_en.go | Adds English catalog strings and updates usage text to mention validate. |
| internal/config/appconfig.go | Adds “value + source” resolution fields/methods for Vercel/GitHub targets. |
| internal/config/appconfig_test.go | Adds tests for the new “with source” resolution behavior. |
| cmd/env-sync/validate.go | Adds CLI entrypoint for validate and dispatch to provider validators. |
| cmd/env-sync/validate_test.go | Adds integration-ish tests for validate help and behavior without def/env files. |
| cmd/env-sync/main.go | Routes the new validate subcommand and applies the same language prescan logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+18
to
+20
| func runValidate(args []string, printUsage func()) error { | ||
| opts := config.ParseFlags(args, printUsage, func() {}) | ||
|
|
Comment on lines
+511
to
+513
| defer res.Body.Close() | ||
| d := parseErrorBody(res.Body) | ||
| return res.StatusCode, d, nil |
Comment on lines
+73
to
+78
| // token / projectId が未設定なら API 確認をスキップ | ||
| if tgt.Token == "" || tgt.ProjectID == "" { | ||
| fmt.Fprint(stdoutWriter, i18n.T(i18n.MsgValidateTokenUnsetSkip)) | ||
| ngCount++ | ||
| continue | ||
| } |
Comment on lines
+66
to
+71
| // repo 表示 | ||
| if resolveErr != nil { | ||
| fmt.Fprintf(githubStdoutWriter, " repo : %s (%s)\n", i18n.T(i18n.MsgValidateSourceUnset), githubSourceLabel(repoSrc)) | ||
| fmt.Fprint(githubStdoutWriter, i18n.T(i18n.MsgValidateTokenUnsetSkip)) | ||
| ngCount++ | ||
| continue |
- validate --version でバージョン情報が表示されない問題を修正 (runValidate に printVersion を渡すよう変更) - vercelCheckAccess で 2xx 時もレスポンスボディ全量読みしていた問題を修正 (2xx 時は io.Discard でドレインのみに変更) - Vercel validate で projectId 未設定時も token 未設定メッセージを出していた問題を修正 (MsgValidateProjectIDUnsetSkip キーを追加し、原因別にメッセージを分離) - GitHub validate で repo 解決失敗時も token 未設定メッセージを出していた問題を修正 (MsgValidateRepoUnresolvableSkip キーを追加) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNh5eprge9f7terW2bFujE
Comment on lines
+46
to
+50
| targetLabel := tgt.ProjectID | ||
| if tgt.Name != "" { | ||
| targetLabel = tgt.Name | ||
| } | ||
| fmt.Fprint(stdoutWriter, i18n.T(i18n.MsgValidateHeader, targetLabel)) |
Comment on lines
+60
to
+64
| if tgt.ProjectID == "" { | ||
| fmt.Fprintf(stdoutWriter, " projectId : %s (%s)\n", i18n.T(i18n.MsgValidateSourceUnset), vercelSourceLabel(tgt.ProjectIDSource)) | ||
| } else { | ||
| fmt.Fprint(stdoutWriter, i18n.T(i18n.MsgValidateVercelProjectID, tgt.ProjectID, vercelSourceLabel(tgt.ProjectIDSource))) | ||
| } |
- Vercel validate: name/projectId 両方未設定時のヘッダが空文字になる問題を修正 (targetLabel に MsgValidateSourceUnset をフォールバック) - Vercel validate: projectId 未設定時の表示が "(unset) ((unset))" と二重カッコになる問題を修正 (MsgValidateVercelProjectID テンプレートで統一) - GitHub validate: repo 解決失敗時の表示が "(unset) ((unset))" と二重カッコになる問題を修正 (MsgValidateGitHubRepo テンプレートで統一) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNh5eprge9f7terW2bFujE
Comment on lines
+472
to
+484
| if readErr == nil { | ||
| var pj projectJSON | ||
| if err := json.Unmarshal(pjText, &pj); err != nil { | ||
| return false, fmt.Errorf("%s", i18n.T(i18n.MsgVercelProjectJSONParseFail, err)) | ||
| } | ||
| targets[0].ProjectID = pj.ProjectID | ||
| targets[0].ProjectIDSource = "project_json" | ||
| if targets[0].TeamID == "" && pj.OrgID != "" { | ||
| targets[0].TeamID = pj.OrgID | ||
| targets[0].TeamIDSource = "project_json" | ||
| } | ||
| return true, nil | ||
| } |
|
|
||
| // ----- Validate サブコマンド ----- | ||
|
|
||
| // MsgValidateHeader は validate の対象プロバイダーヘッダ(書式: プロバイダー名)。 |
- applyProjectJSONFallback: project.json に projectId が無い場合も ProjectIDSource を "project_json" に設定していた問題を修正 (pj.ProjectID != "" のときのみ source を更新するよう条件追加) - MsgValidateHeader のコメントを実際の用途(ターゲットラベル)に修正 (「プロバイダー名」→「ターゲットラベル = name / projectId / owner-repo」) - vercel/github validate の HTTP タイムアウトを 30*time.Second の直書きから 各パッケージの httpTimeout 定数を使うよう変更(不要な time import も削除) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNh5eprge9f7terW2bFujE
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.
タスク
env-sync実行時に出る警告(既存 key 取得失敗: HTTP 404: Project not found.等)の原因(teamId 未設定 / token のスコープ違い / projectId 不一致 など)を、設定・認証・API 到達性を読み取り専用で診断するvalidateサブコマンドで self-service で切り分けられるようにする。完了条件
env-sync validateで解決された Vercel target(name / projectId / teamId / token 有無・取得元)が一覧表示されるtokenは値が表示されずマスクされる(完全マスク)validateは環境変数を一切登録・変更しない(GET のみ・読み取り専用)env-sync --helpにvalidateの説明が追加されている実装概要
provider.goに追加。各 provider が自分の検証を実装・出力する設計(provider 抽象を壊さず、未実装 provider は自動的に「未対応」スキップ)GET /v10/projects/{id}/envで到達確認。404→teamId未設定/projectId不一致、401→token無効、403→スコープ不足の推定原因を提示GET /repos/{owner}/{repo}で repo/token の有効性を検証.vercel/project.json/ git remote)を表示。token は完全マスク動作確認
go vet/gofmt/go buildclean)品質チェック結果
reviewer 指摘の Warning 3件はすべて本PRで解消済み:
GetWd/Chdir削除MsgValidateDefWarn/MsgValidateEnvWarn削除stdoutWriterパターンに統一🔵 Info(非ブロッキング・据え置き):
パフォーマンス診断(静的解析・非ブロッキング)
syncOneVercelTargetが env 変数ごとに直列 POST(本PRスコープ外の既存 sync 経路。一括 upsert で改善余地)http.Clientはループ外で1回生成、正規表現はパッケージ変数でコンパイル済み)🤖 Generated with Claude Code