i-repo 2.14.0 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugins/i-repo-archive +86 -4
package/package.json
CHANGED
package/plugins/i-repo-archive
CHANGED
|
@@ -44,7 +44,7 @@ async function loadBuiltins() {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
const PLUGIN = "i-repo-archive";
|
|
47
|
-
const VERSION = "0.6.
|
|
47
|
+
const VERSION = "0.6.3";
|
|
48
48
|
const PLUGIN_API = "1";
|
|
49
49
|
const defaultArchiveRoot = () => join(homedir(), ".i-repo", "archives");
|
|
50
50
|
|
|
@@ -179,6 +179,19 @@ if (arg0 === "--plugin-schema") {
|
|
|
179
179
|
{ name: "--cleanup", type: "boolean", subcommand: "push-s3", destructive: true,
|
|
180
180
|
label: "Clean up local archive",
|
|
181
181
|
description: "Delete the local archive directory after the upload is verified" },
|
|
182
|
+
// push-s3 無人認証(#92・push-azure と同作法): 値は argv ではなく env で aws に渡す。
|
|
183
|
+
{ name: "--access-key-id", type: "string", subcommand: "push-s3", envVar: "AWS_ACCESS_KEY_ID",
|
|
184
|
+
label: "AWS アクセスキーID(任意・無人用)",
|
|
185
|
+
description: "IAM アクセスキーID。値は環境変数 AWS_ACCESS_KEY_ID で aws に渡す(対話 aws sso login 不要で無人化)" },
|
|
186
|
+
{ name: "--secret-access-key", type: "string", subcommand: "push-s3", secret: true, envVar: "AWS_SECRET_ACCESS_KEY",
|
|
187
|
+
label: "AWS シークレットアクセスキー(任意・無人用)",
|
|
188
|
+
description: "IAM シークレットアクセスキー。値は argv に出さず環境変数 AWS_SECRET_ACCESS_KEY で aws に渡す" },
|
|
189
|
+
{ name: "--profile", type: "string", subcommand: "push-s3", envVar: "AWS_PROFILE",
|
|
190
|
+
label: "AWS プロファイル(任意)",
|
|
191
|
+
description: "named profile(~/.aws 構成)。値は環境変数 AWS_PROFILE で aws に渡す" },
|
|
192
|
+
{ name: "--region", type: "string", subcommand: "push-s3", envVar: "AWS_REGION",
|
|
193
|
+
label: "AWS リージョン(任意)",
|
|
194
|
+
description: "リージョン。値は環境変数 AWS_REGION で aws に渡す" },
|
|
182
195
|
// push-gcs
|
|
183
196
|
{ name: "--to", type: "string", required: true, subcommand: "push-gcs",
|
|
184
197
|
label: "GCS destination", placeholder: "gs://bucket/prefix",
|
|
@@ -190,6 +203,10 @@ if (arg0 === "--plugin-schema") {
|
|
|
190
203
|
{ name: "--cleanup", type: "boolean", subcommand: "push-gcs", destructive: true,
|
|
191
204
|
label: "Clean up local archive",
|
|
192
205
|
description: "Delete the local archive directory after the upload is verified" },
|
|
206
|
+
// push-gcs 無人認証(#92): SA 鍵 JSON の**パス**を env(GOOGLE_APPLICATION_CREDENTIALS)で gcloud に渡す。
|
|
207
|
+
{ name: "--gcp-credentials", type: "string", subcommand: "push-gcs", envVar: "GOOGLE_APPLICATION_CREDENTIALS",
|
|
208
|
+
label: "GCP サービスアカウント鍵のパス(任意・無人用)",
|
|
209
|
+
description: "サービスアカウント鍵 JSON のファイルパス(鍵そのものではない)。env GOOGLE_APPLICATION_CREDENTIALS で受け、プラグインが gcloud CLI 用に CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE へも複写して無人化(対話 gcloud auth login 不要)" },
|
|
193
210
|
// push-azure
|
|
194
211
|
{ name: "--to", type: "string", required: true, subcommand: "push-azure",
|
|
195
212
|
label: "Azure Blob destination", placeholder: "https://<account>.blob.core.windows.net/<container>/<prefix>",
|
|
@@ -222,8 +239,13 @@ if (arg0 === "--plugin-schema") {
|
|
|
222
239
|
// pull-*(取り戻し・host 管理。GUI 配信フォームには出ない=mode:read。Rust が固定引数で渡す)
|
|
223
240
|
{ name: "--from", type: "string", subcommand: "pull-s3", description: "取得元 s3://bucket/prefix(着地した bundle のルート)" },
|
|
224
241
|
{ name: "--out", type: "string", subcommand: "pull-s3", description: "取得先ローカルディレクトリ" },
|
|
242
|
+
{ name: "--access-key-id", type: "string", subcommand: "pull-s3", envVar: "AWS_ACCESS_KEY_ID", description: "無人取り戻し用 IAM アクセスキーID(env AWS_ACCESS_KEY_ID)" },
|
|
243
|
+
{ name: "--secret-access-key", type: "string", subcommand: "pull-s3", secret: true, envVar: "AWS_SECRET_ACCESS_KEY", description: "無人取り戻し用 IAM シークレットキー(env のみ・argv 非掲載)" },
|
|
244
|
+
{ name: "--profile", type: "string", subcommand: "pull-s3", envVar: "AWS_PROFILE", description: "AWS named profile(env AWS_PROFILE)" },
|
|
245
|
+
{ name: "--region", type: "string", subcommand: "pull-s3", envVar: "AWS_REGION", description: "AWS リージョン(env AWS_REGION)" },
|
|
225
246
|
{ name: "--from", type: "string", subcommand: "pull-gcs", description: "取得元 gs://bucket/prefix" },
|
|
226
247
|
{ name: "--out", type: "string", subcommand: "pull-gcs", description: "取得先ローカルディレクトリ" },
|
|
248
|
+
{ name: "--gcp-credentials", type: "string", subcommand: "pull-gcs", envVar: "GOOGLE_APPLICATION_CREDENTIALS", description: "無人取り戻し用 SA 鍵 JSON のパス(env GOOGLE_APPLICATION_CREDENTIALS)" },
|
|
227
249
|
{ name: "--from", type: "string", subcommand: "pull-azure", description: "取得元 https://<account>.blob.core.windows.net/<container>/<prefix>" },
|
|
228
250
|
{ name: "--out", type: "string", subcommand: "pull-azure", description: "取得先ローカルディレクトリ" },
|
|
229
251
|
{ name: "--sas", type: "string", subcommand: "pull-azure", secret: true, envVar: "AZURE_STORAGE_SAS_TOKEN",
|
|
@@ -350,15 +372,23 @@ function usage() {
|
|
|
350
372
|
--history --regist-from --regist-to --update-from --update-to
|
|
351
373
|
-k/--system-key <n=v> (repeatable)
|
|
352
374
|
${PLUGIN} push-s3 <archive-dir> --to s3://bucket/prefix [--cleanup] [--dry-run]
|
|
375
|
+
[--access-key-id <id> --secret-access-key <key> | --profile <name>] [--region <r>]
|
|
353
376
|
${PLUGIN} push-gcs <archive-dir> --to gs://bucket/prefix [--cleanup] [--dry-run]
|
|
377
|
+
[--gcp-credentials <service-account-key.json path>]
|
|
354
378
|
${PLUGIN} push-azure <archive-dir> --to https://<account>.blob.core.windows.net/<container>/<prefix>
|
|
355
379
|
[--sas <token> | --connection-string <cs>] [--cleanup] [--dry-run]
|
|
356
380
|
${PLUGIN} push-local <archive-dir> --to <folder|network-share path> [--cleanup] [--dry-run]
|
|
357
381
|
--cleanup Delete the local archive after the upload is verified
|
|
358
382
|
(gcs requires gcloud; azure requires az CLI. push-local needs no external CLI
|
|
359
383
|
(Node fs copy) and accepts a plain folder or mounted network-share path.
|
|
360
|
-
|
|
361
|
-
|
|
384
|
+
Unattended creds are read from the flags above OR env
|
|
385
|
+
(s3: AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_PROFILE/AWS_REGION; gcs:
|
|
386
|
+
GOOGLE_APPLICATION_CREDENTIALS; azure: AZURE_STORAGE_*) and passed to the
|
|
387
|
+
cloud CLI via env, never argv — no interactive login needed.
|
|
388
|
+
Note: AWS keys are a pair (both required); --profile and IAM keys are mutually
|
|
389
|
+
exclusive. When run under \`i-repo\` (dispatch/deliver) the parent env is
|
|
390
|
+
allow-listed, so pass creds via these flags, host env-injection, or
|
|
391
|
+
\`i-repo config set pluginPassEnv "AWS_*,GOOGLE_APPLICATION_CREDENTIALS,AZURE_STORAGE_*"\`)`);
|
|
362
392
|
}
|
|
363
393
|
|
|
364
394
|
// ── Tiny argv parser (no dependencies) ─────────────────────────────────────
|
|
@@ -475,8 +505,13 @@ function normalizeLocalDest(to) {
|
|
|
475
505
|
function parsePushArgs(argv, backend) {
|
|
476
506
|
const label = `push-${backend.store}`;
|
|
477
507
|
const spec = { "--to": "value", "--prefix": "value", "--dry-run": "flag", "--cleanup": "flag" };
|
|
478
|
-
//
|
|
508
|
+
// 無人認証フラグ(#92)。secret 値は argv に出さず env でクラウド CLI に渡す(buildPushEnv 参照)。
|
|
479
509
|
if (backend.store === "azure") { spec["--sas"] = "value"; spec["--connection-string"] = "value"; }
|
|
510
|
+
if (backend.store === "s3") {
|
|
511
|
+
spec["--access-key-id"] = "value"; spec["--secret-access-key"] = "value";
|
|
512
|
+
spec["--profile"] = "value"; spec["--region"] = "value";
|
|
513
|
+
}
|
|
514
|
+
if (backend.store === "gcs") { spec["--gcp-credentials"] = "value"; }
|
|
480
515
|
const o = parseArgv(argv, spec, label);
|
|
481
516
|
if (o._.length !== 1) throw new Error(`${label} requires exactly one <archive-dir> argument.`);
|
|
482
517
|
// local は scheme 付き URL ではなくファイルパス(フォルダ/ネットワーク共有)。scheme 検査を外し、
|
|
@@ -499,6 +534,10 @@ function parsePushArgs(argv, backend) {
|
|
|
499
534
|
out.sas = o.sas || process.env.AZURE_STORAGE_SAS_TOKEN || "";
|
|
500
535
|
out.connectionString = o["connection-string"] || process.env.AZURE_STORAGE_CONNECTION_STRING || "";
|
|
501
536
|
}
|
|
537
|
+
// s3/gcs 無人認証(#92)。フラグ指定時のみ拾う(未指定なら ambient/host 注入の env が
|
|
538
|
+
// buildPushEnv の {...process.env} で素通り=envVar 宣言と整合)。
|
|
539
|
+
if (backend.store === "s3") Object.assign(out, s3CredsFromArgs(o, label));
|
|
540
|
+
if (backend.store === "gcs") out.gcpCredentials = o["gcp-credentials"] || "";
|
|
502
541
|
return out;
|
|
503
542
|
}
|
|
504
543
|
|
|
@@ -666,6 +705,26 @@ function joinUri(prefix, child) {
|
|
|
666
705
|
}
|
|
667
706
|
|
|
668
707
|
// secret(SAS / 接続文字列)は argv に載せず az が読む環境変数で渡す(AGENTS.md / 本番化方針)。
|
|
708
|
+
/**
|
|
709
|
+
* s3 無人認証フラグを検証して取り出す(#92)。IAM キーは**対**でのみ意味を持つ
|
|
710
|
+
* (AWS は片方だけだと "Partial credentials" で失敗し、明示キーは profile/ambient より
|
|
711
|
+
* 優先されるため)。キーと --profile の併用も aws では profile が黙殺されるので拒否する
|
|
712
|
+
* (usage は排他表記)。フラグ無指定時は ambient/host 注入の env が素通り。
|
|
713
|
+
*/
|
|
714
|
+
function s3CredsFromArgs(o, label) {
|
|
715
|
+
const accessKeyId = o["access-key-id"] || "";
|
|
716
|
+
const secretAccessKey = o["secret-access-key"] || "";
|
|
717
|
+
const profile = o.profile || "";
|
|
718
|
+
const region = o.region || "";
|
|
719
|
+
if (Boolean(accessKeyId) !== Boolean(secretAccessKey)) {
|
|
720
|
+
throw new Error(`${label}: --access-key-id and --secret-access-key must be provided together.`);
|
|
721
|
+
}
|
|
722
|
+
if ((accessKeyId || secretAccessKey) && profile) {
|
|
723
|
+
throw new Error(`${label}: use either IAM keys (--access-key-id/--secret-access-key) or --profile, not both.`);
|
|
724
|
+
}
|
|
725
|
+
return { accessKeyId, secretAccessKey, profile, region };
|
|
726
|
+
}
|
|
727
|
+
|
|
669
728
|
function buildPushEnv(options) {
|
|
670
729
|
const env = { ...process.env };
|
|
671
730
|
if (options.connectionString) env.AZURE_STORAGE_CONNECTION_STRING = options.connectionString;
|
|
@@ -674,6 +733,21 @@ function buildPushEnv(options) {
|
|
|
674
733
|
// RBAC-only / listKeys 無効アカウントで失敗するため・Codex #76 P2)。s3/gcs は options.azure
|
|
675
734
|
// 未設定なので素通り。
|
|
676
735
|
else if (options.azure) env.AZURE_STORAGE_AUTH_MODE = "login";
|
|
736
|
+
// s3 無人認証(#92): フラグ指定時に env を上書き。未指定なら ambient/host 注入が素通り。
|
|
737
|
+
if (options.accessKeyId) env.AWS_ACCESS_KEY_ID = options.accessKeyId;
|
|
738
|
+
if (options.secretAccessKey) env.AWS_SECRET_ACCESS_KEY = options.secretAccessKey;
|
|
739
|
+
if (options.profile) env.AWS_PROFILE = options.profile;
|
|
740
|
+
// AWS_REGION(CLI v2)と AWS_DEFAULT_REGION(v1/botocore 系)の双方を立てる。
|
|
741
|
+
if (options.region) { env.AWS_REGION = options.region; env.AWS_DEFAULT_REGION = options.region; }
|
|
742
|
+
// gcs 無人認証(#92): SA 鍵パスを env で渡す(対話 login 不要)。
|
|
743
|
+
// GOOGLE_APPLICATION_CREDENTIALS は ADC/クライアントライブラリ用で、**gcloud CLI 自体は
|
|
744
|
+
// 読まない**(gcloud は CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE を読む・Codex #93 P1)。
|
|
745
|
+
// 両方を立てて gcloud storage と client-lib の双方をカバーする。フラグが無くても
|
|
746
|
+
// ambient/host 注入の GOOGLE_APPLICATION_CREDENTIALS があれば gcloud 用に複写する。
|
|
747
|
+
if (options.gcpCredentials) env.GOOGLE_APPLICATION_CREDENTIALS = options.gcpCredentials;
|
|
748
|
+
if (env.GOOGLE_APPLICATION_CREDENTIALS && !env.CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE) {
|
|
749
|
+
env.CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE = env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
750
|
+
}
|
|
677
751
|
return env;
|
|
678
752
|
}
|
|
679
753
|
|
|
@@ -876,7 +950,13 @@ async function pushArchiveBundle(options, backend) {
|
|
|
876
950
|
function parsePullArgs(argv, backend) {
|
|
877
951
|
const label = `pull-${backend.store}`;
|
|
878
952
|
const spec = { "--from": "value", "--out": "value" };
|
|
953
|
+
// 無人認証(#92・push と対称): pull も対話ログイン無しで取り戻せる。
|
|
879
954
|
if (backend.store === "azure") { spec["--sas"] = "value"; spec["--connection-string"] = "value"; }
|
|
955
|
+
if (backend.store === "s3") {
|
|
956
|
+
spec["--access-key-id"] = "value"; spec["--secret-access-key"] = "value";
|
|
957
|
+
spec["--profile"] = "value"; spec["--region"] = "value";
|
|
958
|
+
}
|
|
959
|
+
if (backend.store === "gcs") { spec["--gcp-credentials"] = "value"; }
|
|
880
960
|
const o = parseArgv(argv, spec, label);
|
|
881
961
|
if (!o.from) throw new Error(`${label} requires --from ${backend.scheme || "<source>"}…`);
|
|
882
962
|
if (!o.out) throw new Error(`${label} requires --out <local-dir>.`);
|
|
@@ -895,6 +975,8 @@ function parsePullArgs(argv, backend) {
|
|
|
895
975
|
out.sas = o.sas || process.env.AZURE_STORAGE_SAS_TOKEN || "";
|
|
896
976
|
out.connectionString = o["connection-string"] || process.env.AZURE_STORAGE_CONNECTION_STRING || "";
|
|
897
977
|
}
|
|
978
|
+
if (backend.store === "s3") Object.assign(out, s3CredsFromArgs(o, label));
|
|
979
|
+
if (backend.store === "gcs") out.gcpCredentials = o["gcp-credentials"] || "";
|
|
898
980
|
return out;
|
|
899
981
|
}
|
|
900
982
|
|