magic-pocket-cli 0.6.0__tar.gz → 0.7.1__tar.gz

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.
Files changed (66) hide show
  1. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/PKG-INFO +2 -2
  2. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/django_cli.py +45 -9
  3. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/neon.py +17 -6
  4. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pyproject.toml +2 -2
  5. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/.gitignore +0 -0
  6. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/__init__.py +0 -0
  7. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/__init__.py +0 -0
  8. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/aws_auth.py +0 -0
  9. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/awscontainer_cli.py +0 -0
  10. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/cloudfront_cli.py +0 -0
  11. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/cloudfront_keys_cli.py +0 -0
  12. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/cloudfront_waf_cli.py +0 -0
  13. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/deploy_cli.py +0 -0
  14. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/destroy_cli.py +0 -0
  15. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/dsql_cli.py +0 -0
  16. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/main_cli.py +0 -0
  17. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/migrate_cli.py +0 -0
  18. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/neon_cli.py +0 -0
  19. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/permissions_cli.py +0 -0
  20. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/rds_cli.py +0 -0
  21. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/runtime_config_cli.py +0 -0
  22. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/s3_cli.py +0 -0
  23. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/status_cli.py +0 -0
  24. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/store_url_helper.py +0 -0
  25. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/tidb_cli.py +0 -0
  26. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/upstash_cli.py +0 -0
  27. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/vpc_cli.py +0 -0
  28. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/cli/waf_cli.py +0 -0
  29. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/mediator.py +0 -0
  30. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/__init__.py +0 -0
  31. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/__init__.py +0 -0
  32. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/builders/__init__.py +0 -0
  33. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/builders/codebuild.py +0 -0
  34. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/builders/depot.py +0 -0
  35. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/builders/docker.py +0 -0
  36. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/builders/dockerignore.py +0 -0
  37. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/cloudformation.py +0 -0
  38. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/ecr.py +0 -0
  39. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/efs.py +0 -0
  40. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/lambdahandler.py +0 -0
  41. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/s3_utils.py +0 -0
  42. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/aws/state.py +0 -0
  43. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/awscontainer.py +0 -0
  44. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/cloudfront.py +0 -0
  45. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/cloudfront_acm.py +0 -0
  46. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/cloudfront_keys.py +0 -0
  47. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/cloudfront_waf.py +0 -0
  48. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/dsql.py +0 -0
  49. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/rds.py +0 -0
  50. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/s3.py +0 -0
  51. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/tidb.py +0 -0
  52. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/upstash.py +0 -0
  53. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/resources/vpc.py +0 -0
  54. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/awscontainer.yaml +0 -0
  55. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/cf_function_api_host.js +0 -0
  56. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/cf_function_spa_auth.js +0 -0
  57. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/cf_function_spa_fallback.js +0 -0
  58. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/cloudfront.yaml +0 -0
  59. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/cloudfront_acm.yaml +0 -0
  60. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/cloudfront_keys.yaml +0 -0
  61. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/cloudfront_waf.yaml +0 -0
  62. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/cloudformation/vpc.yaml +0 -0
  63. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/init/django-dotenv.env +0 -0
  64. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/init/django-settings.py +0 -0
  65. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/init/pocket.Dockerfile +0 -0
  66. {magic_pocket_cli-0.6.0 → magic_pocket_cli-0.7.1}/pocket_cli/templates/init/pocket_simple.toml +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: magic-pocket-cli
3
- Version: 0.6.0
3
+ Version: 0.7.1
4
4
  Summary: CLI and deploy tools for magic-pocket.
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: awscrt>=0.19.0
7
7
  Requires-Dist: click>=8.1.7
8
8
  Requires-Dist: deepdiff>=6.7.1
9
9
  Requires-Dist: jinja2>=3.1.3
10
- Requires-Dist: magic-pocket>=0.6.0
10
+ Requires-Dist: magic-pocket>=0.7.1
11
11
  Requires-Dist: pathspec>=1.0.4
