Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
parameters:
stack:
type: enum
enum: ["heroku-18", "heroku-20"]
enum: ["heroku-18", "heroku-20", "heroku-22"]
docker:
- image: cimg/ruby:2.7
working_directory: /mnt/ramdisk/project
Expand Down Expand Up @@ -87,4 +87,4 @@ workflows:
- hatchet:
matrix:
parameters:
stack: ["heroku-18", "heroku-20"]
stack: ["heroku-18", "heroku-20", "heroku-22"]
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Add support for Heroku-22 ([#1299](https://github.com/heroku/heroku-buildpack-python/pull/1299)).

## v211 (2022-05-17)

Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# These targets are not files
.PHONY: lint lint-scripts lint-ruby compile builder-image buildenv deploy-runtimes publish

STACK ?= heroku-20
STACKS ?= heroku-18 heroku-20
STACK ?= heroku-22
STACKS ?= heroku-18 heroku-20 heroku-22
PLATFORM := linux/amd64
FIXTURE ?= spec/fixtures/python_version_unspecified
ENV_FILE ?= builds/dockerenv.default
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Specify a Python Runtime

Supported runtime options include:

- `python-3.10.4`
- `python-3.9.13`
- `python-3.8.13`
- `python-3.7.13`
- `python-3.10.4` on all [supported stacks](https://devcenter.heroku.com/articles/stack#stack-support-details)
- `python-3.9.13` on all [supported stacks](https://devcenter.heroku.com/articles/stack#stack-support-details)
- `python-3.8.13` on Heroku-18 and Heroku-20 only
- `python-3.7.13` on Heroku-18 and Heroku-20 only
2 changes: 1 addition & 1 deletion builds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ 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-20'
make deploy-runtimes RUNTIMES='python-A.B.C python-X.Y.Z' STACKS='heroku-22'
```

Note: Both `RUNTIMES` and `STACKS` are space delimited.
20 changes: 20 additions & 0 deletions builds/heroku-22.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
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
6 changes: 6 additions & 0 deletions builds/runtimes/python
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ 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
exit 1
fi

# See: https://www.python.org/downloads/ -> "OpenPGP Public Keys"
case "${VERSION}" in
3.10.*)
Expand Down
2 changes: 1 addition & 1 deletion spec/fixtures/python_3.9_outdated/runtime.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
python-3.9.0
python-3.9.12
8 changes: 2 additions & 6 deletions spec/hatchet/getting_started_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
require_relative '../spec_helper'

RSpec.describe 'Python getting started project' do
it 'getting started app has no relative paths' do
buildpacks = [
:default,
'https://github.com/sharpstone/force_absolute_paths_buildpack'
]
Hatchet::Runner.new('python-getting-started', buildpacks: buildpacks).deploy do |app|
it 'builds successfully' do
Hatchet::Runner.new('python-getting-started').deploy do |app|
# Deploy works
end
end
Expand Down
134 changes: 90 additions & 44 deletions spec/hatchet/pipenv_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@
end
end

RSpec.shared_examples 'aborts the build with a runtime not available message (Pipenv)' do |requested_version|
it 'aborts the build with a runtime not available message' do
app.deploy do |app|
expect(clean_output(app.output)).to include(<<~OUTPUT)
remote: -----> Python app detected
remote: -----> Using Python version specified in Pipfile.lock
remote: ! Requested runtime (python-#{requested_version}) is not available for this stack (#{app.stack}).
remote: ! Aborting. More info: https://devcenter.heroku.com/articles/python-support
OUTPUT
end
end
end

RSpec.describe 'Pipenv support' do
context 'without a Pipfile.lock' do
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_no_lockfile') }
Expand Down Expand Up @@ -85,20 +98,11 @@
end
end

context 'when using Heroku-20', stacks: %w[heroku-20] do
context 'when using Heroku-20 or newer', stacks: %w[heroku-20 heroku-22] do
let(:allow_failure) { true }

it 'fails the build' do
# Python 2.7 is EOL, so it has not been built for Heroku-20.
app.deploy do |app|
expect(clean_output(app.output)).to include(<<~OUTPUT)
remote: -----> Python app detected
remote: -----> Using Python version specified in Pipfile.lock
remote: ! Requested runtime (python-#{LATEST_PYTHON_2_7}) is not available for this stack (#{app.stack}).
remote: ! Aborting. More info: https://devcenter.heroku.com/articles/python-support
OUTPUT
end
end
# Python 2.7 is EOL, so has not been built for newer stacks.
include_examples 'aborts the build with a runtime not available message (Pipenv)', LATEST_PYTHON_2_7
end
end

Expand All @@ -112,34 +116,64 @@
end

context 'with a Pipfile.lock containing python_version 3.6' do
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_python_3.6') }
let(:allow_failure) { false }
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_python_3.6', allow_failure: allow_failure) }

it 'builds with the latest Python 3.6' do
app.deploy do |app|
expect(clean_output(app.output)).to match(Regexp.new(<<~REGEX))
remote: -----> Python app detected
remote: -----> Using Python version specified in Pipfile.lock
remote: cp: cannot stat '/tmp/build_.*/requirements.txt': No such file or directory
remote: -----> Installing python-#{LATEST_PYTHON_3_6}
remote: -----> Installing pip 21.3.1, setuptools 59.6.0 and wheel 0.37.1
remote: -----> Installing dependencies with Pipenv 2020.11.15
remote: Installing dependencies from Pipfile.lock \\(.*\\)...
remote: -----> Installing SQLite3
REGEX
context 'when using Heroku-18 or Heroku-20', stacks: %w[heroku-18 heroku-20] do
it 'builds with the latest Python 3.6' do
app.deploy do |app|
expect(clean_output(app.output)).to match(Regexp.new(<<~REGEX))
remote: -----> Python app detected
remote: -----> Using Python version specified in Pipfile.lock
remote: cp: cannot stat '/tmp/build_.*/requirements.txt': No such file or directory
remote: -----> Installing python-#{LATEST_PYTHON_3_6}
remote: -----> Installing pip 21.3.1, setuptools 59.6.0 and wheel 0.37.1
remote: -----> Installing dependencies with Pipenv 2020.11.15
remote: Installing dependencies from Pipfile.lock \\(.*\\)...
remote: -----> Installing SQLite3
REGEX
end
end
end

context 'when using Heroku-22', stacks: %w[heroku-22] do
let(:allow_failure) { true }

# Python 3.6 is EOL, so has not been built for newer stacks.
include_examples 'aborts the build with a runtime not available message (Pipenv)', LATEST_PYTHON_3_6
end
end

context 'with a Pipfile.lock containing python_version 3.7' do
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_python_3.7') }
let(:allow_failure) { false }
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_python_3.7', allow_failure: allow_failure) }

include_examples 'builds using Pipenv with the requested Python version', LATEST_PYTHON_3_7
context 'when using Heroku-18 or Heroku-20', stacks: %w[heroku-18 heroku-20] do
include_examples 'builds using Pipenv with the requested Python version', LATEST_PYTHON_3_7
end

context 'when using Heroku-22', stacks: %w[heroku-22] do
let(:allow_failure) { true }

# Python 3.7 is in the security fix only stage of its lifecycle, so has not been built for newer stacks.
include_examples 'aborts the build with a runtime not available message (Pipenv)', LATEST_PYTHON_3_7
end
end

context 'with a Pipfile.lock containing python_version 3.8' do
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_python_3.8') }
let(:allow_failure) { false }
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_python_3.8', allow_failure: allow_failure) }

context 'when using Heroku-18 or Heroku-20', stacks: %w[heroku-18 heroku-20] do
include_examples 'builds using Pipenv with the requested Python version', LATEST_PYTHON_3_8
end

include_examples 'builds using Pipenv with the requested Python version', LATEST_PYTHON_3_8
context 'when using Heroku-22', stacks: %w[heroku-22] do
let(:allow_failure) { true }

# Python 3.8 is in the security fix only stage of its lifecycle, so has not been built for newer stacks.
include_examples 'aborts the build with a runtime not available message (Pipenv)', LATEST_PYTHON_3_8
end
end

context 'with a Pipfile.lock containing python_version 3.9' do
Expand All @@ -155,24 +189,36 @@
end

context 'with a Pipfile.lock containing python_full_version 3.10.0' do
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_python_full_version') }
let(:allow_failure) { false }
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_python_full_version', allow_failure: allow_failure) }

it 'builds with the outdated Python version specified' do
app.deploy do |app|
expect(clean_output(app.output)).to match(Regexp.new(<<~REGEX))
remote: -----> Python app detected
remote: -----> Using Python version specified in Pipfile.lock
remote: ! Python has released a security update! Please consider upgrading to python-#{LATEST_PYTHON_3_10}
remote: Learn More: https://devcenter.heroku.com/articles/python-runtimes
remote: cp: cannot stat '/tmp/build_.*/requirements.txt': No such file or directory
remote: -----> Installing python-3.10.0
remote: -----> Installing pip 22.0.4, setuptools 60.10.0 and wheel 0.37.1
remote: -----> Installing dependencies with Pipenv 2020.11.15
remote: Installing dependencies from Pipfile.lock \\(99d8c9\\)...
remote: -----> Installing SQLite3
REGEX
context 'when using Heroku-18 or Heroku-20', stacks: %w[heroku-18 heroku-20] do
it 'builds with the outdated Python version specified' do
app.deploy do |app|
expect(clean_output(app.output)).to match(Regexp.new(<<~REGEX))
remote: -----> Python app detected
remote: -----> Using Python version specified in Pipfile.lock
remote: ! Python has released a security update! Please consider upgrading to python-#{LATEST_PYTHON_3_10}
remote: Learn More: https://devcenter.heroku.com/articles/python-runtimes
remote: cp: cannot stat '/tmp/build_.*/requirements.txt': No such file or directory
remote: -----> Installing python-3.10.0
remote: -----> Installing pip 22.0.4, setuptools 60.10.0 and wheel 0.37.1
remote: -----> Installing dependencies with Pipenv 2020.11.15
remote: Installing dependencies from Pipfile.lock \\(99d8c9\\)...
remote: -----> Installing SQLite3
REGEX
end
end
end

context 'when using Heroku-22', stacks: %w[heroku-22] do
let(:allow_failure) { true }

# Whilst Python 3.10 is supported on Heroku-22, only the latest version (3.10.4) has been built.
# TODO: Once newer Python 3.10 versions are released, adjust this test to use 3.10.4,
# which will work for all stacks.
include_examples 'aborts the build with a runtime not available message (Pipenv)', '3.10.0'
end
end

context 'with a Pipfile.lock containing an invalid python_version',
Expand Down
Loading