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
8 changes: 4 additions & 4 deletions .github/workflows/pytest.yml
Copy link
Member

@MatthiasZepper MatthiasZepper Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent catch! It totally escaped me, that we are running Singularity tests in that action as well.

In the pipeline template, we have upgraded the download test nf_core/pipeline-template/.github/workflows/download_pipeline.yml to Apptainer 1.34 instead of Singularity 3.8.3, which is about 3 years more recent. I think, this would be a good opportunity to piggy-back this change to the #tools test as well.

@mirpedrol @mashehu, @JulianFlesch any opinions against which Apptainer version we should test the pipelines and thus also tools?

Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ jobs:
python -m pip install --upgrade pip -r requirements-dev.txt
pip install -e .

- name: Set up Singularity
if: ${{ matrix.test == 'test_download.py'}}
uses: eWaterCycle/setup-singularity@931d4e31109e875b13309ae1d07c70ca8fbc8537 # v7
- name: Set up Apptainer
if: ${{ startsWith(matrix.test, 'pipelines/download/') }}
uses: eWaterCycle/setup-apptainer@4bb22c52d4f63406c49e94c804632975787312b3 # v2.0.0
with:
singularity-version: 3.8.3
apptainer-version: 1.3.4

- name: Get current date
id: date
Expand Down
8 changes: 8 additions & 0 deletions nf_core/pipelines/download/singularity.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ def pull_image(self, container: str, output_path: Path, library: str) -> bool:
progress_type="singularity_pull",
current_log="",
) as task:
self._ensure_output_dir_exists()
with intermediate_file_no_creation(output_path) as output_path_tmp:
singularity_command = self.construct_pull_command(output_path_tmp, address)
log.debug(f"Building singularity image: {address}")
Expand Down Expand Up @@ -629,6 +630,12 @@ def pull_image(self, container: str, output_path: Path, library: str) -> bool:
self.symlink_registries(output_path)
return True

def _ensure_output_dir_exists(self) -> None:
"""Ensure that the container output directory exists."""
if not self.get_container_output_dir().is_dir():
log.debug(f"Container output directory not found, creating: {self.get_container_output_dir()}")
self.get_container_output_dir().mkdir(parents=True, exist_ok=True)


# Distinct errors for the Singularity container download, required for acting on the exceptions
class SingularityError(Exception):
Expand Down Expand Up @@ -671,6 +678,7 @@ def __init__(
r"manifest\sunknown": self.InvalidTagError,
# The container image is no native Singularity Image Format.
r"ORAS\sSIF\simage\sshould\shave\sa\ssingle\slayer": self.NoSingularityContainerError,
r"received\smediaType:\sapplication/vnd\.docker\.distribution\.manifest": self.NoSingularityContainerError,
}
# Loop through the error messages and patterns. Since we want to have the option of
# no matches at all, we use itertools.product to allow for the use of the for ... else construct.
Expand Down
1 change: 1 addition & 0 deletions tests/pipelines/download/test_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ def test_fetch_containers_docker(self, tmp_path, mock_fetch_wf_config):
docker_fetcher.fetch_containers(
download_obj.containers,
download_obj.containers_remote,
workflow_directory=Path("pipeline-dummy"),
)

#
Expand Down
1 change: 1 addition & 0 deletions tests/pipelines/download/test_singularity.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ def test_singularity_pull_image_successfully(self, tmp_dir, mock_cachedir_prompt
container_cache_utilisation="none",
container_cache_index=None,
)
singularity_fetcher.registry_set = set()
singularity_fetcher.check_and_set_implementation()
singularity_fetcher.progress = mock_progress()
singularity_fetcher.pull_image("hello-world", tmp_dir / "yet-another-hello-world.sif", "docker.io")
Expand Down