repro-lambda 0.2.3__tar.gz → 0.2.4__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.
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/.github/workflows/build.yml +1 -1
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/CHANGELOG.md +5 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/PKG-INFO +1 -1
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/pyproject.toml +1 -1
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/__init__.py +1 -1
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/cli.py +14 -1
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/docker_runner.py +3 -9
- repro_lambda-0.2.4/tests/test_zip_excludes.py +38 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/uv.lock +1 -1
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/.github/workflows/ci.yml +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/.github/workflows/publish.yml +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/.gitignore +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/.pre-commit-config.yaml +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/LICENSE +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/README.md +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/SETUP.md +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/__main__.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/build.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/catalog.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/git_guard.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/hasher.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/manifest.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/s3_uploader.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/source_stager.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/verify.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/src/repro_lambda/zip_packager.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/__init__.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/conftest.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_nodejs_lambda/handler/index.js +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_nodejs_lambda/handler/package-lock.json +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_nodejs_lambda/handler/package.json +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_nodejs_lambda/lambdas.toml +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_python_lambda/handler/app.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_python_lambda/handler/requirements.arm64.lock +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_python_lambda/handler/requirements.in +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_python_lambda/lambdas.toml +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_build_integration.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_build_nodejs.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_catalog.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_cli_build.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_cli_lock.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_cli_smoke.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_docker_runner.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_docker_runner_nodejs.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_e2e_nodejs_lambda.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_e2e_python_lambda.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_git_guard.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_hasher.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_manifest.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_python_byte_compat_regression.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_s3_uploader.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_source_stager.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_verify.py +0 -0
- {repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/test_zip_packager.py +0 -0
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.2.4 - 2026-06-20
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Container build no longer shells out to `find`/`xargs` (both absent from the minimal AWS Lambda base images, which caused `find: command not found`). The post-install cleanup (Python caches + non-deterministic `*.dist-info` metadata: RECORD, INSTALLER, direct_url.json, REQUESTED) now happens in the Python zip step via exclude globs, producing the same artifact bytes.
|
|
7
|
+
|
|
3
8
|
## v0.2.3 - 2026-06-20
|
|
4
9
|
|
|
5
10
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: repro-lambda
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
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
|
|
@@ -220,11 +220,24 @@ def init() -> None:
|
|
|
220
220
|
raise typer.Exit(0)
|
|
221
221
|
|
|
222
222
|
|
|
223
|
+
# Stripped from every lambda zip so the container build needs no findutils/xargs
|
|
224
|
+
# (absent from minimal Lambda base images): Python caches and the non-deterministic
|
|
225
|
+
# dist-info metadata files pip writes (RECORD, INSTALLER, direct_url.json, REQUESTED).
|
|
226
|
+
_LAMBDA_ZIP_EXCLUDES = [
|
|
227
|
+
"*__pycache__*",
|
|
228
|
+
"*.pyc",
|
|
229
|
+
"*.dist-info/RECORD",
|
|
230
|
+
"*.dist-info/INSTALLER",
|
|
231
|
+
"*.dist-info/direct_url.json",
|
|
232
|
+
"*.dist-info/REQUESTED",
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
|
|
223
236
|
def _zip_impl(src: Path, out: Path) -> None:
|
|
224
237
|
"""Pack a directory into a deterministic zip (used inside container)."""
|
|
225
238
|
from repro_lambda.zip_packager import pack_directory
|
|
226
239
|
|
|
227
|
-
pack_directory(src, out)
|
|
240
|
+
pack_directory(src, out, exclude_glob=_LAMBDA_ZIP_EXCLUDES)
|
|
228
241
|
|
|
229
242
|
|
|
230
243
|
@app.command(name="zip")
|
|
@@ -50,15 +50,9 @@ pip install \
|
|
|
50
50
|
--target "$PKG" \
|
|
51
51
|
--requirement /src/requirements.lock
|
|
52
52
|
|
|
53
|
-
#
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
find "$PKG" -type d -name "*.dist-info" -exec sh -c '
|
|
57
|
-
for d; do
|
|
58
|
-
rm -f -- "$d/RECORD" "$d/INSTALLER" "$d/direct_url.json" "$d/REQUESTED"
|
|
59
|
-
done
|
|
60
|
-
' _ {} +
|
|
61
|
-
|
|
53
|
+
# Byte-output cleanup (caches + non-deterministic dist-info metadata) happens in the
|
|
54
|
+
# Python zip step below, so this script needs no findutils/xargs (both absent from the
|
|
55
|
+
# minimal AWS Lambda base images).
|
|
62
56
|
python3 -m repro_lambda zip --src "$PKG" --out /out/lambda.zip
|
|
63
57
|
"""
|
|
64
58
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from zipfile import ZipFile
|
|
3
|
+
|
|
4
|
+
from typer.testing import CliRunner
|
|
5
|
+
|
|
6
|
+
from repro_lambda.cli import app
|
|
7
|
+
|
|
8
|
+
runner = CliRunner()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_zip_excludes_caches_and_dist_info_metadata(tmp_path: Path):
|
|
12
|
+
"""`repro-lambda zip` strips caches + non-deterministic dist-info metadata,
|
|
13
|
+
so the container build needs no find/xargs (absent from minimal base images)."""
|
|
14
|
+
pkg = tmp_path / "pkg"
|
|
15
|
+
(pkg / "mymod").mkdir(parents=True)
|
|
16
|
+
(pkg / "mymod" / "__init__.py").write_text("x = 1\n")
|
|
17
|
+
(pkg / "mymod" / "__pycache__").mkdir()
|
|
18
|
+
(pkg / "mymod" / "__pycache__" / "__init__.cpython-313.pyc").write_bytes(b"\x00")
|
|
19
|
+
(pkg / "mymod" / "stale.pyc").write_bytes(b"\x00")
|
|
20
|
+
dist = pkg / "req-1.0.dist-info"
|
|
21
|
+
dist.mkdir()
|
|
22
|
+
(dist / "RECORD").write_text("mymod/__init__.py,,\n")
|
|
23
|
+
(dist / "INSTALLER").write_text("pip\n")
|
|
24
|
+
(dist / "METADATA").write_text("Name: req\n")
|
|
25
|
+
|
|
26
|
+
out = tmp_path / "lambda.zip"
|
|
27
|
+
result = runner.invoke(app, ["zip", "--src", str(pkg), "--out", str(out)])
|
|
28
|
+
assert result.exit_code == 0, result.stdout
|
|
29
|
+
|
|
30
|
+
names = ZipFile(out).namelist()
|
|
31
|
+
# kept: real code + stable dist-info metadata
|
|
32
|
+
assert "mymod/__init__.py" in names
|
|
33
|
+
assert "req-1.0.dist-info/METADATA" in names
|
|
34
|
+
# stripped: caches + non-deterministic metadata
|
|
35
|
+
assert not any("__pycache__" in n for n in names)
|
|
36
|
+
assert not any(n.endswith(".pyc") for n in names)
|
|
37
|
+
assert "req-1.0.dist-info/RECORD" not in names
|
|
38
|
+
assert "req-1.0.dist-info/INSTALLER" not in names
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_nodejs_lambda/handler/index.js
RENAMED
|
File without changes
|
|
File without changes
|
{repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_nodejs_lambda/handler/package.json
RENAMED
|
File without changes
|
|
File without changes
|
{repro_lambda-0.2.3 → repro_lambda-0.2.4}/tests/fixtures/sample_python_lambda/handler/app.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|