This is an automated email from the ASF dual-hosted git repository. potiuk pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push: new d06a27ecfeb Build python from source for CI (#52265) d06a27ecfeb is described below commit d06a27ecfeb0e06dff701cb4c204ead3e64899b9 Author: Aritra Basu <24430013+aritr...@users.noreply.github.com> AuthorDate: Sat Jul 5 13:23:45 2025 +0530 Build python from source for CI (#52265) * Draft: Build python from source Builds python from source, also installs golang from official distribution. Does both of these for the ci image only. * Updates path * Adds version upgrade check for python version Adds support for using the airflow api to fetch the newest python patch version available for specific major_minor pair * Updated to use args in dockerfile for python * Added support for golang upgrade * Fixed go version sorting in pre_commit install * Added github token usage and fixed version regex Updated python fetch request during upgrade to use github token and fixed the regex * Updated dockerfile.ci file --- .dockerignore | 1 + .github/workflows/basic-tests.yml | 4 + .pre-commit-config.yaml | 2 +- Dockerfile.ci | 65 ++++++-- .../pre_commit/update_installers_and_pre_commit.py | 60 ++++++++ scripts/docker/entrypoint_ci.sh | 2 +- scripts/docker/install_os_dependencies_ci.sh | 166 +++++++++++++++++++++ 7 files changed, 282 insertions(+), 18 deletions(-) diff --git a/.dockerignore b/.dockerignore index c50ed5ae24e..75e6291445a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -38,6 +38,7 @@ !providers/ !task-sdk/ !airflow-ctl/ +!go-sdk/ # Add all "test" distributions !tests diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index 161ba36d580..5c395c3c302 100644 --- a/.github/workflows/basic-tests.yml +++ b/.github/workflows/basic-tests.yml @@ -292,6 +292,8 @@ jobs: if: always() env: UPGRADE_UV: "true" + UPGRADE_PYTHON: "false" + UPGRADE_GOLANG: "true" UPGRADE_PIP: "false" UPGRADE_PRE_COMMIT: "false" UPGRADE_NODE_LTS: "false" @@ -303,6 +305,8 @@ jobs: if: always() env: UPGRADE_UV: "false" + UPGRADE_PYTHON: "true" + UPGRADE_GOLANG: "false" UPGRADE_PIP: "true" UPGRADE_PRE_COMMIT: "true" UPGRADE_NODE_LTS: "true" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 13b7121241e..5af7b636d37 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -213,7 +213,7 @@ repos: ^scripts/ci/pre_commit/update_installers_and_pre_commit\.py$ pass_filenames: false require_serial: true - additional_dependencies: ['pyyaml>=6.0.2', 'rich>=12.4.4', 'requests>=2.31.0'] + additional_dependencies: ['pyyaml>=6.0.2', 'rich>=12.4.4', 'requests>=2.31.0',"packaging>=25"] - id: update-chart-dependencies name: Update chart dependencies to latest (manual) entry: ./scripts/ci/pre_commit/update_chart_dependencies.py diff --git a/Dockerfile.ci b/Dockerfile.ci index 6ba138121af..9e7c1afd6a2 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -16,13 +16,13 @@ # # WARNING: THIS DOCKERFILE IS NOT INTENDED FOR PRODUCTION USE OR DEPLOYMENT. # -ARG PYTHON_BASE_IMAGE="python:3.10-slim-bookworm" +ARG BASE_IMAGE="debian:bookworm-slim" ############################################################################################## # This is the script image where we keep all inlined bash scripts needed in other segments -# We use PYTHON_BASE_IMAGE to make sure that the scripts are different for different platforms. +# We use BASE_IMAGE to make sure that the scripts are different for different platforms. ############################################################################################## -FROM ${PYTHON_BASE_IMAGE} as scripts +FROM ${BASE_IMAGE} as scripts ############################################################################################## # Please DO NOT modify the inlined scripts manually. The content of those files will be @@ -31,22 +31,27 @@ FROM ${PYTHON_BASE_IMAGE} as scripts # make the PROD Dockerfile standalone ############################################################################################## -# The content below is automatically copied from scripts/docker/install_os_dependencies.sh -COPY <<"EOF" /install_os_dependencies.sh +# The content below is automatically copied from scripts/docker/install_os_dependencies_ci.sh +COPY <<"EOF" /install_os_dependencies_ci.sh #!/usr/bin/env bash set -euo pipefail if [[ "$#" != 1 ]]; then - echo "ERROR! There should be 'runtime' or 'dev' parameter passed as argument.". + echo "ERROR! There should be 'runtime', 'ci' or 'dev' parameter passed as argument.". exit 1 fi +AIRFLOW_PYTHON_VERSION=${AIRFLOW_PYTHON_VERSION:-v3.10.10} +GOLANG_MAJOR_MINOR_VERSION=${GOLANG_MAJOR_MINOR_VERSION:-1.24.4} + if [[ "${1}" == "runtime" ]]; then INSTALLATION_TYPE="RUNTIME" elif [[ "${1}" == "dev" ]]; then - INSTALLATION_TYPE="dev" + INSTALLATION_TYPE="DEV" +elif [[ "${1}" == "ci" ]]; then + INSTALLATION_TYPE="CI" else - echo "ERROR! Wrong argument. Passed ${1} and it should be one of 'runtime' or 'dev'.". + echo "ERROR! Wrong argument. Passed ${1} and it should be one of 'runtime', 'ci' or 'dev'.". exit 1 fi @@ -56,7 +61,10 @@ function get_dev_apt_deps() { freetds-bin freetds-dev git graphviz graphviz-dev krb5-user ldap-utils libev4 libev-dev libffi-dev libgeos-dev \ libkrb5-dev libldap2-dev libleveldb1d libleveldb-dev libsasl2-2 libsasl2-dev libsasl2-modules \ libssl-dev libxmlsec1 libxmlsec1-dev locales lsb-release openssh-client pkgconf sasl2-bin \ -software-properties-common sqlite3 sudo unixodbc unixodbc-dev zlib1g-dev" +software-properties-common sqlite3 sudo unixodbc unixodbc-dev zlib1g-dev \ +gdb lcov pkg-config libbz2-dev libgdbm-dev libgdbm-compat-dev liblzma-dev \ +libncurses5-dev libreadline6-dev libsqlite3-dev lzma lzma-dev tk-dev uuid-dev \ +libzstd-dev" export DEV_APT_DEPS fi } @@ -143,14 +151,35 @@ function install_debian_runtime_dependencies() { rm -rf /var/lib/apt/lists/* /var/log/* } +function install_python() { + git clone --branch "${AIRFLOW_PYTHON_VERSION}" --depth 1 https://github.com/python/cpython.git + cd cpython + ./configure --enable-optimizations + make -s -j "$(nproc)" install + ln -s /usr/local/bin/python3 /usr/local/bin/python + ln -s /usr/local/bin/pip3 /usr/local/bin/pip + cd .. + rm -rf cpython +} + +function install_golang() { + curl "https://dl.google.com/go/go${GOLANG_MAJOR_MINOR_VERSION}.linux-$(dpkg --print-architecture).tar.gz" -o "go${GOLANG_MAJOR_MINOR_VERSION}.linux.tar.gz" + rm -rf /usr/local/go && tar -C /usr/local -xzf go"${GOLANG_MAJOR_MINOR_VERSION}".linux.tar.gz +} + if [[ "${INSTALLATION_TYPE}" == "RUNTIME" ]]; then get_runtime_apt_deps install_debian_runtime_dependencies install_docker_cli else + get_dev_apt_deps install_debian_dev_dependencies + install_python + if [[ "${INSTALLATION_TYPE}" == "CI" ]]; then + install_golang + fi install_docker_cli fi EOF @@ -925,7 +954,7 @@ function environment_initialization() { CI=${CI:="false"} # Added to have run-tests on path - export PATH=${PATH}:${AIRFLOW_SOURCES} + export PATH=${PATH}:${AIRFLOW_SOURCES}:/usr/local/go/bin/ mkdir -pv "${AIRFLOW_HOME}/logs/" @@ -1237,13 +1266,13 @@ COPY <<"EOF" /entrypoint_exec.sh exec /bin/bash "${@}" EOF -FROM ${PYTHON_BASE_IMAGE} as main +FROM ${BASE_IMAGE} as main # Nolog bash flag is currently ignored - but you can replace it with other flags (for example # xtrace - to show commands executed) SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "nounset", "-o", "nolog", "-c"] -ARG PYTHON_BASE_IMAGE +ARG BASE_IMAGE ARG AIRFLOW_IMAGE_REPOSITORY="https://github.com/apache/airflow" # By increasing this number we can do force build of all dependencies. @@ -1253,7 +1282,7 @@ ARG AIRFLOW_IMAGE_REPOSITORY="https://github.com/apache/airflow" ARG DEPENDENCIES_EPOCH_NUMBER="15" # Make sure noninteractive debian install is used and language variables set -ENV PYTHON_BASE_IMAGE=${PYTHON_BASE_IMAGE} \ +ENV BASE_IMAGE=${BASE_IMAGE} \ DEBIAN_FRONTEND=noninteractive LANGUAGE=C.UTF-8 LANG=C.UTF-8 LC_ALL=C.UTF-8 \ LC_CTYPE=C.UTF-8 LC_MESSAGES=C.UTF-8 \ DEPENDENCIES_EPOCH_NUMBER=${DEPENDENCIES_EPOCH_NUMBER} \ @@ -1264,7 +1293,7 @@ ENV PYTHON_BASE_IMAGE=${PYTHON_BASE_IMAGE} \ UV_CACHE_DIR=/root/.cache/uv -RUN echo "Base image version: ${PYTHON_BASE_IMAGE}" +RUN echo "Base image version: ${BASE_IMAGE}" ARG DEV_APT_COMMAND="" ARG ADDITIONAL_DEV_APT_COMMAND="" @@ -1279,8 +1308,12 @@ ENV DEV_APT_COMMAND=${DEV_APT_COMMAND} \ ADDITIONAL_DEV_APT_DEPS=${ADDITIONAL_DEV_APT_DEPS} \ ADDITIONAL_DEV_APT_COMMAND=${ADDITIONAL_DEV_APT_COMMAND} -COPY --from=scripts install_os_dependencies.sh /scripts/docker/ -RUN bash /scripts/docker/install_os_dependencies.sh dev +ENV AIRFLOW_PYTHON_VERSION=v3.10.18 +ENV GOLANG_MAJOR_MINOR_VERSION=1.24.4 + +COPY --from=scripts install_os_dependencies_ci.sh /scripts/docker/ + +RUN bash /scripts/docker/install_os_dependencies_ci.sh ci COPY --from=scripts common.sh /scripts/docker/ diff --git a/scripts/ci/pre_commit/update_installers_and_pre_commit.py b/scripts/ci/pre_commit/update_installers_and_pre_commit.py index ef1b745f9fe..8613949f7b3 100755 --- a/scripts/ci/pre_commit/update_installers_and_pre_commit.py +++ b/scripts/ci/pre_commit/update_installers_and_pre_commit.py @@ -24,6 +24,7 @@ from enum import Enum from pathlib import Path import requests +from packaging.version import Version sys.path.insert(0, str(Path(__file__).parent.resolve())) # make sure common_precommit_utils is imported from common_precommit_utils import AIRFLOW_CORE_ROOT_PATH, AIRFLOW_ROOT_PATH, console @@ -65,6 +66,35 @@ def get_latest_pypi_version(package_name: str) -> str: return latest_version +def get_latest_python_version(python_major_minor: str, github_token: str | None) -> str | None: + latest_version = None + # Matches versions of vA.B.C and vA.B where C can only be numeric and v is optional + version_match = re.compile(rf"^v?{python_major_minor}\.?\d*$") + headers = {"User-Agent": "Python requests"} + if github_token: + headers["Authorization"] = f"Bearer {github_token}" + for i in range(5): + response = requests.get( + f"https://api.github.com/repos/python/cpython/tags?per_page=100&page={i + 1}", + headers=headers, + ) + response.raise_for_status() # Ensure we got a successful response + data = response.json() + versions = [str(tag["name"]) for tag in data if version_match.match(tag.get("name", ""))] + if versions: + latest_version = sorted(versions, key=Version, reverse=True)[0] + break + return latest_version + + +def get_latest_golang_version() -> str: + response = requests.get("https://go.dev/dl/?mode=json") + response.raise_for_status() # Ensure we got a successful response + versions = response.json() + stable_versions = [release["version"].replace("go", "") for release in versions if release["stable"]] + return sorted(stable_versions, key=Version, reverse=True)[0] + + def get_latest_lts_node_version() -> str: response = requests.get("https://nodejs.org/dist/index.json") response.raise_for_status() # Ensure we got a successful response @@ -92,6 +122,16 @@ PIP_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ (re.compile(r"(\| *`AIRFLOW_PIP_VERSION` *\| *)(`[0-9.]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED), ] +PYTHON_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ + (re.compile(r"(AIRFLOW_PYTHON_VERSION=)(v[0-9.]+)"), Quoting.UNQUOTED), + (re.compile(r"(\| *`AIRFLOW_PYTHON_VERSION` *\| *)(`v[0-9.]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED), +] + +GOLANG_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ + (re.compile(r"(GOLANG_MAJOR_MINOR_VERSION=)([0-9.]+)"), Quoting.UNQUOTED), + (re.compile(r"(\| *`GOLANG_MAJOR_MINOR_VERSION` *\| *)(`[0-9.]+`)( *\|)"), Quoting.REVERSE_SINGLE_QUOTED), +] + UV_PATTERNS: list[tuple[re.Pattern, Quoting]] = [ (re.compile(r"(AIRFLOW_UV_VERSION=)([0-9.]+)"), Quoting.UNQUOTED), (re.compile(r"(uv>=)([0-9.]+)"), Quoting.UNQUOTED), @@ -167,10 +207,16 @@ def get_replacement(value: str, quoting: Quoting) -> str: UPGRADE_UV: bool = os.environ.get("UPGRADE_UV", "true").lower() == "true" UPGRADE_PIP: bool = os.environ.get("UPGRADE_PIP", "true").lower() == "true" +UPGRADE_PYTHON: bool = os.environ.get("UPGRADE_PYTHON", "true").lower() == "true" +UPGRADE_GOLANG: bool = os.environ.get("UPGRADE_GOLANG", "true").lower() == "true" UPGRADE_SETUPTOOLS: bool = os.environ.get("UPGRADE_SETUPTOOLS", "true").lower() == "true" UPGRADE_PRE_COMMIT: bool = os.environ.get("UPGRADE_PRE_COMMIT", "true").lower() == "true" UPGRADE_NODE_LTS: bool = os.environ.get("UPGRADE_NODE_LTS", "true").lower() == "true" +PYTHON_VERSION: str = os.environ.get("PYTHON_VERSION", "3.10") + +GITHUB_TOKEN: str | None = os.environ.get("GITHUB_TOKEN") + def replace_version(pattern: re.Pattern[str], version: str, text: str, keep_total_length: bool = True) -> str: # Assume that the pattern has up to 3 replacement groups: @@ -201,6 +247,8 @@ def replace_version(pattern: re.Pattern[str], version: str, text: str, keep_tota if __name__ == "__main__": changed = False + python_version = get_latest_python_version(PYTHON_VERSION, GITHUB_TOKEN) + golang_version = get_latest_golang_version() pip_version = get_latest_pypi_version("pip") uv_version = get_latest_pypi_version("uv") setuptools_version = get_latest_pypi_version("setuptools") @@ -217,6 +265,18 @@ if __name__ == "__main__": new_content = replace_version( line_pattern, get_replacement(pip_version, quoting), new_content, keep_length ) + if UPGRADE_PYTHON and python_version: + console.print(f"[bright_blue]Latest python {PYTHON_VERSION} version: {python_version}") + for line_pattern, quoting in PYTHON_PATTERNS: + new_content = replace_version( + line_pattern, get_replacement(python_version, quoting), new_content, keep_length + ) + if UPGRADE_GOLANG: + console.print(f"[bright_blue]Latest golang version: {golang_version}") + for line_pattern, quoting in GOLANG_PATTERNS: + new_content = replace_version( + line_pattern, get_replacement(golang_version, quoting), new_content, keep_length + ) if UPGRADE_SETUPTOOLS: console.print(f"[bright_blue]Latest setuptools version: {setuptools_version}") for line_pattern, quoting in SETUPTOOLS_PATTERNS: diff --git a/scripts/docker/entrypoint_ci.sh b/scripts/docker/entrypoint_ci.sh index e215ce642a0..fef63aa88f0 100755 --- a/scripts/docker/entrypoint_ci.sh +++ b/scripts/docker/entrypoint_ci.sh @@ -130,7 +130,7 @@ function environment_initialization() { CI=${CI:="false"} # Added to have run-tests on path - export PATH=${PATH}:${AIRFLOW_SOURCES} + export PATH=${PATH}:${AIRFLOW_SOURCES}:/usr/local/go/bin/ mkdir -pv "${AIRFLOW_HOME}/logs/" diff --git a/scripts/docker/install_os_dependencies_ci.sh b/scripts/docker/install_os_dependencies_ci.sh new file mode 100644 index 00000000000..b2e6294dbe0 --- /dev/null +++ b/scripts/docker/install_os_dependencies_ci.sh @@ -0,0 +1,166 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# shellcheck shell=bash +set -euo pipefail + +if [[ "$#" != 1 ]]; then + echo "ERROR! There should be 'runtime', 'ci' or 'dev' parameter passed as argument.". + exit 1 +fi + +AIRFLOW_PYTHON_VERSION=${AIRFLOW_PYTHON_VERSION:-v3.10.10} +GOLANG_MAJOR_MINOR_VERSION=${GOLANG_MAJOR_MINOR_VERSION:-1.24.4} + +if [[ "${1}" == "runtime" ]]; then + INSTALLATION_TYPE="RUNTIME" +elif [[ "${1}" == "dev" ]]; then + INSTALLATION_TYPE="DEV" +elif [[ "${1}" == "ci" ]]; then + INSTALLATION_TYPE="CI" +else + echo "ERROR! Wrong argument. Passed ${1} and it should be one of 'runtime', 'ci' or 'dev'.". + exit 1 +fi + +function get_dev_apt_deps() { + if [[ "${DEV_APT_DEPS=}" == "" ]]; then + DEV_APT_DEPS="apt-transport-https apt-utils build-essential ca-certificates dirmngr \ +freetds-bin freetds-dev git graphviz graphviz-dev krb5-user ldap-utils libev4 libev-dev libffi-dev libgeos-dev \ +libkrb5-dev libldap2-dev libleveldb1d libleveldb-dev libsasl2-2 libsasl2-dev libsasl2-modules \ +libssl-dev libxmlsec1 libxmlsec1-dev locales lsb-release openssh-client pkgconf sasl2-bin \ +software-properties-common sqlite3 sudo unixodbc unixodbc-dev zlib1g-dev \ +gdb lcov pkg-config libbz2-dev libgdbm-dev libgdbm-compat-dev liblzma-dev \ +libncurses5-dev libreadline6-dev libsqlite3-dev lzma lzma-dev tk-dev uuid-dev \ +libzstd-dev" + export DEV_APT_DEPS + fi +} + +function get_runtime_apt_deps() { + local debian_version + local debian_version_apt_deps + # Get debian version without installing lsb_release + # shellcheck disable=SC1091 + debian_version=$(. /etc/os-release; printf '%s\n' "$VERSION_CODENAME";) + echo + echo "DEBIAN CODENAME: ${debian_version}" + echo + debian_version_apt_deps="libffi8 libldap-2.5-0 libssl3 netcat-openbsd" + echo + echo "APPLIED INSTALLATION CONFIGURATION FOR DEBIAN VERSION: ${debian_version}" + echo + if [[ "${RUNTIME_APT_DEPS=}" == "" ]]; then + RUNTIME_APT_DEPS="apt-transport-https apt-utils ca-certificates \ +curl dumb-init freetds-bin git krb5-user libev4 libgeos-dev \ +ldap-utils libsasl2-2 libsasl2-modules libxmlsec1 locales ${debian_version_apt_deps} \ +lsb-release openssh-client python3-selinux rsync sasl2-bin sqlite3 sudo unixodbc" + export RUNTIME_APT_DEPS + fi +} + +function install_docker_cli() { + apt-get update + apt-get install ca-certificates curl + install -m 0755 -d /etc/apt/keyrings + curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc + chmod a+r /etc/apt/keyrings/docker.asc + # shellcheck disable=SC1091 + echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null + apt-get update + apt-get install -y --no-install-recommends docker-ce-cli +} + +function install_debian_dev_dependencies() { + apt-get update + apt-get install -yqq --no-install-recommends apt-utils >/dev/null 2>&1 + apt-get install -y --no-install-recommends curl gnupg2 lsb-release + # shellcheck disable=SC2086 + export ${ADDITIONAL_DEV_APT_ENV?} + if [[ ${DEV_APT_COMMAND} != "" ]]; then + bash -o pipefail -o errexit -o nounset -o nolog -c "${DEV_APT_COMMAND}" + fi + if [[ ${ADDITIONAL_DEV_APT_COMMAND} != "" ]]; then + bash -o pipefail -o errexit -o nounset -o nolog -c "${ADDITIONAL_DEV_APT_COMMAND}" + fi + apt-get update + local debian_version + local debian_version_apt_deps + # Get debian version without installing lsb_release + # shellcheck disable=SC1091 + debian_version=$(. /etc/os-release; printf '%s\n' "$VERSION_CODENAME";) + echo + echo "DEBIAN CODENAME: ${debian_version}" + echo + # shellcheck disable=SC2086 + apt-get install -y --no-install-recommends ${DEV_APT_DEPS} ${ADDITIONAL_DEV_APT_DEPS} +} + +function install_debian_runtime_dependencies() { + apt-get update + apt-get install --no-install-recommends -yqq apt-utils >/dev/null 2>&1 + apt-get install -y --no-install-recommends curl gnupg2 lsb-release + # shellcheck disable=SC2086 + export ${ADDITIONAL_RUNTIME_APT_ENV?} + if [[ "${RUNTIME_APT_COMMAND}" != "" ]]; then + bash -o pipefail -o errexit -o nounset -o nolog -c "${RUNTIME_APT_COMMAND}" + fi + if [[ "${ADDITIONAL_RUNTIME_APT_COMMAND}" != "" ]]; then + bash -o pipefail -o errexit -o nounset -o nolog -c "${ADDITIONAL_RUNTIME_APT_COMMAND}" + fi + apt-get update + # shellcheck disable=SC2086 + apt-get install -y --no-install-recommends ${RUNTIME_APT_DEPS} ${ADDITIONAL_RUNTIME_APT_DEPS} + apt-get autoremove -yqq --purge + apt-get clean + rm -rf /var/lib/apt/lists/* /var/log/* +} + +function install_python() { + git clone --branch "${AIRFLOW_PYTHON_VERSION}" --depth 1 https://github.com/python/cpython.git + cd cpython + ./configure --enable-optimizations + make -s -j "$(nproc)" install + ln -s /usr/local/bin/python3 /usr/local/bin/python + ln -s /usr/local/bin/pip3 /usr/local/bin/pip + cd .. + rm -rf cpython +} + +function install_golang() { + curl "https://dl.google.com/go/go${GOLANG_MAJOR_MINOR_VERSION}.linux-$(dpkg --print-architecture).tar.gz" -o "go${GOLANG_MAJOR_MINOR_VERSION}.linux.tar.gz" + rm -rf /usr/local/go && tar -C /usr/local -xzf go"${GOLANG_MAJOR_MINOR_VERSION}".linux.tar.gz +} + +if [[ "${INSTALLATION_TYPE}" == "RUNTIME" ]]; then + get_runtime_apt_deps + install_debian_runtime_dependencies + install_docker_cli + +else + + get_dev_apt_deps + install_debian_dev_dependencies + install_python + if [[ "${INSTALLATION_TYPE}" == "CI" ]]; then + install_golang + fi + install_docker_cli +fi