12
12
  Requires-Dist: python-on-whales>=0.68.0
13
13
  Requires-Dist: pyyaml>=6.0.1
@@ -99,7 +99,12 @@ def deploy(stage: str, openpath, yes):
99
99
  def _django_post_deploy(stage: str, *, yes: bool, openpath):
100
100
  """deploy / promote 共通の Django 固有後処理 (collectstatic + migrate + URL)。"""
101
101
  context = Context.from_toml(stage=stage)
102
- if yes or click.confirm("deploystatic?", default=True):
102
+ if _staticfiles_publish_mode(context) == "command":
103
+ echo.info(
104
+ 'staticfiles is publish = "command": skipping deploystatic. '
105
+ "Publish with `pocket django deploystatic --stage %s`." % stage
106
+ )
107
+ elif yes or click.confirm("deploystatic?", default=True):
103
108
  collectstatic_locally(stage)
104
109
  upload_collected_staticfiles(stage)
105
110
  handler = _get_management_command_handler(context)
@@ -181,6 +186,14 @@ def build(stage: str, allow_dirty: bool):
181
186
  echo.success("built and pushed: %s" % target)
182
187
 
183
188
 
189
+ def _staticfiles_publish_mode(context: Context) -> str:
190
+ if context.awscontainer and context.awscontainer.django:
191
+ storage = context.awscontainer.django.storages.get("staticfiles")
192
+ if storage:
193
+ return storage.publish
194
+ return "deploy"
195
+
196
+
184
197
  def _get_management_command_handler(context: Context, key: str | None = None):
185
198
  if not context.awscontainer:
186
199
  raise Exception("awscontainer is not configured for this stage")
@@ -257,7 +270,7 @@ def clear_staticfiles_override_env():
257
270
  os.environ.pop("POCKET_STATICFILES_LOCATION_OVERRIDE", None)
258
271
 
259
272
 
260
- def upload_collected_staticfiles(stage: str):
273
+ def upload_collected_staticfiles(stage: str, *, delete: bool = False):
261
274
  from pocket.django.utils import get_static_storage_s3_options
262
275
 
263
276
  s3_options = get_static_storage_s3_options(stage=stage)
@@ -267,9 +280,15 @@ def upload_collected_staticfiles(stage: str):
267
280
  echo.info("Bucket: %s" % s3_bucket_name)
268
281
  echo.info("Location: %s" % s3_location)
269
282
  echo.info("Uploading static files...")
283
+ cmd = "aws s3 sync %s s3://%s/%s/" % (
284
+ local_storage["OPTIONS"]["location"],
285
+ s3_bucket_name,
286
+ s3_location,
287
+ )
288
+ if delete:
289
+ cmd += " --delete"
270
290
  run( # noqa: S602 aws s3 sync を pocket.toml 設定値から構築 (信頼境界内)
271
- "aws s3 sync %s s3://%s/%s/ --delete"
272
- % (local_storage["OPTIONS"]["location"], s3_bucket_name, s3_location),
291
+ cmd,
273
292
  shell=True, # nosemgrep
274
293
  check=True,
275
294
  )
@@ -299,11 +318,14 @@ def _get_project_dir(stage: str) -> str | None:
299
318
  return None
300
319
 
301
320
 
302
- def collectstatic_locally(stage: str):
321
+ def collectstatic_locally(stage: str, *, link: bool = False):
303
322
  local_storage = get_deploystatic_local_storage(stage)
304
323
  echo.info("collectstatic to %s..." % local_storage["OPTIONS"]["location"])
305
324
  set_staticfiles_override_env(local_storage)
306
- cmd = _build_python_command(["manage.py", "collectstatic", "--noinput"])
325
+ args = ["manage.py", "collectstatic", "--noinput"]
326
+ if link:
327
+ args.append("--link")
328
+ cmd = _build_python_command(args)
307
329
  project_dir = _get_project_dir(stage)
