From d76473faccd90720265a0e7f515f7ccff66b0634 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Thu, 6 Apr 2023 09:45:17 +0100 Subject: [PATCH] Migrate Python runtime builds to GitHub Actions (#1432) * Builds are now performed on GitHub Actions (which supports IP allowlisting), and can be triggered via the dispatch job workflow. * The build process no longer uses the legacy bob-builder tool. * The identical and thus redundant per-version scripts have been removed. * The per-stack Dockerfiles have been consolidated. GUS-W-12964868. --- .dockerignore | 1 - .github/dependabot.yml | 4 - .github/workflows/build_python_runtime.yml | 74 ++++++++++++++++ .gitignore | 14 +--- Makefile | 38 +-------- builds/Dockerfile | 13 +++ builds/README.md | 83 ++---------------- .../python => build_python_runtime.sh} | 84 ++++++++++--------- builds/dockerenv.default | 8 -- builds/heroku-18.Dockerfile | 20 ----- builds/heroku-20.Dockerfile | 20 ----- builds/heroku-22.Dockerfile | 20 ----- builds/runtimes/python-3.10.10 | 5 -- builds/runtimes/python-3.10.4 | 5 -- builds/runtimes/python-3.10.5 | 5 -- builds/runtimes/python-3.10.6 | 5 -- builds/runtimes/python-3.10.7 | 5 -- builds/runtimes/python-3.10.8 | 5 -- builds/runtimes/python-3.10.9 | 5 -- builds/runtimes/python-3.11.0 | 5 -- builds/runtimes/python-3.11.1 | 5 -- builds/runtimes/python-3.11.2 | 5 -- builds/runtimes/python-3.7.13 | 5 -- builds/runtimes/python-3.7.14 | 5 -- builds/runtimes/python-3.7.15 | 5 -- builds/runtimes/python-3.7.16 | 5 -- builds/runtimes/python-3.8.13 | 5 -- builds/runtimes/python-3.8.14 | 5 -- builds/runtimes/python-3.8.15 | 5 -- builds/runtimes/python-3.8.16 | 5 -- builds/runtimes/python-3.9.12 | 5 -- builds/runtimes/python-3.9.13 | 5 -- builds/runtimes/python-3.9.14 | 5 -- builds/runtimes/python-3.9.15 | 5 -- builds/runtimes/python-3.9.16 | 5 -- requirements.txt | 6 -- 36 files changed, 144 insertions(+), 356 deletions(-) delete mode 100644 .dockerignore create mode 100644 .github/workflows/build_python_runtime.yml create mode 100644 builds/Dockerfile rename builds/{runtimes/python => build_python_runtime.sh} (74%) delete mode 100644 builds/dockerenv.default delete mode 100644 builds/heroku-18.Dockerfile delete mode 100644 builds/heroku-20.Dockerfile delete mode 100644 builds/heroku-22.Dockerfile delete mode 100755 builds/runtimes/python-3.10.10 delete mode 100755 builds/runtimes/python-3.10.4 delete mode 100755 builds/runtimes/python-3.10.5 delete mode 100755 builds/runtimes/python-3.10.6 delete mode 100755 builds/runtimes/python-3.10.7 delete mode 100755 builds/runtimes/python-3.10.8 delete mode 100755 builds/runtimes/python-3.10.9 delete mode 100755 builds/runtimes/python-3.11.0 delete mode 100755 builds/runtimes/python-3.11.1 delete mode 100755 builds/runtimes/python-3.11.2 delete mode 100755 builds/runtimes/python-3.7.13 delete mode 100755 builds/runtimes/python-3.7.14 delete mode 100755 builds/runtimes/python-3.7.15 delete mode 100755 builds/runtimes/python-3.7.16 delete mode 100755 builds/runtimes/python-3.8.13 delete mode 100755 builds/runtimes/python-3.8.14 delete mode 100755 builds/runtimes/python-3.8.15 delete mode 100755 builds/runtimes/python-3.8.16 delete mode 100755 builds/runtimes/python-3.9.12 delete mode 100755 builds/runtimes/python-3.9.13 delete mode 100755 builds/runtimes/python-3.9.14 delete mode 100755 builds/runtimes/python-3.9.15 delete mode 100755 builds/runtimes/python-3.9.16 delete mode 100644 requirements.txt diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 2d2ecd68d..000000000 --- a/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -.git/ diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 40b2d7aa2..961827362 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,9 +1,5 @@ version: 2 updates: - - package-ecosystem: "pip" - directory: "/" - schedule: - interval: "monthly" - package-ecosystem: "bundler" directory: "/" schedule: diff --git a/.github/workflows/build_python_runtime.yml b/.github/workflows/build_python_runtime.yml new file mode 100644 index 000000000..f61f1d876 --- /dev/null +++ b/.github/workflows/build_python_runtime.yml @@ -0,0 +1,74 @@ +name: Build and upload Python runtime +run-name: "Build and upload Python ${{ inputs.python_version }}${{ inputs.dry_run && ' (dry run)' || '' }}" + +on: + workflow_dispatch: + inputs: + python_version: + description: "The Python version to build, specified as X.Y.Z" + type: string + required: true + dry_run: + description: "Skip deploying to S3 (e.g. for testing)" + type: boolean + default: false + required: false + +permissions: + contents: read + +env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: "us-west-2" + S3_BUCKET: "heroku-buildpack-python" + +# Unfortunately these jobs cannot be easily written as a matrix since `matrix.exclude` does not +# support expression syntax, and the `inputs` context is not available inside the job `if` key. +jobs: + build-and-upload-heroku-18: + runs-on: pub-hk-ubuntu-22.04-xlarge + env: + STACK_VERSION: "18" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Build Docker image + run: docker build --pull --tag buildenv --build-arg=STACK_VERSION builds/ + - name: Build and package Python runtime + run: docker run --rm --platform="linux/amd64" --volume="${PWD}/upload:/tmp/upload" buildenv ./build_python_runtime.sh "${{ inputs.python_version }}" + - name: Upload Python runtime archive to S3 + if: (!inputs.dry_run) + run: aws s3 sync ./upload "s3://${S3_BUCKET}" + + build-and-upload-heroku-20: + runs-on: pub-hk-ubuntu-22.04-xlarge + env: + STACK_VERSION: "20" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Build Docker image + run: docker build --pull --tag buildenv --build-arg=STACK_VERSION builds/ + - name: Build and package Python runtime + run: docker run --rm --platform="linux/amd64" --volume="${PWD}/upload:/tmp/upload" buildenv ./build_python_runtime.sh "${{ inputs.python_version }}" + - name: Upload Python runtime archive to S3 + if: (!inputs.dry_run) + run: aws s3 sync ./upload "s3://${S3_BUCKET}" + + build-and-upload-heroku-22: + # We only support Python 3.9+ on Heroku-22. + if: (!startsWith(inputs.python_version, '3.7.') && !startsWith(inputs.python_version,'3.8.')) + runs-on: pub-hk-ubuntu-22.04-xlarge + env: + STACK_VERSION: "22" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Build Docker image + run: docker build --pull --tag buildenv --build-arg=STACK_VERSION builds/ + - name: Build and package Python runtime + run: docker run --rm --platform="linux/amd64" --volume="${PWD}/upload:/tmp/upload" buildenv ./build_python_runtime.sh "${{ inputs.python_version }}" + - name: Upload Python runtime archive to S3 + if: (!inputs.dry_run) + run: aws s3 sync ./upload "s3://${S3_BUCKET}" diff --git a/.gitignore b/.gitignore index 23caccd6a..642e0051c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,4 @@ -*.pyc -site -.DS_Store - -/.envrc +__pycache__/ .hatchet/repos/ - -#Venv -buildpack/* - -builds/dockerenv.staging* -builds/dockerenv.production - +.DS_Store .rspec_status diff --git a/Makefile b/Makefile index 721ba0341..a1f03054f 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,9 @@ # These targets are not files -.PHONY: lint lint-scripts lint-ruby compile builder-image buildenv deploy-runtimes publish +.PHONY: lint lint-scripts lint-ruby compile publish STACK ?= heroku-22 -STACKS ?= heroku-18 heroku-20 heroku-22 PLATFORM := linux/amd64 FIXTURE ?= spec/fixtures/python_version_unspecified -ENV_FILE ?= builds/dockerenv.default -BUILDER_IMAGE_PREFIX := heroku-python-build # Converts a stack name of `heroku-NN` to its build Docker image tag of `heroku/heroku:NN-build`. STACK_IMAGE_TAG := heroku/$(subst -,:,$(STACK))-build @@ -17,7 +14,7 @@ lint-scripts: @shellcheck -x bin/compile bin/detect bin/release bin/test-compile bin/utils bin/warnings bin/default_pythons @shellcheck -x bin/steps/collectstatic bin/steps/nltk bin/steps/pip-install bin/steps/pipenv bin/steps/pipenv-python-version bin/steps/python @shellcheck -x bin/steps/hooks/* - @shellcheck -x builds/runtimes/* + @shellcheck -x builds/*.sh lint-ruby: @bundle exec rubocop @@ -29,36 +26,5 @@ compile: bash -c 'cp -r /src/{bin,vendor} /buildpack && cp -r /src/$(FIXTURE) /build && mkdir /cache /env && bin/compile /build /cache /env' @echo -builder-image: - @echo "Generating binary builder image for $(STACK)..." - @echo - @docker build --pull -f builds/$(STACK).Dockerfile --platform="$(PLATFORM)" -t "$(BUILDER_IMAGE_PREFIX)-$(STACK)" . - @echo - -buildenv: builder-image - @echo "Starting build environment for $(STACK)..." - @echo - @echo "Usage..." - @echo - @echo " $$ bob build runtimes/python-X.Y.Z" - @echo - @docker run --rm -it --env-file="$(ENV_FILE)" -v $(PWD)/builds:/app/builds --platform="$(PLATFORM)" "$(BUILDER_IMAGE_PREFIX)-$(STACK)" bash - -deploy-runtimes: -ifndef RUNTIMES - $(error No runtimes specified! Use: "make deploy-runtimes RUNTIMES='python-X.Y.Z ...' [STACKS='heroku-18 ...'] [ENV_FILE=...]") -endif - @echo "Using: RUNTIMES='$(RUNTIMES)' STACKS='$(STACKS)' ENV_FILE='$(ENV_FILE)'" - @echo - @set -eu; for stack in $(STACKS); do \ - $(MAKE) builder-image STACK=$${stack}; \ - for runtime in $(RUNTIMES); do \ - echo "Generating/deploying $${runtime} for $${stack}..."; \ - echo; \ - docker run --rm -it --env-file="$(ENV_FILE)" --platform="$(PLATFORM)" "$(BUILDER_IMAGE_PREFIX)-$${stack}" bob deploy "runtimes/$${runtime}"; \ - echo; \ - done; \ - done - publish: @etc/publish.sh diff --git a/builds/Dockerfile b/builds/Dockerfile new file mode 100644 index 000000000..37e25c26f --- /dev/null +++ b/builds/Dockerfile @@ -0,0 +1,13 @@ +ARG STACK_VERSION="22" +FROM --platform=linux/amd64 heroku/heroku:${STACK_VERSION}-build + +ARG STACK_VERSION +ENV STACK="heroku-${STACK_VERSION}" + +RUN apt-get update \ + && apt-get install --no-install-recommends -y \ + libsqlite3-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /tmp +COPY build_python_runtime.sh . diff --git a/builds/README.md b/builds/README.md index a9094cf41..772d17858 100644 --- a/builds/README.md +++ b/builds/README.md @@ -1,80 +1,11 @@ # Python Buildpack Binaries -The binaries for this buildpack are built in Docker containers based on the Heroku stack image. +The binaries for this buildpack are built on GitHub Actions, inside Docker containers based on the Heroku stack image. -## Configuration +Users with suitable repository access can trigger builds by: -In order to publish binaries AWS credentials must be passed to the build container. -If you are testing only the build (ie: `bob build`), these are optional. - -In addition, unless you are building the official binaries for Heroku (which use the defaults -specified in each `Dockerfile`), you will need to override `S3_BUCKET` and `S3_PREFIX` to -match your own S3 bucket/use case. - -If you only need to set AWS credentials, you can do so by setting the environment variables -`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` before calling the make commands. - -For example: - -```bash -set +o history # Disable bash history -export AWS_ACCESS_KEY_ID=... -export AWS_SECRET_ACCESS_KEY=... -set -o history # Re-enable bash history -make ... -``` - -If you need to override the default S3 bucket, or would prefer not to use credentials via -environment variables, then you need to instead use a Docker env file like so: - -1. Copy the `builds/dockerenv.default` env file to a location outside the buildpack repository. -2. Edit the new file, adding at a minimum the values for the variables - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` (see Docker - [env-file documentation](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file)). -3. Pass the path of the file to the make commands using `ENV_FILE`. For example: - - ```bash - make ... ENV_FILE=~/.dockerenv.python-buildpack - ``` - -## Launching an interactive build environment - -To start an interactive version of the build environment (ideal for development) use the -`buildenv` make target, passing in the desired `STACK` name. For example: - -```bash -make buildenv STACK=heroku-18 -``` - -This will create the builder docker image based on the latest image for that stack, and -then start a bash shell where you can run `bob build`, `bob deploy`, and so forth. - -The `builds/` directory is bind-mounted into the running container, so local build formula -changes will appear there immediately without the need to rebuild the image. - -## Bulk deploying runtimes - -When a new Python version is released, binaries have to be generated for multiple stacks. -To automate this, use the `deploy-runtimes` make target, which will ensure the builder -image is up to date, and then run `bob deploy` for each runtime-stack combination. - -The build formula name(s) are passed using `RUNTIMES`, like so: - -```bash -make deploy-runtimes RUNTIMES='python-X.Y.Z' -``` - -By default this will deploy to all supported stacks (see `STACKS` in `Makefile`), -but this can be overridden using `STACKS`: - -```bash -make deploy-runtimes RUNTIMES='python-X.Y.Z' STACKS='heroku-18' -``` - -Multiple runtimes can also be specified (useful for when adding a new stack), like so: - -```bash -make deploy-runtimes RUNTIMES='python-A.B.C python-X.Y.Z' STACKS='heroku-22' -``` - -Note: Both `RUNTIMES` and `STACKS` are space delimited. +1. Navigating to the [Build and upload Python runtime](https://github.com/heroku/heroku-buildpack-python/actions/workflows/build_python_runtime.yml) workflow. +2. Opening the "Run workflow" prompt. +3. Entering the desired Python version. +4. Optionally checking the "Skip deploying" checkbox (if testing) +5. Clicking "Run workflow". diff --git a/builds/runtimes/python b/builds/build_python_runtime.sh similarity index 74% rename from builds/runtimes/python rename to builds/build_python_runtime.sh index ca2757e1b..b2c1ef060 100755 --- a/builds/runtimes/python +++ b/builds/build_python_runtime.sh @@ -2,47 +2,47 @@ set -euo pipefail -# This is set by bob-builder from the "Build Path" comment line in the -# build formula script that sourced this one. -OUT_PREFIX=$1 -# The filename of the script that sourced this one (e.g. `python-3.10.0`). -FORMULA_FILENAME=$(basename "${0}") -# The version component (e.g. `3.10.0`). -VERSION=$(echo "${FORMULA_FILENAME}" | cut --delimiter '-' --fields 2) - -echo "Building Python ${VERSION}..." - -if [[ "${STACK}" != "heroku-18" && "${STACK}" != "heroku-20" && "${VERSION}" == 3.[7-8].* ]]; then - echo "Python 3.7 and 3.8 are only supported on Heroku-20 and older!" >&2 - echo "Override the default stacks list using: STACKS='heroku-18 heroku-20'" >&2 +PYTHON_VERSION="${1:?"Error: The Python version to build must be specified as the first argument."}" +PYTHON_MAJOR_VERSION="${PYTHON_VERSION%.*}" + +INSTALL_DIR="/app/.heroku/python" +SRC_DIR="/tmp/src" +ARCHIVES_DIR="/tmp/upload/${STACK}/runtimes" + +echo "Building Python ${PYTHON_VERSION} for ${STACK}..." + +if [[ "${STACK}" != "heroku-18" && "${STACK}" != "heroku-20" && "${PYTHON_MAJOR_VERSION}" == 3.[7-8] ]]; then + echo "Error: Python ${PYTHON_MAJOR_VERSION} is only supported on Heroku-20 and older!" >&2 exit 1 fi -# See: https://www.python.org/downloads/ -> "OpenPGP Public Keys" -case "${VERSION}" in - 3.1[0-1].*) +# The release keys can be found on https://www.python.org/downloads/ -> "OpenPGP Public Keys". +case "${PYTHON_MAJOR_VERSION}" in + 3.10|3.11) # https://keybase.io/pablogsal/ GPG_KEY_FINGERPRINT='A035C8C19219BA821ECEA86B64E628F8D684696D' ;; - 3.[8-9].*) + 3.8|3.9) # https://keybase.io/ambv/ GPG_KEY_FINGERPRINT='E3FF2839C048B25C084DEBE9B26995E310250568' ;; - 3.7.*) + 3.7) # https://keybase.io/nad/ GPG_KEY_FINGERPRINT='0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D' ;; *) - echo "Unsupported Python version!" >&2 + echo "Error: Unsupported Python version '${PYTHON_MAJOR_VERSION}'!" >&2 exit 1 ;; esac -SOURCE_URL="https://www.python.org/ftp/python/${VERSION}/Python-${VERSION}.tgz" +SOURCE_URL="https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz" SIGNATURE_URL="${SOURCE_URL}.asc" set -o xtrace +mkdir -p "${SRC_DIR}" "${INSTALL_DIR}" "${ARCHIVES_DIR}" + curl --fail --retry 3 --retry-connrefused --connect-timeout 5 --max-time 60 -o python.tgz "${SOURCE_URL}" curl --fail --retry 3 --retry-connrefused --connect-timeout 5 --max-time 60 -o python.tgz.asc "${SIGNATURE_URL}" @@ -53,9 +53,8 @@ if [[ "${STACK}" != "heroku-18" ]]; then gpg --batch --verify python.tgz.asc python.tgz fi -mkdir src -tar --extract --file python.tgz --strip-components=1 --directory src/ -cd src +tar --extract --file python.tgz --strip-components=1 --directory "${SRC_DIR}" +cd "${SRC_DIR}" # Aim to keep this roughly consistent with the options used in the Python Docker images, # for maximum compatibility / most battle-tested build configuration: @@ -66,7 +65,7 @@ CONFIGURE_OPTS=( # Make autoconf's configure option validation more strict. "--enable-option-checking=fatal" # Install Python into `/app/.heroku/python` rather than the default of `/usr/local`. - "--prefix=${OUT_PREFIX}" + "--prefix=${INSTALL_DIR}" # Skip running `ensurepip` as part of install, since the buildpack installs a curated # version of pip itself (which ensures it's consistent across Python patch releases). "--with-ensurepip=no" @@ -75,7 +74,7 @@ CONFIGURE_OPTS=( "--with-system-expat" ) -if [[ "${VERSION}" != 3.7.* ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" != "3.7" ]]; then CONFIGURE_OPTS+=( # Python 3.7 and older run the whole test suite for PGO, which takes # much too long. Whilst this can be overridden via `PROFILE_TASK`, we @@ -85,7 +84,7 @@ if [[ "${VERSION}" != 3.7.* ]]; then ) fi -if [[ "${VERSION}" != 3.[7-9].* ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" != 3.[7-9] ]]; then CONFIGURE_OPTS+=( # Shared builds are beneficial for a number of reasons: # - Reduces the size of the build, since it avoids the duplication between @@ -108,7 +107,7 @@ if [[ "${VERSION}" != 3.[7-9].* ]]; then ) fi -if [[ "${VERSION}" == 3.11.* ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" == "3.11" ]]; then CONFIGURE_OPTS+=( # Skip building the test modules, since we remove them after the build anyway. # This feature was added in Python 3.10+, however it wasn't until Python 3.11 @@ -128,7 +127,7 @@ fi make -j "$(nproc)" LDFLAGS='-Wl,--strip-all' make install -if [[ "${VERSION}" == 3.[7-9].* ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" == 3.[7-9] ]]; then # On older versions of Python we're still building the static library, which has to be # manually stripped since the linker stripping enabled in LDFLAGS doesn't cover them. # We're using `--strip-unneeded` since `--strip-all` would remove the `.symtab` section @@ -137,9 +136,9 @@ if [[ "${VERSION}" == 3.[7-9].* ]]; then # locations, eg: # - `lib/libpython3.9.a` # - `lib/python3.9/config-3.9-x86_64-linux-gnu/libpython3.9.a` - find "${OUT_PREFIX}" -type f -name '*.a' -print -exec strip --strip-unneeded '{}' + -elif ! find "${OUT_PREFIX}" -type f -name '*.a' -print -exec false '{}' +; then - echo "Unexpected static libraries found!" >&2 + find "${INSTALL_DIR}" -type f -name '*.a' -print -exec strip --strip-unneeded '{}' + +elif ! find "${INSTALL_DIR}" -type f -name '*.a' -print -exec false '{}' +; then + echo "Error: Unexpected static libraries found!" >&2 exit 1 fi @@ -147,7 +146,7 @@ fi # https://github.com/docker-library/python # This is a no-op on Python 3.11+, since --disable-test-modules will have prevented # the test files from having been built in the first place. -find "${OUT_PREFIX}" -depth -type d -a \( -name 'test' -o -name 'tests' -o -name 'idle_test' \) -print -exec rm -rf '{}' + +find "${INSTALL_DIR}" -depth -type d -a \( -name 'test' -o -name 'tests' -o -name 'idle_test' \) -print -exec rm -rf '{}' + # The `make install` step automatically generates `.pyc` files for the stdlib, however: # - It generates these using the default `timestamp` invalidation mode, which does @@ -167,17 +166,26 @@ find "${OUT_PREFIX}" -depth -type d -a \( -name 'test' -o -name 'tests' -o -name # https://docs.python.org/3/library/compileall.html # https://peps.python.org/pep-0488/ # https://peps.python.org/pep-0552/ -find "${OUT_PREFIX}" -depth -type f -name "*.pyc" -delete +find "${INSTALL_DIR}" -depth -type f -name "*.pyc" -delete # We use the Python binary from the original build output in the source directory, -# rather than the installed binary in `$OUT_PREFIX`, for parity with the automatic +# rather than the installed binary in `$INSTALL_DIR`, for parity with the automatic # `.pyc` generation run by `make install`: -# https://github.com/python/cpython/blob/v3.10.4/Makefile.pre.in#L1603-L1629 -LD_LIBRARY_PATH="${PWD}" ./python -m compileall -f --invalidation-mode unchecked-hash --workers 0 "${OUT_PREFIX}" +# https://github.com/python/cpython/blob/v3.11.3/Makefile.pre.in#L2087-L2113 +LD_LIBRARY_PATH="${SRC_DIR}" "${SRC_DIR}/python" -m compileall -f --invalidation-mode unchecked-hash --workers 0 "${INSTALL_DIR}" # Support using Python 3 via the version-less `python` command, for parity with virtualenvs, # the Python Docker images and to also ensure buildpack Python shadows any installed system # Python, should that provide a version-less alias too. # This symlink must be relative, to ensure that the Python install remains relocatable. -ln -srvT "${OUT_PREFIX}/bin/python3" "${OUT_PREFIX}/bin/python" +ln -srvT "${INSTALL_DIR}/bin/python3" "${INSTALL_DIR}/bin/python" + +cd "${ARCHIVES_DIR}" + +# The tar file is gzipped separately, so we can set a higher gzip compression level than +# the default. In the future we'll also want to create a second archive that used zstd. +TAR_FILENAME="python-${PYTHON_VERSION}.tar" +tar --create --format=pax --sort=name --verbose --file "${TAR_FILENAME}" --directory="${INSTALL_DIR}" . +gzip --best "${TAR_FILENAME}" -du --max-depth 1 --human-readable "${OUT_PREFIX}" +du --max-depth 1 --human-readable "${INSTALL_DIR}" +du --all --human-readable "${ARCHIVES_DIR}" diff --git a/builds/dockerenv.default b/builds/dockerenv.default deleted file mode 100644 index 80517ef6d..000000000 --- a/builds/dockerenv.default +++ /dev/null @@ -1,8 +0,0 @@ -# Since no values are specified here, these variables will be read from the environment at run time: -# https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file -AWS_ACCESS_KEY_ID -AWS_SECRET_ACCESS_KEY - -# Uncomment these if you need to override the default S3 bucket and/or path prefixes. -# S3_BUCKET -# S3_PREFIX diff --git a/builds/heroku-18.Dockerfile b/builds/heroku-18.Dockerfile deleted file mode 100644 index ab992b0ba..000000000 --- a/builds/heroku-18.Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM heroku/heroku:18-build - -ENV WORKSPACE_DIR="/app/builds" \ - S3_BUCKET="heroku-buildpack-python" \ - S3_PREFIX="heroku-18/" \ - STACK="heroku-18" - -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - libsqlite3-dev \ - python3-pip \ - python3-setuptools \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /app - -COPY requirements.txt /app/ -RUN pip3 install --disable-pip-version-check --no-cache-dir -r /app/requirements.txt - -COPY . /app diff --git a/builds/heroku-20.Dockerfile b/builds/heroku-20.Dockerfile deleted file mode 100644 index 4ee19edf0..000000000 --- a/builds/heroku-20.Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM heroku/heroku:20-build - -ENV WORKSPACE_DIR="/app/builds" \ - S3_BUCKET="heroku-buildpack-python" \ - S3_PREFIX="heroku-20/" \ - STACK="heroku-20" - -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - libsqlite3-dev \ - python3-pip \ - python3-setuptools \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /app - -COPY requirements.txt /app/ -RUN pip3 install --disable-pip-version-check --no-cache-dir -r /app/requirements.txt - -COPY . /app diff --git a/builds/heroku-22.Dockerfile b/builds/heroku-22.Dockerfile deleted file mode 100644 index 9ab6b484c..000000000 --- a/builds/heroku-22.Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM heroku/heroku:22-build - -ENV WORKSPACE_DIR="/app/builds" \ - S3_BUCKET="heroku-buildpack-python" \ - S3_PREFIX="heroku-22/" \ - STACK="heroku-22" - -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - libsqlite3-dev \ - python3-pip \ - python3-setuptools \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /app - -COPY requirements.txt /app/ -RUN pip3 install --disable-pip-version-check --no-cache-dir -r /app/requirements.txt - -COPY . /app diff --git a/builds/runtimes/python-3.10.10 b/builds/runtimes/python-3.10.10 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.10.10 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.10.4 b/builds/runtimes/python-3.10.4 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.10.4 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.10.5 b/builds/runtimes/python-3.10.5 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.10.5 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.10.6 b/builds/runtimes/python-3.10.6 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.10.6 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.10.7 b/builds/runtimes/python-3.10.7 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.10.7 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.10.8 b/builds/runtimes/python-3.10.8 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.10.8 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.10.9 b/builds/runtimes/python-3.10.9 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.10.9 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.11.0 b/builds/runtimes/python-3.11.0 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.11.0 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.11.1 b/builds/runtimes/python-3.11.1 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.11.1 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.11.2 b/builds/runtimes/python-3.11.2 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.11.2 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.7.13 b/builds/runtimes/python-3.7.13 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.7.13 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.7.14 b/builds/runtimes/python-3.7.14 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.7.14 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.7.15 b/builds/runtimes/python-3.7.15 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.7.15 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.7.16 b/builds/runtimes/python-3.7.16 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.7.16 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.8.13 b/builds/runtimes/python-3.8.13 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.8.13 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.8.14 b/builds/runtimes/python-3.8.14 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.8.14 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.8.15 b/builds/runtimes/python-3.8.15 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.8.15 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.8.16 b/builds/runtimes/python-3.8.16 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.8.16 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.9.12 b/builds/runtimes/python-3.9.12 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.9.12 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.9.13 b/builds/runtimes/python-3.9.13 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.9.13 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.9.14 b/builds/runtimes/python-3.9.14 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.9.14 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.9.15 b/builds/runtimes/python-3.9.15 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.9.15 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/builds/runtimes/python-3.9.16 b/builds/runtimes/python-3.9.16 deleted file mode 100755 index 6bc9111eb..000000000 --- a/builds/runtimes/python-3.9.16 +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/python - -# shellcheck source-path=SCRIPTDIR -source "$(dirname "${0}")/python" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8394b25a7..000000000 --- a/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Dependencies for generating/publishing Python binaries. -bob-builder==0.0.19 - -# Sub-dependencies of bob-builder. -boto==2.49.0 -docopt==0.6.2