Skip to content

Commit

Permalink
Make Python version pinning pin to the major version only
Browse files Browse the repository at this point in the history
For apps that do not specify an explicit Python version (eg: via a
`.python-version` or `runtime.txt` file), the buildpack uses a curated
default version for the first build of the app.

Then for subsequent builds of the app, the buildpack selects a Python
version based on the version found in the build cache, so that the
version used for the app doesn't change in a breaking way over time as
the buildpack's own default version changes. This feature is referred to
as "version pinning" and/or "sticky versions".

The existing implementation of this feature pinned the version to the
full Python version (eg `3.13.0`), meaning that the app would always use
that exact Python version, even as newer backwards-compatible patch
releases (such as `3.13.1`) become available over time.

Now that we have Python major version -> latest patch version resolution
support (as of #1658) and improved build output around cache
invalidation reasons (as of #1679), we can switch to instead only
pinning to the major Python version (eg `3.13`). This allows apps that
do not specify a Python version to pick up any bug and security fixes
for their major Python version the next time the app is built, whilst
still keeping the compatibility properties of version pinning.

Longer term, the plan is to deprecate/sunset version pinning entirely
(since it leads to confusing UX / lack of parity between multiple apps
deployed from the same codebase at different times, eg review apps), and
the Python CNB has already dropped support for it. However, that will
be a breaking change for the classic buildpack, so out of scope for now.

GUS-W-17384879.
  • Loading branch information
edmorley committed Dec 6, 2024
1 parent cd69eb3 commit cc277c9
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 18 deletions.
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]

- Changed Python version pinning behaviour for apps that do not specify a Python version. Repeat builds are now pinned to the major Python version only (`3.X`) instead of the full Python version (`3.X.Y`), so that they always use the latest patch version. ([#1714](https://github.com/heroku/heroku-buildpack-python/pull/1714))

## [v269] - 2024-12-04

Expand Down
13 changes: 4 additions & 9 deletions spec/hatchet/python_version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,15 @@
app.push!
expect(clean_output(app.output)).to include(<<~OUTPUT)
remote: -----> Python app detected
remote: -----> No Python version was specified. Using the same version as the last build: Python 3.12.6
remote: -----> No Python version was specified. Using the same major version as the last build: Python 3.12
remote: To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes
remote: -----> Discarding cache since:
remote: - The Python version has changed from 3.12.6 to #{LATEST_PYTHON_3_12}
remote: - The pip version has changed from 24.0 to #{PIP_VERSION}
remote: -----> Installing Python 3.12.6
remote:
remote: ! Warning: A Python security update is available!
remote: !
remote: ! Upgrade as soon as possible to: Python #{LATEST_PYTHON_3_12}
remote: ! See: https://devcenter.heroku.com/articles/python-runtimes
remote:
remote: -----> Installing Python #{LATEST_PYTHON_3_12}
remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION}
OUTPUT
expect(app.run('python -V')).to include('Python 3.12.6')
expect(app.run('python -V')).to include("Python #{LATEST_PYTHON_3_12}")
end
end
end
Expand Down
13 changes: 4 additions & 9 deletions spec/hatchet/stack_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,13 @@
app.push!
expect(clean_output(app.output)).to include(<<~OUTPUT)
remote: -----> Python app detected
remote: -----> No Python version was specified. Using the same version as the last build: Python 3.12.3
remote: -----> No Python version was specified. Using the same major version as the last build: Python 3.12
remote: To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes
remote: -----> Discarding cache since:
remote: - The stack has changed from heroku-22 to heroku-24
remote: - The Python version has changed from 3.12.3 to #{LATEST_PYTHON_3_12}
remote: - The pip version has changed
remote: -----> Installing Python 3.12.3
remote:
remote: ! Warning: A Python security update is available!
remote: !
remote: ! Upgrade as soon as possible to: Python #{LATEST_PYTHON_3_12}
remote: ! See: https://devcenter.heroku.com/articles/python-runtimes
remote:
remote: -----> Installing Python #{LATEST_PYTHON_3_12}
remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION}
remote: -----> Installing SQLite3
remote: -----> Installing dependencies using 'pip install -r requirements.txt'
Expand All @@ -53,7 +48,7 @@
app.push!
expect(clean_output(app.output)).to include(<<~OUTPUT)
remote: -----> Python app detected
remote: -----> No Python version was specified. Using the same version as the last build: Python #{DEFAULT_PYTHON_FULL_VERSION}
remote: -----> No Python version was specified. Using the same major version as the last build: Python #{DEFAULT_PYTHON_MAJOR_VERSION}
remote: To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes
remote: -----> Discarding cache since:
remote: - The stack has changed from heroku-24 to heroku-22
Expand Down

0 comments on commit cc277c9

Please sign in to comment.