diff --git a/.github/workflows/build_image_target-test-base_jammy-py.yml b/.github/workflows/build_image_target-test-base_jammy-py.yml new file mode 100644 index 0000000..9782593 --- /dev/null +++ b/.github/workflows/build_image_target-test-base_jammy-py.yml @@ -0,0 +1,127 @@ +name: Build and push Docker image 'target-test-base_jammy-py' +on: + push: + branches: + - master + paths: + - 'target-test-base_jammy-py/**' + - '.github/workflows/build_image_target-test-base_jammy-py.yml' + pull_request: + paths: + - 'target-test-base_jammy-py/**' + - '.github/workflows/build_image_target-test-base_jammy-py.yml' + workflow_dispatch: + inputs: + python_3_8_17: + description: 'Build Ubuntu 22.04 (Jammy) with Python 3.8.17' + required: false + type: boolean + default: true + python_3_9_17: + description: 'Build Ubuntu 22.04 (Jammy) with Python 3.9.17' + required: false + type: boolean + default: false + python_3_10_12: + description: 'Build Ubuntu 22.04 (Jammy) with Python 3.10.12' + required: false + type: boolean + default: false + python_3_11_4: + description: 'Build Ubuntu 22.04 (Jammy) with Python 3.11.4' + required: false + type: boolean + default: false + +# Kill running actions pipeline (for PR) when new changes are pushed to PR +concurrency: + group: pr-${{ github.event.pull_request.number }} + cancel-in-progress: true + +env: + IMAGE_DIR: ./target-test-base_jammy-py + IMAGE_BASE_NAME: ghcr.io/${{ github.repository }}/target-test-base-jammy + IMAGE_ARCHS: linux/amd64,linux/arm + +jobs: + setup-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Set Matrix + id: set-matrix + run: | + matrix='["3.8.17"]' + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + if [ "${{ github.event.inputs.python_3_9_17 }}" = "true" ]; then + matrix=$(echo $matrix | jq ' . + ["3.9.17"] ') + fi + if [ "${{ github.event.inputs.python_3_10_12 }}" = "true" ]; then + matrix=$(echo $matrix | jq ' . + ["3.10.12"] ') + fi + if [ "${{ github.event.inputs.python_3_11_4 }}" = "true" ]; then + matrix=$(echo $matrix | jq ' . + ["3.11.4"] ') + fi + fi + echo $matrix + echo "::set-output name=matrix::$matrix" + shell: bash + + + build-and-push-docker-image: + needs: setup-matrix + runs-on: ubuntu-latest + strategy: + matrix: + python_version: ${{fromJson(needs.setup-matrix.outputs.matrix)}} + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Extract Major/Minor Version from Full Version + id: extract_version + run: | + echo "PYTHON_VERSION=${{ matrix.python_version }}" >> $GITHUB_ENV + echo "PYTHON_VERSION_MM=$(echo "${{ matrix.python_version }}" | cut -d'.' -f1,2)" >> $GITHUB_ENV + + - name: Setup QEMU for Multi-Arch Builds + uses: docker/setup-qemu-action@v1 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to GitHub Container Registry (GHCR) + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Pull Docker image to use as cache (for master) + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + run: | + docker pull ${{ env.IMAGE_BASE_NAME }}:py${{ matrix.python_version }} || true + + - name: Cache Docker layers (for PRs) + if: github.event_name == 'pull_request' + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: buildx-${{ matrix.python_version }}-${{ github.sha }} + restore-keys: | + buildx-${{ matrix.python_version }}- + + - name: Build and Push Docker Image + uses: docker/build-push-action@v2 + with: + context: ${{ env.IMAGE_DIR }} + platforms: ${{env.IMAGE_ARCHS}} + tags: ${{ env.IMAGE_BASE_NAME }}:py${{ matrix.python_version }} + build-args: | + PYTHON_VERSION=${{ env.PYTHON_VERSION }} + PYTHON_VERSION_MM=${{ env.PYTHON_VERSION_MM }} + push: true #TODO: remove this for production + # push: ${{ github.event_name != 'pull_request' }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache diff --git a/target-test-base_jammy-py/Dockerfile b/target-test-base_jammy-py/Dockerfile new file mode 100644 index 0000000..9789e2d --- /dev/null +++ b/target-test-base_jammy-py/Dockerfile @@ -0,0 +1,73 @@ +FROM ubuntu:22.04 AS build-python + +ARG PYTHON_VERSION_MM=3.8 +ARG PYTHON_VERSION=3.8.17 + +# Install essential build tools and necessary runtime libraries for Python compilation +RUN : \ + && apt-get update \ + && apt-get install -y \ + build-essential \ + wget \ + libffi-dev \ + libssl-dev \ + zlib1g-dev \ + liblzma-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + && : + +# Download, compile, and install Python from source code (to have this version available for both amd64 and armv7l) +WORKDIR /tmp +RUN : \ + && wget https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz \ + && tar xvf Python-${PYTHON_VERSION}.tar.xz \ + && cd Python-${PYTHON_VERSION} \ + && ./configure --enable-shared --enable-optimizations \ + && make -j$(nproc) \ + && make altinstall \ + && : + +# Update symbolic links for python3 and pip3 (to be able to use commands without version suffix) +RUN : \ + && ln -s /usr/local/bin/python${PYTHON_VERSION_MM} /usr/local/bin/python3 \ + && ln -s /usr/local/bin/pip${PYTHON_VERSION_MM} /usr/local/bin/pip3 \ + && ln -s /usr/local/bin/python${PYTHON_VERSION_MM} /usr/local/bin/python \ + && ln -s /usr/local/bin/pip${PYTHON_VERSION_MM} /usr/local/bin/pip \ + && : + +# ------------------------------------------------------------------------------------------------------------------------------- +FROM ubuntu:22.04 as main + +# Set up required development and runtime dependencies +RUN : \ + && apt-get update \ + && apt-get install -y \ + wget \ + libffi-dev \ + libssl-dev \ + zlib1g-dev \ + liblzma-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && : + +# Copy Python binaries, libraries, includes, and virtualenv from the build-python stage +COPY --from=build-python /usr/local/ /usr/local/ + +# Update the dynamic linker run-time bindings (Python shared libraries are not in the default search path) +RUN ldconfig + +# This prefers the Espressif pypi wheel registry (https://dl.espressif.com/pypi/) over the public PyPI (fallback) +RUN pip install --upgrade pip +ENV PIP_INDEX_URL=https://dl.espressif.com/pypi/ +ENV PIP_EXTRA_INDEX_URL=https://pypi.org/simple + +# Prioritize using binary (wheel) packages over source packages for faster installations and to avoid unnecessary compilations. +ENV PIP_PREFER_BINARY=true + +CMD [ "/bin/bash" ]