From c58460def2677da846a771bdf45aee92eb0ef959 Mon Sep 17 00:00:00 2001 From: Alexy Grabov Date: Sun, 13 Sep 2026 11:36:12 +0300 Subject: [PATCH 1/2] feat(packaging): add PyPI packaging and CI/CD release workflow for lambda-deps-builder --- .github/workflows/ci-lambda-deps-builder.yml | 73 ++++++++++++++++ .../workflows/release-lambda-deps-builder.yml | 83 +++++++++++++++++++ .gitignore | 20 +++++ lambda_deps_builder/.gitignore | 2 + .../lambda_deps_builder/__init__.py | 3 +- .../lambda_deps_builder/py.typed | 1 + lambda_deps_builder/pyproject.toml | 23 ++++- 7 files changed, 200 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ci-lambda-deps-builder.yml create mode 100644 .github/workflows/release-lambda-deps-builder.yml create mode 100644 .gitignore create mode 100644 lambda_deps_builder/lambda_deps_builder/py.typed diff --git a/.github/workflows/ci-lambda-deps-builder.yml b/.github/workflows/ci-lambda-deps-builder.yml new file mode 100644 index 0000000..445282b --- /dev/null +++ b/.github/workflows/ci-lambda-deps-builder.yml @@ -0,0 +1,73 @@ +name: CI Lambda Deps Builder + +on: + push: + branches: + - '*' + paths: + - 'lambda_deps_builder/**' + - '.github/workflows/*lambda-deps*' + pull_request: + branches: + - main + - master + paths: + - 'lambda_deps_builder/**' + - '.github/workflows/*lambda-deps*' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + test: + name: Test on Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.11", "3.12", "3.13"] + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + + - name: Install dependencies and package + run: | + python -m pip install --upgrade pip + pip install ./lambda_deps_builder + pip install pytest boto3 + + - name: Run unit & synth tests + run: | + pytest lambda_deps_builder/tests -v + + build-check: + name: Verify package build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: "pip" + + - name: Install build tooling + run: | + python -m pip install --upgrade pip + pip install build twine + + - name: Build wheel and sdist + run: | + python -m build --sdist --wheel lambda_deps_builder --outdir dist + + - name: Check distributions with twine + run: | + twine check dist/* diff --git a/.github/workflows/release-lambda-deps-builder.yml b/.github/workflows/release-lambda-deps-builder.yml new file mode 100644 index 0000000..f6a395f --- /dev/null +++ b/.github/workflows/release-lambda-deps-builder.yml @@ -0,0 +1,83 @@ +name: Release Lambda Deps Builder to PyPI + +on: + push: + branches: + - main + - master + paths: + - 'lambda_deps_builder/**' + - '.github/workflows/release-lambda-deps-builder.yml' + release: + types: [published] + workflow_dispatch: + inputs: + dry-run: + description: "Build everything but skip the publish step" + type: boolean + default: false + +permissions: + contents: read + id-token: write + +jobs: + build: + name: Build distribution packages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: "pip" + + - name: Install build tooling + run: | + python -m pip install --upgrade pip + pip install build twine + + - name: Build sdist and wheel + run: | + python -m build --sdist --wheel lambda_deps_builder --outdir dist + + - name: Check package metadata + run: | + twine check dist/* + + - name: Upload distribution artifacts + uses: actions/upload-artifact@v4 + with: + name: python-package-distributions + path: dist/ + retention-days: 7 + + publish: + name: Publish to PyPI + needs: build + runs-on: ubuntu-latest + environment: pypi + if: (!inputs.dry-run) + steps: + - name: Download distribution artifacts + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + + - name: Publish to PyPI (Trusted Publishing OIDC) + if: ${{ secrets.PYPI_API_TOKEN == '' }} + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist/ + skip-existing: true + + - name: Publish to PyPI (API Token fallback) + if: ${{ secrets.PYPI_API_TOKEN != '' }} + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist/ + password: ${{ secrets.PYPI_API_TOKEN }} + skip-existing: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..984fd1c --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Distribution / packaging +dist/ +build/ +*.egg-info/ + +# Virtual environments +.venv/ +env/ +venv/ +ENV/ + +# Testing & CDK +.pytest_cache/ +cdk.out/ +.cdk.staging/ diff --git a/lambda_deps_builder/.gitignore b/lambda_deps_builder/.gitignore index 2696216..6fd74b2 100644 --- a/lambda_deps_builder/.gitignore +++ b/lambda_deps_builder/.gitignore @@ -5,3 +5,5 @@ __pycache__/ .pytest_cache/ cdk.out/ .cdk.staging/ +dist/ +build/ diff --git a/lambda_deps_builder/lambda_deps_builder/__init__.py b/lambda_deps_builder/lambda_deps_builder/__init__.py index 2b00307..ec25c0f 100644 --- a/lambda_deps_builder/lambda_deps_builder/__init__.py +++ b/lambda_deps_builder/lambda_deps_builder/__init__.py @@ -1,3 +1,4 @@ from lambda_deps_builder.construct import LambdaDepsBuilder -__all__ = ["LambdaDepsBuilder"] +__version__ = "0.1.0" +__all__ = ["LambdaDepsBuilder", "__version__"] diff --git a/lambda_deps_builder/lambda_deps_builder/py.typed b/lambda_deps_builder/lambda_deps_builder/py.typed new file mode 100644 index 0000000..1242d43 --- /dev/null +++ b/lambda_deps_builder/lambda_deps_builder/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. diff --git a/lambda_deps_builder/pyproject.toml b/lambda_deps_builder/pyproject.toml index a21771d..76e15ad 100644 --- a/lambda_deps_builder/pyproject.toml +++ b/lambda_deps_builder/pyproject.toml @@ -2,14 +2,29 @@ name = "lambda-deps-builder" version = "0.1.0" description = "CDK construct that builds Python Lambda dependencies inside Lambda — no local Docker." -authors = ["POC "] +authors = ["Alexy Grabov "] +license = "Apache-2.0" readme = "README.md" +repository = "https://github.com/CoreOxide/poc" +homepage = "https://github.com/CoreOxide/poc/tree/main/lambda_deps_builder" +keywords = ["aws", "cdk", "lambda", "dependencies", "dockerless", "layer"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Software Development :: Build Tools", + "Typing :: Typed", +] packages = [{ include = "lambda_deps_builder" }] [tool.poetry.dependencies] -python = "^3.11" -aws-cdk-lib = "^2.150.0" -constructs = "^10.0.0" +python = ">=3.11,<4.0" +aws-cdk-lib = ">=2.150.0" +constructs = ">=10.0.0" [tool.poetry.group.dev.dependencies] pytest = "^8.0.0" From 14ead006426d996df15d8050a85cb7e1436ab30b Mon Sep 17 00:00:00 2001 From: Alexy Grabov Date: Sun, 13 Sep 2026 11:38:10 +0300 Subject: [PATCH 2/2] fix(ci): fix release workflow YAML syntax and token evaluation --- .../workflows/release-lambda-deps-builder.yml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-lambda-deps-builder.yml b/.github/workflows/release-lambda-deps-builder.yml index f6a395f..dacee89 100644 --- a/.github/workflows/release-lambda-deps-builder.yml +++ b/.github/workflows/release-lambda-deps-builder.yml @@ -59,7 +59,7 @@ jobs: needs: build runs-on: ubuntu-latest environment: pypi - if: (!inputs.dry-run) + if: ${{ github.event_name != 'workflow_dispatch' || !inputs.dry-run }} steps: - name: Download distribution artifacts uses: actions/download-artifact@v4 @@ -67,15 +67,26 @@ jobs: name: python-package-distributions path: dist/ + - name: Check for PyPI API token + id: token-check + env: + TOKEN: ${{ secrets.PYPI_API_TOKEN }} + run: | + if [ -n "$TOKEN" ]; then + echo "has_token=true" >> "$GITHUB_OUTPUT" + else + echo "has_token=false" >> "$GITHUB_OUTPUT" + fi + - name: Publish to PyPI (Trusted Publishing OIDC) - if: ${{ secrets.PYPI_API_TOKEN == '' }} + if: steps.token-check.outputs.has_token == 'false' uses: pypa/gh-action-pypi-publish@release/v1 with: packages-dir: dist/ skip-existing: true - name: Publish to PyPI (API Token fallback) - if: ${{ secrets.PYPI_API_TOKEN != '' }} + if: steps.token-check.outputs.has_token == 'true' uses: pypa/gh-action-pypi-publish@release/v1 with: packages-dir: dist/