Merge branch 'main' into 1455-fail-earlier

pull/1456/head
Min RK 2025-09-03 10:11:17 -07:00 zatwierdzone przez GitHub
commit 53e8ce11a7
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
13 zmienionych plików z 211 dodań i 65 usunięć

Wyświetl plik

@ -5,23 +5,23 @@
(And thank you particularly for coming to read the guidelines! :heart_eyes:) (And thank you particularly for coming to read the guidelines! :heart_eyes:)
The repo2docker developer documentation is all rendered on our documentation website: [https://repo2docker.readthedocs.io](https://repo2docker.readthedocs.io). The repo2docker developer documentation is all rendered on our documentation website: [https://repo2docker.readthedocs.io](https://repo2docker.readthedocs.io).
If you're here, you're probably looking for the [Contributing to repo2docker development](https://repo2docker.readthedocs.io/en/latest/contributing/contributing.html) page. If you're here, you're probably looking for the [Contributing to repo2docker development](https://repo2docker.readthedocs.io/en/latest/contribute/contributing.html) page.
Please make sure you've read the following sections before opening an issue/pull request: Please make sure you've read the following sections before opening an issue/pull request:
- [Process for making a contribution](https://repo2docker.readthedocs.io/en/latest/contributing/contributing.html#process-for-making-a-contribution). - [Process for making a contribution](https://repo2docker.readthedocs.io/en/latest/contribute/contributing.html#process-for-making-a-contribution).
- These steps talk you through choosing the right issue template (bug report or feature request) and making a change. - These steps talk you through choosing the right issue template (bug report or feature request) and making a change.
- [Guidelines to getting a Pull Request merged](https://repo2docker.readthedocs.io/en/latest/contributing/contributing.html#guidelines-to-getting-a-pull-request-merged). - [Guidelines to getting a Pull Request merged](https://repo2docker.readthedocs.io/en/latest/contribute/contributing.html#guidelines-to-getting-a-pull-request-merged).
- These are tips and tricks to help make your contribution as smooth as possible for you and for the repo2docker maintenance team. - These are tips and tricks to help make your contribution as smooth as possible for you and for the repo2docker maintenance team.
There are a few other pages to highlight: There are a few other pages to highlight:
- [Our roadmap](https://repo2docker.readthedocs.io/en/latest/contributing/roadmap.html) - [Our roadmap](https://repo2docker.readthedocs.io/en/latest/contribute/roadmap.html)
- We use the roadmap to develop a shared understanding of the project's vision and direction amongst the community of users, contributors, and maintainers. - We use the roadmap to develop a shared understanding of the project's vision and direction amongst the community of users, contributors, and maintainers.
This is a great place to get a feel for what the maintainers are thinking about for the short, medium, and long term future of the project. This is a great place to get a feel for what the maintainers are thinking about for the short, medium, and long term future of the project.
- [Design of repo2docker](https://repo2docker.readthedocs.io/en/latest/design.html) - [Design of repo2docker](https://repo2docker.readthedocs.io/en/latest/design.html)
- This page explains some of the design principles behind repo2docker. - This page explains some of the design principles behind repo2docker.
Its a good place to understand _why_ the team have made the decisions that they have along the way! Its a good place to understand _why_ the team have made the decisions that they have along the way!
- We absolutely encourage discussion around refactoring, updating or extending repo2docker, but please make sure that you've understood this page before opening an issue to discuss the change you'd like to propose. - We absolutely encourage discussion around refactoring, updating or extending repo2docker, but please make sure that you've understood this page before opening an issue to discuss the change you'd like to propose.
- [Common developer tasks and how-tos](https://repo2docker.readthedocs.io/en/latest/contributing/tasks.html) - [Common developer tasks and how-tos](https://repo2docker.readthedocs.io/en/latest/contribute/tasks.html)
- Some notes on running tests, buildpack dependencies, creating a release, and keeping the pip files up to date. - Some notes on running tests, buildpack dependencies, creating a release, and keeping the pip files up to date.

Wyświetl plik

@ -1,5 +1,80 @@
# Changelog # Changelog
## Unreleased breaking changes
`RBuildPack.runtime` previously returned the contents of `runtime.txt` as a string.
It has been replaced by `BuildPack.runtime` which returns a tuple `(name, version, date)`.
## 2025.08.0
([full changelog](https://github.com/jupyterhub/repo2docker/compare/4da768765372c602c06606cb79d21a398fcc2987...6cf91e45d5b03f79e365cd82eda09d1178d03327))
### API and Breaking Changes
- Switch to using CLI for everything except running the container [#1421](https://github.com/jupyterhub/repo2docker/pull/1421) ([@yuvipanda](https://github.com/yuvipanda), [@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
- Require Python 3.9 to run repo2docker [#1411](https://github.com/jupyterhub/repo2docker/pull/1411) ([@manics](https://github.com/manics), [@minrk](https://github.com/minrk), [@yuvipanda](https://github.com/yuvipanda))
- Shell out to `docker buildx build` to build images [#1402](https://github.com/jupyterhub/repo2docker/pull/1402) ([@yuvipanda](https://github.com/yuvipanda), [@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
- notebook 7 [#1363](https://github.com/jupyterhub/repo2docker/pull/1363) ([@minrk](https://github.com/minrk), [@manics](https://github.com/manics))
- Major version bump node (18->20) and jupyterhub-singleuser (3->5) [#1359](https://github.com/jupyterhub/repo2docker/pull/1359) ([@consideRatio](https://github.com/consideRatio), [@yuvipanda](https://github.com/yuvipanda))
### Enhancements made
- add triplets for r versions 4.3, 4.4 [#1403](https://github.com/jupyterhub/repo2docker/pull/1403) ([@minrk](https://github.com/minrk), [@yuvipanda](https://github.com/yuvipanda), [@manics](https://github.com/manics))
- Upgrade Shiny server to 2024.12 [#1400](https://github.com/jupyterhub/repo2docker/pull/1400) ([@rgaiacs](https://github.com/rgaiacs), [@manics](https://github.com/manics))
- Upgrade RStudio to 2024.12 [#1399](https://github.com/jupyterhub/repo2docker/pull/1399) ([@rgaiacs](https://github.com/rgaiacs), [@manics](https://github.com/manics))
- Use REST APIs to resolve DOIs + cleanup dataverse provider [#1390](https://github.com/jupyterhub/repo2docker/pull/1390) ([@yuvipanda](https://github.com/yuvipanda), [@minrk](https://github.com/minrk), [@pdurbin](https://github.com/pdurbin))
- exclude defaults channel by default [#1365](https://github.com/jupyterhub/repo2docker/pull/1365) ([@minrk](https://github.com/minrk), [@rgaiacs](https://github.com/rgaiacs))
### Bugs fixed
- [MRG] Disable bash trace output in conda activation script [#1425](https://github.com/jupyterhub/repo2docker/pull/1425) ([@mfisher87](https://github.com/mfisher87), [@manics](https://github.com/manics))
- Simulate json output from docker buildx build [#1413](https://github.com/jupyterhub/repo2docker/pull/1413) ([@yuvipanda](https://github.com/yuvipanda), [@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
- `set -e` should not be set after conda environment is sourced [#1409](https://github.com/jupyterhub/repo2docker/pull/1409) ([@manics](https://github.com/manics), [@yuvipanda](https://github.com/yuvipanda))
- Use self.log rather than logging module directly [#1378](https://github.com/jupyterhub/repo2docker/pull/1378) ([@yuvipanda](https://github.com/yuvipanda), [@manics](https://github.com/manics))
- julia_project.py: fix Pkg REPL api warning [#1376](https://github.com/jupyterhub/repo2docker/pull/1376) ([@fonsp](https://github.com/fonsp), [@GeorgianaElena](https://github.com/GeorgianaElena), [@agoose77](https://github.com/agoose77))
- TarFile.add: don't add recursively [#1371](https://github.com/jupyterhub/repo2docker/pull/1371) ([@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
### Maintenance and upkeep improvements
- Bump mamba from 2.0.5 to 2.1.0 [#1423](https://github.com/jupyterhub/repo2docker/pull/1423) ([@weiji14](https://github.com/weiji14), [@yuvipanda](https://github.com/yuvipanda))
- maint: Adapt mamba activation [#1419](https://github.com/jupyterhub/repo2docker/pull/1419) ([@jjerphan](https://github.com/jjerphan), [@yuvipanda](https://github.com/yuvipanda), [@minrk](https://github.com/minrk))
- Add a test for runtime.txt with full R version specified [#1416](https://github.com/jupyterhub/repo2docker/pull/1416) ([@yuvipanda](https://github.com/yuvipanda), [@minrk](https://github.com/minrk))
- Bump alpine docker to 3.21 [#1412](https://github.com/jupyterhub/repo2docker/pull/1412) ([@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
- Refreeze base environment for package upgrades [#1407](https://github.com/jupyterhub/repo2docker/pull/1407) ([@yuvipanda](https://github.com/yuvipanda), [@manics](https://github.com/manics))
- Remove unused \_urlopen method [#1392](https://github.com/jupyterhub/repo2docker/pull/1392) ([@yuvipanda](https://github.com/yuvipanda), [@minrk](https://github.com/minrk))
- Upgraded to micromamba 2.0.5 [#1387](https://github.com/jupyterhub/repo2docker/pull/1387) ([@JohanMabille](https://github.com/JohanMabille), [@yuvipanda](https://github.com/yuvipanda), [@SylvainCorlay](https://github.com/SylvainCorlay))
- Use self.log.warning instead of warnings.warn [#1384](https://github.com/jupyterhub/repo2docker/pull/1384) ([@yuvipanda](https://github.com/yuvipanda), [@manics](https://github.com/manics))
- call close_handlers before garbage collection [#1380](https://github.com/jupyterhub/repo2docker/pull/1380) ([@minrk](https://github.com/minrk), [@manics](https://github.com/manics))
- [pre-commit.ci] pre-commit autoupdate [#1377](https://github.com/jupyterhub/repo2docker/pull/1377) ([@minrk](https://github.com/minrk))
- Update to mamba 1.5.9 [#1370](https://github.com/jupyterhub/repo2docker/pull/1370) ([@SylvainCorlay](https://github.com/SylvainCorlay), [@manics](https://github.com/manics))
- Refreeze conda packages (JupyterLab 4.2.3 -> 4.2.5) [#1369](https://github.com/jupyterhub/repo2docker/pull/1369) ([@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
- Update for mamba 1.5.8 [#1367](https://github.com/jupyterhub/repo2docker/pull/1367) ([@jjerphan](https://github.com/jjerphan), [@manics](https://github.com/manics), [@SylvainCorlay](https://github.com/SylvainCorlay))
- update import of shlex.quote [#1364](https://github.com/jupyterhub/repo2docker/pull/1364) ([@minrk](https://github.com/minrk), [@manics](https://github.com/manics))
- [pre-commit.ci] pre-commit autoupdate [#1362](https://github.com/jupyterhub/repo2docker/pull/1362) ([@minrk](https://github.com/minrk))
### Documentation improvements
- Revamp our documentation and refactor a bit [#1433](https://github.com/jupyterhub/repo2docker/pull/1433) ([@choldgraf](https://github.com/choldgraf), [@chuckwondo](https://github.com/chuckwondo), [@rgaiacs](https://github.com/rgaiacs), [@yuvipanda](https://github.com/yuvipanda))
- bug report.rst [#1429](https://github.com/jupyterhub/repo2docker/pull/1429) ([@nadiaguiffant](https://github.com/nadiaguiffant), [@manics](https://github.com/manics))
- Add changelog for 2024.07.0 [#1356](https://github.com/jupyterhub/repo2docker/pull/1356) ([@yuvipanda](https://github.com/yuvipanda), [@consideRatio](https://github.com/consideRatio), [@manics](https://github.com/manics))
### Continuous integration improvements
- Add basic UI Playwright tests [#1410](https://github.com/jupyterhub/repo2docker/pull/1410) ([@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
- Don't run scheduled workflows on forks [#1408](https://github.com/jupyterhub/repo2docker/pull/1408) ([@manics](https://github.com/manics), [@yuvipanda](https://github.com/yuvipanda))
- build(deps): bump codecov/codecov-action from 4 to 5 [#1381](https://github.com/jupyterhub/repo2docker/pull/1381) ([@minrk](https://github.com/minrk))
- [pre-commit.ci] pre-commit autoupdate [#1358](https://github.com/jupyterhub/repo2docker/pull/1358) ([@minrk](https://github.com/minrk))
- build(deps): bump docker/build-push-action from 5 to 6 [#1357](https://github.com/jupyterhub/repo2docker/pull/1357) ([@manics](https://github.com/manics))
### Contributors to this release
The following people contributed discussions, new ideas, code and documentation contributions, and review.
See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports).
([GitHub contributors page for this release](https://github.com/jupyterhub/repo2docker/graphs/contributors?from=2024-07-01&to=2025-08-03&type=c))
@agoose77 ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Aagoose77+updated%3A2024-07-01..2025-08-03&type=Issues)) | @AliMirlou ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3AAliMirlou+updated%3A2024-07-01..2025-08-03&type=Issues)) | @betatim ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Abetatim+updated%3A2024-07-01..2025-08-03&type=Issues)) | @choldgraf ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Acholdgraf+updated%3A2024-07-01..2025-08-03&type=Issues)) | @chuckwondo ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Achuckwondo+updated%3A2024-07-01..2025-08-03&type=Issues)) | @consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3AconsideRatio+updated%3A2024-07-01..2025-08-03&type=Issues)) | @d70-t ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Ad70-t+updated%3A2024-07-01..2025-08-03&type=Issues)) | @felder ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Afelder+updated%3A2024-07-01..2025-08-03&type=Issues)) | @fonsp ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Afonsp+updated%3A2024-07-01..2025-08-03&type=Issues)) | @GeorgianaElena ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3AGeorgianaElena+updated%3A2024-07-01..2025-08-03&type=Issues)) | @Hind-M ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3AHind-M+updated%3A2024-07-01..2025-08-03&type=Issues)) | @hiroyuki-sato ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Ahiroyuki-sato+updated%3A2024-07-01..2025-08-03&type=Issues)) | @jjerphan ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Ajjerphan+updated%3A2024-07-01..2025-08-03&type=Issues)) | @JohanMabille ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3AJohanMabille+updated%3A2024-07-01..2025-08-03&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Amanics+updated%3A2024-07-01..2025-08-03&type=Issues)) | @mfisher87 ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Amfisher87+updated%3A2024-07-01..2025-08-03&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Aminrk+updated%3A2024-07-01..2025-08-03&type=Issues)) | @nadiaguiffant ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Anadiaguiffant+updated%3A2024-07-01..2025-08-03&type=Issues)) | @pdurbin ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Apdurbin+updated%3A2024-07-01..2025-08-03&type=Issues)) | @rgaiacs ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Argaiacs+updated%3A2024-07-01..2025-08-03&type=Issues)) | @ryanlovett ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Aryanlovett+updated%3A2024-07-01..2025-08-03&type=Issues)) | @SylvainCorlay ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3ASylvainCorlay+updated%3A2024-07-01..2025-08-03&type=Issues)) | @weiji14 ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Aweiji14+updated%3A2024-07-01..2025-08-03&type=Issues)) | @yuvipanda ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Frepo2docker+involves%3Ayuvipanda+updated%3A2024-07-01..2025-08-03&type=Issues))
## 2024.07.0 ## 2024.07.0
([full changelog](https://github.com/jupyterhub/repo2docker/compare/2024.03.0...2024.07.0)) ([full changelog](https://github.com/jupyterhub/repo2docker/compare/2024.03.0...2024.07.0))

Wyświetl plik

@ -733,7 +733,10 @@ class Repo2Docker(Application):
try: try:
self.fetch(self.repo, self.ref, checkout_path) self.fetch(self.repo, self.ref, checkout_path)
if self.find_image(): if self.find_image() and not self.push:
# If push is requested we don't have a general way to query the registry.
# ContainerEngine.build() also handles pushing, so always "build" and
# rely on the implementation to decide whether to rebuild.
self.log.info( self.log.info(
f"Reusing existing image ({self.output_image_spec}), not building." f"Reusing existing image ({self.output_image_spec}), not building."
) )

Wyświetl plik

@ -1,3 +1,4 @@
import datetime
import hashlib import hashlib
import io import io
import logging import logging
@ -750,3 +751,50 @@ class BaseImage(BuildPack):
# the only path evaluated at container start time rather than build time # the only path evaluated at container start time rather than build time
return os.path.join("${REPO_DIR}", start) return os.path.join("${REPO_DIR}", start)
return None return None
@property
def runtime(self):
"""
Return parsed contents of runtime.txt
Returns (runtime, version, date), tuple components may be None.
Returns (None, None, None) if runtime.txt not found.
Supported formats:
name-version
name-version-yyyy-mm-dd
name-yyyy-mm-dd
"""
if hasattr(self, "_runtime"):
return self._runtime
self._runtime = (None, None, None)
runtime_path = self.binder_path("runtime.txt")
try:
with open(runtime_path) as f:
runtime_txt = f.read().strip()
except FileNotFoundError:
return self._runtime
name = None
version = None
date = None
parts = runtime_txt.split("-")
if len(parts) not in (2, 4, 5) or any(not (p) for p in parts):
raise ValueError(f"Invalid runtime.txt: {runtime_txt}")
name = parts[0]
if len(parts) in (2, 5):
version = parts[1]
if len(parts) in (4, 5):
date = "-".join(parts[-3:])
if not re.match(r"\d\d\d\d-\d\d-\d\d", date):
raise ValueError(f"Invalid runtime.txt date: {date}")
date = datetime.datetime.fromisoformat(date).date()
self._runtime = (name, version, date)
return self._runtime

Wyświetl plik

@ -187,12 +187,9 @@ class PipfileBuildPack(CondaBuildPack):
def detect(self): def detect(self):
"""Check if current repo should be built with the Pipfile buildpack.""" """Check if current repo should be built with the Pipfile buildpack."""
# first make sure python is not explicitly unwanted # first make sure python is not explicitly unwanted
runtime_txt = self.binder_path("runtime.txt") name = self.runtime[0]
if os.path.exists(runtime_txt): if name and name != "python":
with open(runtime_txt) as f: return False
runtime = f.read().strip()
if not runtime.startswith("python-"):
return False
pipfile = self.binder_path("Pipfile") pipfile = self.binder_path("Pipfile")
pipfile_lock = self.binder_path("Pipfile.lock") pipfile_lock = self.binder_path("Pipfile.lock")

Wyświetl plik

@ -15,14 +15,10 @@ class PythonBuildPack(CondaBuildPack):
if hasattr(self, "_python_version"): if hasattr(self, "_python_version"):
return self._python_version return self._python_version
try: name, version, _ = self.runtime
with open(self.binder_path("runtime.txt")) as f:
runtime = f.read().strip()
except FileNotFoundError:
runtime = ""
if not runtime.startswith("python-"): if name != "python" or not version:
# not a Python runtime (e.g. R, which subclasses this) # Either not specified, or not a Python runtime (e.g. R, which subclasses this)
# use the default Python # use the default Python
self._python_version = self.major_pythons["3"] self._python_version = self.major_pythons["3"]
self.log.warning( self.log.warning(
@ -30,7 +26,7 @@ class PythonBuildPack(CondaBuildPack):
) )
return self._python_version return self._python_version
py_version_info = runtime.split("-", 1)[1].split(".") py_version_info = version.split(".")
py_version = "" py_version = ""
if len(py_version_info) == 1: if len(py_version_info) == 1:
py_version = self.major_pythons[py_version_info[0]] py_version = self.major_pythons[py_version_info[0]]
@ -138,16 +134,11 @@ class PythonBuildPack(CondaBuildPack):
def detect(self): def detect(self):
"""Check if current repo should be built with the Python buildpack.""" """Check if current repo should be built with the Python buildpack."""
requirements_txt = self.binder_path("requirements.txt") requirements_txt = self.binder_path("requirements.txt")
runtime_txt = self.binder_path("runtime.txt")
setup_py = "setup.py" setup_py = "setup.py"
if os.path.exists(runtime_txt): name = self.runtime[0]
with open(runtime_txt) as f: if name:
runtime = f.read().strip() return name == "python"
if runtime.startswith("python-"):
return True
else:
return False
if not self.binder_dir and os.path.exists(setup_py): if not self.binder_dir and os.path.exists(setup_py):
return True return True
return os.path.exists(requirements_txt) return os.path.exists(requirements_txt)

Wyświetl plik

@ -46,21 +46,6 @@ class RBuildPack(PythonBuildPack):
R is installed from https://docs.rstudio.com/resources/install-r/ R is installed from https://docs.rstudio.com/resources/install-r/
""" """
@property
def runtime(self):
"""
Return contents of runtime.txt if it exists, '' otherwise
"""
if not hasattr(self, "_runtime"):
runtime_path = self.binder_path("runtime.txt")
try:
with open(runtime_path) as f:
self._runtime = f.read().strip()
except FileNotFoundError:
self._runtime = ""
return self._runtime
@property @property
def r_version(self): def r_version(self):
"""Detect the R version for a given `runtime.txt` """Detect the R version for a given `runtime.txt`
@ -70,6 +55,7 @@ class RBuildPack(PythonBuildPack):
""" """
# Available versions at https://cran.r-project.org/src/base/ # Available versions at https://cran.r-project.org/src/base/
version_map = { version_map = {
"4.5": "4.5.1",
"4.4": "4.4.2", "4.4": "4.4.2",
"4.3": "4.3.3", "4.3": "4.3.3",
"4.2": "4.2.3", "4.2": "4.2.3",
@ -91,11 +77,11 @@ class RBuildPack(PythonBuildPack):
r_version = version_map["4.4"] r_version = version_map["4.4"]
if not hasattr(self, "_r_version"): if not hasattr(self, "_r_version"):
parts = self.runtime.split("-") _, version, date = self.runtime
# If runtime.txt is not set, or if it isn't of the form r-<version>-<yyyy>-<mm>-<dd>, # If runtime.txt is not set, or if it isn't of the form r-<version>-<yyyy>-<mm>-<dd>,
# we don't use any of it in determining r version and just use the default # we don't use any of it in determining r version and just use the default
if len(parts) == 5: if version and date:
r_version = parts[1] r_version = version
# For versions of form x.y, we want to explicitly provide x.y.z - latest patchlevel # For versions of form x.y, we want to explicitly provide x.y.z - latest patchlevel
# available. Users can however explicitly specify the full version to get something specific # available. Users can however explicitly specify the full version to get something specific
if r_version in version_map: if r_version in version_map:
@ -131,15 +117,11 @@ class RBuildPack(PythonBuildPack):
Returns '' if no date is specified Returns '' if no date is specified
""" """
if not hasattr(self, "_checkpoint_date"): if not hasattr(self, "_checkpoint_date"):
match = re.match(r"r-(\d.\d(.\d)?-)?(\d\d\d\d)-(\d\d)-(\d\d)", self.runtime) name, version, date = self.runtime
if not match: if name == "r" and date:
self._checkpoint_date = False self._checkpoint_date = date
else: else:
# turn the last three groups of the match into a date self._checkpoint_date = False
self._checkpoint_date = datetime.date(
*[int(s) for s in match.groups()[-3:]]
)
return self._checkpoint_date return self._checkpoint_date
def detect(self): def detect(self):
@ -157,13 +139,9 @@ class RBuildPack(PythonBuildPack):
description_R = "DESCRIPTION" description_R = "DESCRIPTION"
if not self.binder_dir and os.path.exists(description_R): if not self.binder_dir and os.path.exists(description_R):
if not self.checkpoint_date: # no R snapshot date set through runtime.txt
# no R snapshot date set through runtime.txt # Set it to two days ago from today
# Set it to two days ago from today self._checkpoint_date = datetime.date.today() - datetime.timedelta(days=2)
self._checkpoint_date = datetime.date.today() - datetime.timedelta(
days=2
)
self._runtime = f"r-{str(self._checkpoint_date)}"
return True return True
@lru_cache @lru_cache

Wyświetl plik

@ -107,6 +107,13 @@ class DockerEngine(ContainerEngine):
): ):
if not shutil.which("docker"): if not shutil.which("docker"):
raise RuntimeError("The docker commandline client must be installed") raise RuntimeError("The docker commandline client must be installed")
# docker buildx is based in a plugin that might not be installed
# https://github.com/docker/buildx
docker_buildx_version = subprocess.run(["docker", "buildx", "version"])
if docker_buildx_version.returncode:
raise RuntimeError("The docker buildx plugin must be installed")
args = ["docker", "buildx", "build", "--progress", "plain"] args = ["docker", "buildx", "build", "--progress", "plain"]
if load: if load:
if push: if push:

Wyświetl plik

@ -1 +0,0 @@
r-4.4-2025-01-01

Wyświetl plik

@ -0,0 +1 @@
r-4.5.1-2025-06-13

Wyświetl plik

@ -1,9 +1,9 @@
#!/usr/bin/env Rscript #!/usr/bin/env Rscript
library('digest') library('digest')
# Fail if version is not 4.0 # Fail if version is not 4.5
print(version) print(version)
if (!(version$major == "4" && as.double(version$minor) >= 4 && as.double(version$minor) < 5)) { if (!(version$major == "4" && as.double(version$minor) >= 5 && as.double(version$minor) < 6)) {
quit("yes", 1) quit("yes", 1)
} }

Wyświetl plik

@ -1,9 +1,14 @@
from datetime import date
from os.path import join as pjoin from os.path import join as pjoin
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
import pytest import pytest
from repo2docker.buildpacks import LegacyBinderDockerBuildPack, PythonBuildPack from repo2docker.buildpacks import (
BaseImage,
LegacyBinderDockerBuildPack,
PythonBuildPack,
)
from repo2docker.utils import chdir from repo2docker.utils import chdir
@ -46,3 +51,45 @@ def test_unsupported_python(tmpdir, python_version, base_image):
assert bp.python_version == python_version assert bp.python_version == python_version
with pytest.raises(ValueError): with pytest.raises(ValueError):
bp.render() bp.render()
@pytest.mark.parametrize(
"runtime_txt, expected",
[
(None, (None, None, None)),
("abc-001", ("abc", "001", None)),
("abc-001-2025-06-22", ("abc", "001", date(2025, 6, 22))),
("abc-2025-06-22", ("abc", None, date(2025, 6, 22))),
("a_b/c-0.0.1-2025-06-22", ("a_b/c", "0.0.1", date(2025, 6, 22))),
],
)
def test_runtime(tmpdir, runtime_txt, expected, base_image):
tmpdir.chdir()
if runtime_txt is not None:
with open("runtime.txt", "w") as f:
f.write(runtime_txt)
base = BaseImage(base_image)
assert base.runtime == expected
@pytest.mark.parametrize(
"runtime_txt",
[
"",
"abc",
"abc-001-25-06-22",
],
)
def test_invalid_runtime(tmpdir, runtime_txt, base_image):
tmpdir.chdir()
if runtime_txt is not None:
with open("runtime.txt", "w") as f:
f.write(runtime_txt)
base = BaseImage(base_image)
with pytest.raises(ValueError, match=r"^Invalid runtime.txt.*"):
base.runtime