repro-lambda 0.8.0__tar.gz → 0.8.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 (82) hide show
  1. repro_lambda-0.8.1/.release-please-manifest.json +3 -0
  2. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/CHANGELOG.md +7 -0
  3. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/PKG-INFO +1 -1
  4. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/pyproject.toml +1 -1
  5. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/__init__.py +1 -1
  6. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/sources.py +11 -2
  7. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_sources.py +54 -0
  8. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/uv.lock +1 -1
  9. repro_lambda-0.8.0/.release-please-manifest.json +0 -3
  10. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/.github/workflows/build.yml +0 -0
  11. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/.github/workflows/ci.yml +0 -0
  12. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/.github/workflows/move-major-tag.yml +0 -0
  13. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/.github/workflows/promote.yml +0 -0
  14. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/.github/workflows/publish.yml +0 -0
  15. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/.github/workflows/release.yml +0 -0
  16. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/.gitignore +0 -0
  17. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/.pre-commit-config.yaml +0 -0
  18. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/LICENSE +0 -0
  19. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/README.md +0 -0
  20. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/SETUP.md +0 -0
  21. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/USAGE.md +0 -0
  22. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/assets/social-preview.html +0 -0
  23. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/assets/social-preview.png +0 -0
  24. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/README.md +0 -0
  25. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/builds/catalog.json +0 -0
  26. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/lambdas.toml +0 -0
  27. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/main.tf +0 -0
  28. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/outputs.tf +0 -0
  29. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/src/app/app.py +0 -0
  30. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/src/app/requirements.arm64.lock +0 -0
  31. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/variables.tf +0 -0
  32. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/examples/complete/versions.tf +0 -0
  33. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/release-please-config.json +0 -0
  34. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/__main__.py +0 -0
  35. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/build.py +0 -0
  36. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/catalog.py +0 -0
  37. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/cli.py +0 -0
  38. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/docker_runner.py +0 -0
  39. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/git_guard.py +0 -0
  40. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/hasher.py +0 -0
  41. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/manifest.py +0 -0
  42. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/promote.py +0 -0
  43. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/s3_uploader.py +0 -0
  44. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/source_locker.py +0 -0
  45. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/source_stager.py +0 -0
  46. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/verify.py +0 -0
  47. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/src/repro_lambda/zip_packager.py +0 -0
  48. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/__init__.py +0 -0
  49. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/conftest.py +0 -0
  50. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/fixtures/sample_nodejs_lambda/handler/index.js +0 -0
  51. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/fixtures/sample_nodejs_lambda/handler/package-lock.json +0 -0
  52. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/fixtures/sample_nodejs_lambda/handler/package.json +0 -0
  53. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/fixtures/sample_nodejs_lambda/lambdas.toml +0 -0
  54. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/fixtures/sample_python_lambda/handler/app.py +0 -0
  55. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/fixtures/sample_python_lambda/handler/requirements.arm64.lock +0 -0
  56. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/fixtures/sample_python_lambda/handler/requirements.in +0 -0
  57. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/fixtures/sample_python_lambda/lambdas.toml +0 -0
  58. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_build_integration.py +0 -0
  59. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_build_nodejs.py +0 -0
  60. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_catalog.py +0 -0
  61. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_cli_build.py +0 -0
  62. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_cli_lock.py +0 -0
  63. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_cli_smoke.py +0 -0
  64. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_docker_runner.py +0 -0
  65. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_docker_runner_nodejs.py +0 -0
  66. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_e2e_nodejs_lambda.py +0 -0
  67. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_e2e_python_lambda.py +0 -0
  68. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_extra_files.py +0 -0
  69. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_git_guard.py +0 -0
  70. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_hasher.py +0 -0
  71. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_manifest.py +0 -0
  72. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_per_lambda_builder.py +0 -0
  73. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_promote.py +0 -0
  74. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_python_byte_compat_regression.py +0 -0
  75. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_s3_uploader.py +0 -0
  76. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_source_locker.py +0 -0
  77. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_source_stager.py +0 -0
  78. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_sources_hash.py +0 -0
  79. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_sources_schema.py +0 -0
  80. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_verify.py +0 -0
  81. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_zip_excludes.py +0 -0
  82. {repro_lambda-0.8.0 → repro_lambda-0.8.1}/tests/test_zip_packager.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.8.1"