308
330
  run(cmd, check=True, cwd=project_dir) # noqa: S603 shell=False + 制御された引数
309
331
  clear_staticfiles_override_env()
@@ -312,10 +334,24 @@ def collectstatic_locally(stage: str):
312
334
  @django.command()
313
335
  @click.option("--stage", envvar="POCKET_DEPLOY_STAGE", prompt=True)
314
336
  @click.option("--skip-collectstatic", is_flag=True, default=False)
315
- def deploystatic(stage: str, skip_collectstatic: bool):
337
+ @click.option(
338
+ "--delete",
339
+ is_flag=True,
340
+ default=False,
341
+ help="collectstatic 出力に無い S3 上のファイルを削除する (aws s3 sync --delete)。"
342
+ " 旧デプロイのアセットを参照中のリクエストや rollback を壊しうるため opt-in",
343
+ )
344
+ @click.option(
345
+ "--link",
346
+ is_flag=True,
347
+ default=False,
348
+ help="collectstatic に --link を渡す (大容量資産の複製コスト削減。"
349
+ " aws s3 sync は symlink を追うので upload 互換)",
350
+ )
351
+ def deploystatic(stage: str, skip_collectstatic: bool, delete: bool, link: bool):
316
352
  if not skip_collectstatic:
317
- collectstatic_locally(stage)
318
- upload_collected_staticfiles(stage)
353
+ collectstatic_locally(stage, link=link)
354
+ upload_collected_staticfiles(stage, delete=delete)
319
355
 
320
356
 
321
357
  @django.command(
@@ -310,16 +310,27 @@ class Neon:
310
310
  pass
311
311
 
312
312
  def create(self):
313
- # parent_branch_name 指定時はその親から分岐。未指定なら parent_branch=None
314
- # 従来通り Neon default ブランチから分岐する。
315
- self.create_branch(self.parent_branch)
313
+ # branch が既に存在するなら (Neon project 作成時に自動生成される default main
314
+ # を含む) その上に role/database を ensure するだけにし branch 作成はスキップ。
315
+ # parent_branch の解決も branch 不在時のみ行う (存在するのに親を要求して誤って
316
+ # ValueError にしないため)。これで default main を使う stage の初回 deploy が
317
+ # 409 (branch already exists) にならず、既存 branch への db/role bootstrap も
318
+ # deploy で完結する。
319
+ if self.branch is None:
320
+ # parent_branch_name 指定時はその親から分岐。未指定なら parent_branch=None
321
+ # で従来通り Neon default ブランチから分岐する。
322
+ self.create_branch(self.parent_branch)
316
323
  self.ensure_role()
317
324
  self.ensure_database()
318
325
 
319
326
  def create_branch(self, base_branch: Branch | None = None):
320
- if self.branch is None:
321
- del self.branch
322
- del self.endpoint
327
+ # 冪等化: context.branch_name の branch が既に存在するなら POST /branches は
328
+ # 409 (branch already exists) になるため作成をスキップする。branch_out /
329
+ # store_url の呼び出し側も branch 不在を確認済だが、直接呼ばれた場合の防御。
330
+ if self.branch is not None:
331
+ return
332
+ del self.branch
333
+ del self.endpoint
323
334
  data = {
324
335
  "branch": {
325
336
  "name": self.context.branch_name,
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "magic-pocket-cli"
3
- version = "0.6.0"
3
+ version = "0.7.1"
4
4
  description = "CLI and deploy tools for magic-pocket."
5
5
  requires-python = ">=3.10"
6
6
  dependencies = [
7
- "magic-pocket>=0.6.0",
7
+ "magic-pocket>=0.7.1",
8
8
  "click>=8.1.7",
9
9
  "jinja2>=3.1.3",
10
10
  "python-on-whales>=0.68.0",