diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f92ac8a18..8826ce8e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: strategy: fail-fast: false matrix: - stack: ["heroku-22", "heroku-24"] + stack: ["heroku-22", "heroku-24", "heroku-26"] env: HATCHET_APP_LIMIT: 300 HATCHET_DEFAULT_STACK: ${{ matrix.stack }} diff --git a/CHANGELOG.md b/CHANGELOG.md index fc63d204e..c68979af4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased] +- Added support for Heroku-26. ([#2073](https://github.com/heroku/heroku-buildpack-python/pull/2073)) ## [v341] - 2026-04-07 diff --git a/Makefile b/Makefile index ea5971da4..f1afaf93d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # These targets are not files .PHONY: lint lint-scripts lint-ruby check-format format run publish -STACK ?= heroku-24 +STACK ?= heroku-26 FIXTURE ?= spec/fixtures/python_version_unspecified # Allow overriding the exit code in CI, so we can test bin/report works for failing builds. COMPILE_FAILURE_EXIT_CODE ?= 1 diff --git a/lib/checks.sh b/lib/checks.sh index e6f222954..5e9e4b65e 100644 --- a/lib/checks.sh +++ b/lib/checks.sh @@ -4,7 +4,7 @@ function checks::ensure_supported_stack() { local stack="${1}" case "${stack}" in - heroku-22 | heroku-24) + heroku-22 | heroku-24 | heroku-26) return 0 ;; cedar* | heroku-16 | heroku-18 | heroku-20) diff --git a/spec/fixtures/python_version_outdated/.python-version b/spec/fixtures/python_version_outdated/.python-version index 3e388a4ac..f982feb41 100644 --- a/spec/fixtures/python_version_outdated/.python-version +++ b/spec/fixtures/python_version_outdated/.python-version @@ -1 +1 @@ -3.13.2 +3.14.0 diff --git a/spec/hatchet/pipenv_spec.rb b/spec/hatchet/pipenv_spec.rb index c451b1d35..2ee6cb83b 100644 --- a/spec/hatchet/pipenv_spec.rb +++ b/spec/hatchet/pipenv_spec.rb @@ -455,7 +455,10 @@ end end - context 'when the Pipenv and Python versions have changed since the last build' do + # TODO: Enable on Heroku-26 after the Pipenv and default Python versions next change, + # since for now there isn't a historic buildpack version we can use in this test whose + # stack check permits Heroku-26 and that also uses older Pipenv/Python versions. + context 'when the Pipenv and Python versions have changed since the last build', stacks: %w[heroku-22 heroku-24] do let(:buildpacks) { ['https://github.com/heroku/heroku-buildpack-python#v313'] } let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_basic', buildpacks:) } diff --git a/spec/hatchet/poetry_spec.rb b/spec/hatchet/poetry_spec.rb index 74832d7f1..25aad1ada 100644 --- a/spec/hatchet/poetry_spec.rb +++ b/spec/hatchet/poetry_spec.rb @@ -131,7 +131,10 @@ end end - context 'when the Poetry and Python versions have changed since the last build' do + # TODO: Enable on Heroku-26 after the Poetry and default Python versions next change, + # since for now there isn't a historic buildpack version we can use in this test whose + # stack check permits Heroku-26 and that also uses older Poetry/Python versions. + context 'when the Poetry and Python versions have changed since the last build', stacks: %w[heroku-22 heroku-24] do let(:buildpacks) { ['https://github.com/heroku/heroku-buildpack-python#v313'] } let(:app) { Hatchet::Runner.new('spec/fixtures/poetry_basic', buildpacks:) } diff --git a/spec/hatchet/python_version_spec.rb b/spec/hatchet/python_version_spec.rb index e779fffbc..93db7cda9 100644 --- a/spec/hatchet/python_version_spec.rb +++ b/spec/hatchet/python_version_spec.rb @@ -88,17 +88,21 @@ end end - context 'with an app last built using an older default Python version' do + # TODO: Enable on Heroku-26 after the default Python version next changes (for the 3.14.5 + # release), since for now there isn't a historic buildpack version we can use in this test + # whose stack check permits Heroku-26 and also has a different default Python version so + # that we can test the sticky versions feature. + context 'with an app last built using an older default Python version', stacks: %w[heroku-22 heroku-24] do # This test performs an initial build using an older buildpack version, followed # by a build using the current version. This ensures that: # - The current buildpack can successfully read the version metadata # written to the build cache by older buildpack versions. # - If no Python version is specified, the same major version as the - # last build is used (sticky versioning). + # last build is used (sticky major versioning). # - Changes in the pip version are handled correctly. let(:buildpacks) { ['https://github.com/heroku/heroku-buildpack-python#v267'] } - it 'builds with the same Python version as the last build' do + it 'builds with the same major Python version as the last build' do app.deploy do |app| update_buildpacks(app, [:default]) app.commit! @@ -566,12 +570,12 @@ app.deploy do |app| expect(clean_output(app.output)).to include(<<~OUTPUT) remote: -----> Python app detected - remote: -----> Using Python 3.13.2 specified in .python-version + remote: -----> Using Python 3.14.0 specified in .python-version remote: remote: ! Warning: A Python patch update is available! remote: ! - remote: ! Your app is using Python 3.13.2, however, there is a newer - remote: ! patch release of Python 3.13 available: #{LATEST_PYTHON_3_13} + remote: ! Your app is using Python 3.14.0, however, there is a newer + remote: ! patch release of Python 3.14 available: #{LATEST_PYTHON_3_14} remote: ! remote: ! It is important to always use the latest patch version of remote: ! Python to keep your app secure. @@ -579,12 +583,12 @@ remote: ! Update your .python-version file to use the new version. remote: ! remote: ! We strongly recommend that you don't pin your app to an - remote: ! exact Python version such as 3.13.2, and instead only specify - remote: ! the major Python version of 3.13 in your .python-version file. + remote: ! exact Python version such as 3.14.0, and instead only specify + remote: ! the major Python version of 3.14 in your .python-version file. remote: ! This will allow your app to receive the latest available Python remote: ! patch version automatically and prevent this warning. remote: - remote: -----> Installing Python 3.13.2 + remote: -----> Installing Python 3.14.0 remote: -----> Installing pip #{PIP_VERSION} OUTPUT end diff --git a/spec/hatchet/stack_spec.rb b/spec/hatchet/stack_spec.rb index 8fe115496..0aebe7179 100644 --- a/spec/hatchet/stack_spec.rb +++ b/spec/hatchet/stack_spec.rb @@ -3,7 +3,7 @@ require_relative '../spec_helper' RSpec.describe 'Stack changes' do - context 'when the stack is upgraded from Heroku-22 to Heroku-24', stacks: %w[heroku-22] do + context 'when the stack is upgraded from Heroku-24 to Heroku-26', stacks: %w[heroku-24] do # This test performs an initial build using an older buildpack version, followed by a build # using the current version. This ensures that the current buildpack can successfully read # the stack metadata written to the build cache in the past. The buildpack version chosen is @@ -14,8 +14,8 @@ it 'clears the cache before installing again whilst preserving the sticky Python version' do app.deploy do |app| - expect(app.output).to include('Building on the Heroku-22 stack') - app.update_stack('heroku-24') + expect(app.output).to include('Building on the Heroku-24 stack') + app.update_stack('heroku-26') update_buildpacks(app, [:default]) app.commit! app.push! @@ -64,7 +64,7 @@ remote: ! file and this warning will be made an error. remote: remote: -----> Discarding cache since: - remote: - The stack has changed from heroku-22 to heroku-24 + remote: - The stack has changed from heroku-24 to heroku-26 remote: - The Python version has changed from 3.12.3 to #{LATEST_PYTHON_3_12} remote: - The buildpack cache format has changed remote: - The legacy SQLite3 headers and CLI binary need to be uninstalled @@ -77,20 +77,20 @@ end end - context 'when the stack is downgraded from Heroku-24 to Heroku-22', stacks: %w[heroku-24] do + context 'when the stack is downgraded from Heroku-26 to Heroku-24', stacks: %w[heroku-26] do let(:app) { Hatchet::Runner.new('spec/fixtures/python_3.14') } it 'clears the cache before installing again' do app.deploy do |app| - expect(app.output).to include('Building on the Heroku-24 stack') - app.update_stack('heroku-22') + expect(app.output).to include('Building on the Heroku-26 stack') + app.update_stack('heroku-24') app.commit! app.push! expect(clean_output(app.output)).to include(<<~OUTPUT) remote: -----> Python app detected remote: -----> Using Python 3.14 specified in .python-version remote: -----> Discarding cache since: - remote: - The stack has changed from heroku-24 to heroku-22 + remote: - The stack has changed from heroku-26 to heroku-24 remote: -----> Installing Python #{LATEST_PYTHON_3_14} remote: -----> Installing pip #{PIP_VERSION} remote: -----> Installing dependencies using 'pip install -r requirements.txt' diff --git a/spec/hatchet/uv_spec.rb b/spec/hatchet/uv_spec.rb index 9eedb5af6..716afee90 100644 --- a/spec/hatchet/uv_spec.rb +++ b/spec/hatchet/uv_spec.rb @@ -128,7 +128,10 @@ end end - context 'when the uv and Python versions have changed since the last build' do + # TODO: Enable on Heroku-26 after the uv and default Python versions next change, + # since for now there isn't a historic buildpack version we can use in this test + # whose stack check permits Heroku-26 and that also uses older uv/Python versions. + context 'when the uv and Python versions have changed since the last build', stacks: %w[heroku-22 heroku-24] do let(:buildpacks) { ['https://github.com/heroku/heroku-buildpack-python#v313'] } let(:app) { Hatchet::Runner.new('spec/fixtures/uv_basic', buildpacks:) } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 25ea11c6d..617c73d04 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true ENV['HATCHET_BUILDPACK_BASE'] ||= 'https://github.com/heroku/heroku-buildpack-python.git' -ENV['HATCHET_DEFAULT_STACK'] ||= 'heroku-24' +ENV['HATCHET_DEFAULT_STACK'] ||= 'heroku-26' require 'English' # for $CHILD_STATUS require 'rspec/core'