Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c2630b972 |
+11
-10
@@ -183,26 +183,24 @@ def s3_sync(artifact, route, site_dir, credential_env_names=None):
|
||||
if _is_immutable(rule):
|
||||
publish_immutable_rule(artifact, route, rule, html_dir, aws_env)
|
||||
print(f"Syncing artifact {artifact['name']} → {destination} via {endpoint}")
|
||||
# Sync and deletion are scoped to the current route prefix. A route move
|
||||
# Upload with the final cache policy before cleanup. Sync and deletion are
|
||||
# scoped to the same current route prefix and cache partition. A route move
|
||||
# leaves its old bucket partition intact but unreachable after the old
|
||||
# Ingress disappears, while stale mutable keys on the serving prefix are
|
||||
# deleted. Immutable subtrees are structurally excluded. Partitioned
|
||||
# `cp --recursive` calls then re-upload each file once to refresh metadata
|
||||
# (cache-control, content-type) on objects sync skipped as unchanged.
|
||||
# deleted. Immutable subtrees are structurally excluded. `cp --recursive`
|
||||
# refreshes metadata atomically per object before `sync --delete` removes
|
||||
# stale keys without ever exposing new bytes under a provisional policy.
|
||||
# A no-op deploy therefore transfers the artifact bytes once.
|
||||
# AWS CLI guesses Content-Type from file extension on local→S3 uploads,
|
||||
# so a fresh upload always carries the right MIME type.
|
||||
sync_excludes = [*exclude_args,
|
||||
*(arg for path in immutable_paths for arg in ("--exclude", f"{path}/*"))]
|
||||
run(["aws", "--endpoint-url", endpoint, "s3", "sync", f"{html_dir}/", destination,
|
||||
"--delete", "--only-show-errors", "--cache-control", default_cache,
|
||||
*sync_excludes], env=aws_env)
|
||||
print("Re-stamping metadata on all objects...")
|
||||
specific_paths = [rule["path"] for rule in artifact["cache_rules"] if rule["path"]]
|
||||
default_filters = [arg for path in specific_paths for arg in ("--exclude", f"{path}/*")]
|
||||
run(["aws", "--endpoint-url", endpoint, "s3", "cp", f"{html_dir}/", destination,
|
||||
"--recursive", "--only-show-errors", "--cache-control", default_cache,
|
||||
*default_filters, *exclude_args], env=aws_env)
|
||||
run(["aws", "--endpoint-url", endpoint, "s3", "sync", f"{html_dir}/", destination,
|
||||
"--delete", "--only-show-errors", "--cache-control", default_cache,
|
||||
*default_filters, *exclude_args], env=aws_env)
|
||||
for rule in artifact["cache_rules"]:
|
||||
if not rule["path"]:
|
||||
continue
|
||||
@@ -217,6 +215,9 @@ def s3_sync(artifact, route, site_dir, credential_env_names=None):
|
||||
run(["aws", "--endpoint-url", endpoint, "s3", "cp", f"{html_dir}/", destination,
|
||||
"--recursive", "--only-show-errors", "--cache-control", rule["cache_control"],
|
||||
"--exclude", "*", "--include", include, *child_filters, *exclude_args], env=aws_env)
|
||||
run(["aws", "--endpoint-url", endpoint, "s3", "sync", f"{html_dir}/", destination,
|
||||
"--delete", "--only-show-errors", "--cache-control", rule["cache_control"],
|
||||
"--exclude", "*", "--include", include, *child_filters, *exclude_args], env=aws_env)
|
||||
|
||||
|
||||
def garage_admin(method, path, token, body=None):
|
||||
|
||||
@@ -405,7 +405,8 @@ class PublishingTests(unittest.TestCase):
|
||||
rendered = [" ".join(command) for command, _ in commands]
|
||||
self.assertIn("s3://baseline-dist/dist/", rendered[0])
|
||||
self.assertIn("releases/*", rendered[0])
|
||||
self.assertIn("--delete", rendered[0])
|
||||
self.assertNotIn("--delete", rendered[0])
|
||||
self.assertIn("--delete", rendered[1])
|
||||
self.assertTrue(all("s3://baseline-dist/dist/" in command for command in rendered[1:]))
|
||||
self.assertTrue(any("channels/" in command and
|
||||
"public, max-age=0, must-revalidate" in command
|
||||
|
||||
Reference in New Issue
Block a user