3
+ }
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.1](https://github.com/antonbabenko/repro-lambda/compare/v0.8.0...v0.8.1) (2026-09-23)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **sources:** fall back to the release assets endpoint when the tag view lists none ([#17](https://github.com/antonbabenko/repro-lambda/issues/17)) ([3a5608b](https://github.com/antonbabenko/repro-lambda/commit/3a5608b8cd7294f66986b1a61e4607efd052163a))
9
+
3
10
  ## [0.8.0](https://github.com/antonbabenko/repro-lambda/compare/v0.7.2...v0.8.0) (2026-09-18)
4
11
 
5
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: repro-lambda
3
- Version: 0.8.0
3
+ Version: 0.8.1
4
4
  Summary: Build reproducible AWS Lambda packages outside Terraform, optimized for terraform-aws-lambda by serverless.tf.
5
5
  Project-URL: Homepage, https://github.com/antonbabenko/repro-lambda
6
6
  Project-URL: Repository, https://github.com/antonbabenko/repro-lambda
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "repro-lambda"
3
- version = "0.8.0"
3
+ version = "0.8.1"
4
4
  description = "Build reproducible AWS Lambda packages outside Terraform, optimized for terraform-aws-lambda by serverless.tf."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  """repro-lambda — reproducible AWS Lambda packaging outside Terraform."""
2
2
 
3
- __version__ = "0.8.0" # x-release-please-version
3
+ __version__ = "0.8.1" # x-release-please-version
@@ -34,6 +34,7 @@ import tempfile
34
34
  import zipfile
35
35
  from http.client import HTTPSConnection
36
36
  from pathlib import Path
37
+ from typing import Any
37
38
  from urllib.parse import urljoin, urlsplit, urlunsplit
38
39
 
39
40
  from repro_lambda import __version__
@@ -183,7 +184,7 @@ def _stream_to(resp, sink: io.BufferedWriter, max_bytes: int) -> str:
183
184
  return h.hexdigest()
184
185
 
185
186
 
186
- def _http_get_json(url: str, headers: dict[str, str]) -> dict:
187
+ def _http_get_json(url: str, headers: dict[str, str]) -> Any:
187
188
  buf = io.BytesIO()
188
189
  writer = io.BufferedWriter(_RawSink(buf))
189
190
  _http_request(url, headers, writer, _JSON_MAX_BYTES)
@@ -219,7 +220,15 @@ def _github_asset_url(src: Source, token: str | None) -> tuple[str, dict[str, st
219
220
  auth = {"Authorization": f"Bearer {token}", "Accept": "application/vnd.github+json"}
220
221
  release = _http_get_json(api, auth)
221
222
  want = src.resolved_asset
222
- for asset in release.get("assets", []):
223
+ assets = release.get("assets", [])
224
+ if not any(a.get("name") == want for a in assets) and "id" in release:
225
+ # The tag view can serve a stale, empty `assets` list for a while after an
226
+ # upload; the per-release assets endpoint is current.
227
+ # ponytail: first 100 assets only, paginate if a release ever carries more.
228
+ assets = _http_get_json(
229
+ f"{_GITHUB_API}/repos/{src.repo}/releases/{release['id']}/assets?per_page=100", auth
230
+ )
231
+ for asset in assets:
223
232
  if asset.get("name") == want:
224
233
  asset_id = asset["id"]
225
234
  dl = f"{_GITHUB_API}/repos/{src.repo}/releases/assets/{asset_id}"
@@ -358,6 +358,60 @@ def test_github_source_requires_token(tmp_path: Path):
358
358
  sources._github_asset_url(src, None)
359
359
 
360
360
 
361
+ def _gh_src() -> Source:
362
+ return Source(
363
+ name="p",
364
+ type="github_release",
365
+ sha256=SHA_PLACEHOLDER,
366
+ extract="tar.gz",
367
+ dest="p",
368
+ repo="o/r",
369
+ tag="t",
370
+ asset="a.tgz",
371
+ )
372
+
373
+
374
+ def test_github_asset_falls_back_to_assets_endpoint(monkeypatch):
375
+ # GitHub can serve releases/tags/<tag> with a stale, empty `assets` list right after
376
+ # an upload, while /releases/{id}/assets already lists the file.
377
+ calls = []
378
+
379
+ def fake_get(url, headers):
380
+ calls.append(url)
381
+ if url.endswith("/releases/tags/t"):
382
+ return {"id": 7, "assets": []}
383
+ assert url.endswith("/releases/7/assets?per_page=100")
384
+ return [{"name": "other", "id": 1}, {"name": "a.tgz", "id": 42}]
385
+
386
+ monkeypatch.setattr(sources, "_http_get_json", fake_get)
387
+ url, headers = sources._github_asset_url(_gh_src(), "tok")
388
+ assert url.endswith("/repos/o/r/releases/assets/42")
389
+ assert headers["Accept"] == "application/octet-stream"
390
+ assert len(calls) == 2
391
+
392
+
393
+ def test_github_asset_embedded_list_needs_no_second_call(monkeypatch):
394
+ calls = []
395
+
396
+ def fake_get(url, headers):
397
+ calls.append(url)
398
+ return {"id": 7, "assets": [{"name": "a.tgz", "id": 42}]}
399
+
400
+ monkeypatch.setattr(sources, "_http_get_json", fake_get)
401
+ url, _ = sources._github_asset_url(_gh_src(), "tok")
402
+ assert url.endswith("/releases/assets/42")
403
+ assert len(calls) == 1
404
+
405
+
406
+ def test_github_asset_missing_everywhere_raises(monkeypatch):
407
+ def fake_get(url, headers):
408
+ return {"id": 7, "assets": []} if url.endswith("/tags/t") else []
409
+
410
+ monkeypatch.setattr(sources, "_http_get_json", fake_get)
411
+ with pytest.raises(SourceFetchError, match="not found"):
412
+ sources._github_asset_url(_gh_src(), "tok")
413
+
414
+
361
415
  # --- staging + end-to-end (no network) -------------------------------------
362
416
 
363
417
 
@@ -646,7 +646,7 @@ wheels = [
646
646
 
647
647
  [[package]]
648
648
  name = "repro-lambda"
649
- version = "0.8.0"
649
+ version = "0.8.1"
650
650
  source = { editable = "." }
651
651
  dependencies = [
652
652
  { name = "boto3" },
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.8.0"
3
- }
File without changes
File without changes
File without changes
File without changes
File without changes