diff --git a/CHANGELOG.md b/CHANGELOG.md index b305273654..ab0d37627a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ - Only match assignments of params in `main.nf` and not references like `params.aligner == ` ([#2833](https://github.com/nf-core/tools/pull/2833)) +### Download + +- Replace `--tower` with `--platform`. The former will remain for backwards compatability for now but will be removed in a future release. + ### Components ### General @@ -30,6 +34,7 @@ - Optimize layers in dockerfile ([#2842](https://github.com/nf-core/tools/pull/2842)) - Update gitpod/workspace-base Docker digest to 1e133e5 ([#2843](https://github.com/nf-core/tools/pull/2843)) - Update python:3.11-slim Docker digest to a2eb07f ([#2847](https://github.com/nf-core/tools/pull/2847)) +- Strip out mention of "Nextflow Tower" and replace with "Seqera Platform" wherever possible - Update pre-commit hook astral-sh/ruff-pre-commit to v0.3.3 ([#2850](https://github.com/nf-core/tools/pull/2850)) ## [v2.13.1 - Tin Puppy Patch](https://github.com/nf-core/tools/releases/tag/2.13) - [2024-02-29] diff --git a/README.md b/README.md index cf0b01d210..53e9f77c97 100644 --- a/README.md +++ b/README.md @@ -376,7 +376,7 @@ The pipeline files are automatically updated (`params.custom_config_base` is set So using `-profile ` should work if available within [nf-core/configs](https://github.com/nf-core/configs). > [!WARNING] -> This option is not available when downloading a pipeline for use with [Nextflow Tower](#adapting-downloads-to-nextflow-tower) because the application manages all configurations separately. +> This option is not available when downloading a pipeline for use with [Seqera Platform](#adapting-downloads-to-seqera-platform) because the application manages all configurations separately. ### Downloading Apptainer containers @@ -428,14 +428,14 @@ Note that compressing many GBs of binary files can be slow, so specifying `--com If the download speeds are much slower than your internet connection is capable of, you can set `--parallel-downloads` to a large number to download loads of images at once. -### Adapting downloads to Nextflow Tower +### Adapting downloads to Seqera Platform -[seqeralabs® Nextflow Tower](https://cloud.tower.nf/) provides a graphical user interface to oversee pipeline runs, gather statistics and configure compute resources. While pipelines added to _Tower_ are preferably hosted at a Git service, providing them as disconnected, self-reliant repositories is also possible for premises with restricted network access. Choosing the `--tower` flag will download the pipeline in an appropriate form. +[Seqera Platform](https://seqera.io/platform/) (formerly _"Nextflow Tower"_) provides a graphical user interface to oversee pipeline runs, gather statistics and configure compute resources. While pipelines added to _Seqera Platform_ are preferably hosted at a Git service, providing them as disconnected, self-reliant repositories is also possible for premises with restricted network access. Choosing the `--platform` flag will download the pipeline in an appropriate form. -Subsequently, the `*.git` folder can be moved to it's final destination and linked with a pipeline in _Tower_ using the `file:/` prefix. +Subsequently, the `*.git` folder can be moved to it's final destination and linked with a pipeline in _Seqera Platform_ using the `file:/` prefix. > [!TIP] -> Also without access to Tower, pipelines downloaded with the `--tower` flag can be run if the _absolute_ path is specified: `nextflow run -r 2.5 file:/path/to/pipelinedownload.git`. Downloads in this format allow you to include multiple revisions of a pipeline in a single file, but require that the revision (e.g. `-r 2.5`) is always explicitly specified. +> Also without access to Seqera Platform, pipelines downloaded with the `--platform` flag can be run if the _absolute_ path is specified: `nextflow run -r 2.5 file:/path/to/pipelinedownload.git`. Downloads in this format allow you to include multiple revisions of a pipeline in a single file, but require that the revision (e.g. `-r 2.5`) is always explicitly specified. ## Pipeline software licences diff --git a/nf_core/__main__.py b/nf_core/__main__.py index d6f6077be9..20cba43e4e 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -358,11 +358,19 @@ def create_params_file(pipeline, revision, output, force, show_hidden): help="Archive compression type", ) @click.option("-f", "--force", is_flag=True, default=False, help="Overwrite existing files") +# TODO: Remove this in a future release. Deprecated in March 2024. @click.option( - "-t", "--tower", is_flag=True, default=False, + hidden=True, + help="Download for Seqera Platform. DEPRECATED: Please use --platform instead.", +) +@click.option( + "-t", + "--platform", + is_flag=True, + default=False, help="Download for Seqera Platform (formerly Nextflow Tower)", ) @click.option( @@ -370,7 +378,7 @@ def create_params_file(pipeline, revision, output, force, show_hidden): "--download-configuration", is_flag=True, default=False, - help="Include configuration profiles in download. Not available with `--tower`", + help="Include configuration profiles in download. Not available with `--platform`", ) # -c changed to -s for consistency with other --container arguments, where it is always the first letter of the last word. # Also -c might be used instead of -d for config in a later release, but reusing params for different options in two subsequent releases might be too error-prone. @@ -412,6 +420,7 @@ def download( compress, force, tower, + platform, download_configuration, container_system, container_library, @@ -433,7 +442,7 @@ def download( outdir, compress, force, - tower, + tower or platform, # True if either specified download_configuration, container_system, container_library, diff --git a/nf_core/download.py b/nf_core/download.py index d08e0ba40e..9d4decc424 100644 --- a/nf_core/download.py +++ b/nf_core/download.py @@ -90,7 +90,7 @@ class DownloadWorkflow: pipeline (str): A nf-core pipeline name. revision (List[str]): The workflow revision to download, like `1.0`. Defaults to None. container (bool): Flag, if the Singularity container should be downloaded as well. Defaults to False. - tower (bool): Flag, to customize the download for Nextflow Tower (convert to git bare repo). Defaults to False. + platform (bool): Flag, to customize the download for Seqera Platform (convert to git bare repo). Defaults to False. outdir (str): Path to the local download directory. Defaults to None. """ @@ -101,7 +101,7 @@ def __init__( outdir=None, compress_type=None, force=False, - tower=False, + platform=False, download_configuration=None, container_system=None, container_library=None, @@ -120,11 +120,11 @@ def __init__( self.output_filename = None self.compress_type = compress_type self.force = force - self.tower = tower + self.platform = platform # if flag is not specified, do not assume deliberate choice and prompt config inclusion interactively. - # this implies that non-interactive "no" choice is only possible implicitly (e.g. with --tower or if prompt is suppressed by !stderr.is_interactive). + # this implies that non-interactive "no" choice is only possible implicitly (e.g. with --platform or if prompt is suppressed by !stderr.is_interactive). # only alternative would have been to make it a parameter with argument, e.g. -d="yes" or -d="no". - self.include_configs = True if download_configuration else False if bool(tower) else None + self.include_configs = True if download_configuration else False if bool(platform) else None # Specifying a cache index or container library implies that containers should be downloaded. self.container_system = "singularity" if container_cache_index or bool(container_library) else container_system # Manually specified container library (registry) @@ -165,8 +165,8 @@ def download_workflow(self): ) self.prompt_revision() self.get_revision_hash() - # Inclusion of configs is unnecessary for Tower. - if not self.tower and self.include_configs is None: + # Inclusion of configs is unnecessary for Seqera Platform. + if not self.platform and self.include_configs is None: self.prompt_config_inclusion() # If a remote cache is specified, it is safe to assume images should be downloaded. if not self.container_cache_utilisation == "remote": @@ -177,7 +177,7 @@ def download_workflow(self): self.prompt_singularity_cachedir_utilization() self.prompt_singularity_cachedir_remote() # Nothing meaningful to compress here. - if not self.tower: + if not self.platform: self.prompt_compression_type() except AssertionError as e: raise DownloadError(e) from e @@ -196,7 +196,7 @@ def download_workflow(self): ) # Set an output filename now that we have the outdir - if self.tower: + if self.platform: self.output_filename = f"{self.outdir}.git" summary_log.append(f"Output file: '{self.output_filename}'") elif self.compress_type is not None: @@ -205,11 +205,11 @@ def download_workflow(self): else: summary_log.append(f"Output directory: '{self.outdir}'") - if not self.tower: + if not self.platform: # Only show entry, if option was prompted. summary_log.append(f"Include default institutional configuration: '{self.include_configs}'") else: - summary_log.append(f"Enabled for seqeralabs® Nextflow Tower: '{self.tower}'") + summary_log.append(f"Enabled for Seqera Platform: '{self.platform}'") # Check that the outdir doesn't already exist if os.path.exists(self.outdir): @@ -233,8 +233,8 @@ def download_workflow(self): log.info("Saving '{}'\n {}".format(self.pipeline, "\n ".join(summary_log))) # Perform the actual download - if self.tower: - self.download_workflow_tower() + if self.platform: + self.download_workflow_platform() else: self.download_workflow_static() @@ -273,7 +273,7 @@ def download_workflow_static(self): log.info("Compressing output into archive") self.compress_download() - def download_workflow_tower(self, location=None): + def download_workflow_platform(self, location=None): """Create a bare-cloned git repository of the workflow, so it can be launched with `tw launch` as file:/ pipeline""" log.info("Collecting workflow from GitHub") @@ -289,7 +289,7 @@ def download_workflow_tower(self, location=None): # Remove tags for those revisions that had not been selected self.workflow_repo.tidy_tags_and_branches() - # create a bare clone of the modified repository needed for Tower + # create a bare clone of the modified repository needed for Seqera Platform self.workflow_repo.bare_clone(os.path.join(self.outdir, self.output_filename)) # extract the required containers @@ -306,9 +306,11 @@ def download_workflow_tower(self, location=None): except OSError as e: raise DownloadError(f"[red]{e}[/]") from e - # Justify why compression is skipped for Tower downloads (Prompt is not shown, but CLI argument could have been set) + # Justify why compression is skipped for Seqera Platform downloads (Prompt is not shown, but CLI argument could have been set) if self.compress_type is not None: - log.info("Compression choice is ignored for Tower downloads since nothing can be reasonably compressed.") + log.info( + "Compression choice is ignored for Seqera Platform downloads since nothing can be reasonably compressed." + ) def prompt_pipeline_name(self): """Prompt for the pipeline name if not set with a flag""" @@ -321,13 +323,13 @@ def prompt_revision(self): """ Prompt for pipeline revision / branch Prompt user for revision tag if '--revision' was not set - If --tower is specified, allow to select multiple revisions + If --platform is specified, allow to select multiple revisions Also the static download allows for multiple revisions, but we do not prompt this option interactively. """ if not bool(self.revision): (choice, tag_set) = nf_core.utils.prompt_pipeline_release_branch( - self.wf_revisions, self.wf_branches, multiple=self.tower + self.wf_revisions, self.wf_branches, multiple=self.platform ) """ The checkbox() prompt unfortunately does not support passing a Validator, @@ -384,7 +386,7 @@ def get_revision_hash(self): else: self.outdir = f"{self.pipeline.replace('/', '-').lower()}_{self.revision[0]}" - if not self.tower: + if not self.platform: for revision, wf_sha in self.wf_sha.items(): # Set the download URL and return - only applicable for classic downloads self.wf_download_url = { @@ -406,7 +408,7 @@ def prompt_config_inclusion(self): def prompt_container_download(self): """Prompt whether to download container images or not""" - if self.container_system is None and stderr.is_interactive and not self.tower: + if self.container_system is None and stderr.is_interactive and not self.platform: stderr.print("\nIn addition to the pipeline code, this tool can download software containers.") self.container_system = questionary.select( "Download software container images:", @@ -1621,7 +1623,7 @@ def setup_local_repo(self, remote, location=None, in_cache=True): def tidy_tags_and_branches(self): """ Function to delete all tags and branches that are not of interest to the downloader. - This allows a clutter-free experience in Tower. The untagged commits are evidently still available. + This allows a clutter-free experience in Seqera Platform. The untagged commits are evidently still available. However, due to local caching, the downloader might also want access to revisions that had been deleted before. In that case, don't bother with re-adding the tags and rather download anew from Github. @@ -1655,7 +1657,7 @@ def tidy_tags_and_branches(self): if self.repo.head.is_detached: self.repo.head.reset(index=True, working_tree=True) - # no branch exists, but one is required for Tower's UI to display revisions correctly). Thus, "latest" will be created. + # no branch exists, but one is required for Seqera Platform's UI to display revisions correctly). Thus, "latest" will be created. if not bool(self.repo.heads): if self.repo.is_valid_object("latest"): # "latest" exists as tag but not as branch diff --git a/nf_core/lint/actions_awsfulltest.py b/nf_core/lint/actions_awsfulltest.py index 66aa3f99bf..d5a061c935 100644 --- a/nf_core/lint/actions_awsfulltest.py +++ b/nf_core/lint/actions_awsfulltest.py @@ -17,7 +17,7 @@ def actions_awsfulltest(self): .. note:: You can manually trigger the AWS tests by going to the `Actions` tab on the pipeline GitHub repository and selecting the `nf-core AWS full size tests` workflow on the left. - .. tip:: For tests on full data prior to release, `Nextflow Tower `_ launch feature can be employed. + .. tip:: For tests on full data prior to release, `Seqera Platform `_ launch feature can be employed. The ``.github/workflows/awsfulltest.yml`` file is tested for the following: @@ -52,7 +52,7 @@ def actions_awsfulltest(self): # Warn if `-profile test` is still unchanged try: - steps = wf["jobs"]["run-tower"]["steps"] + steps = wf["jobs"]["run-platform"]["steps"] if not any(aws_profile in step["run"] for step in steps if "run" in step.keys()): raise AssertionError() except (AssertionError, KeyError, TypeError): diff --git a/nf_core/pipeline-template/.github/workflows/awsfulltest.yml b/nf_core/pipeline-template/.github/workflows/awsfulltest.yml index 4c9fd69fcc..56ecb60302 100644 --- a/nf_core/pipeline-template/.github/workflows/awsfulltest.yml +++ b/nf_core/pipeline-template/.github/workflows/awsfulltest.yml @@ -8,12 +8,12 @@ on: types: [published] workflow_dispatch: jobs: - run-tower: + run-platform: name: Run AWS full tests if: github.repository == '{{ name }}' runs-on: ubuntu-latest steps: - - name: Launch workflow via tower + - name: Launch workflow via Seqera Platform uses: seqeralabs/action-tower-launch@v2 # TODO nf-core: You can customise AWS full pipeline tests as required # Add full size test data (but still relatively small datasets for few samples) @@ -33,7 +33,7 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: Tower debug log file + name: Seqera Platform debug log file path: | - tower_action_*.log - tower_action_*.json + seqera_platform_action_*.log + seqera_platform_action_*.json diff --git a/nf_core/pipeline-template/.github/workflows/awstest.yml b/nf_core/pipeline-template/.github/workflows/awstest.yml index 25726aa1c9..e1c26a71c7 100644 --- a/nf_core/pipeline-template/.github/workflows/awstest.yml +++ b/nf_core/pipeline-template/.github/workflows/awstest.yml @@ -5,13 +5,13 @@ name: nf-core AWS test on: workflow_dispatch: jobs: - run-tower: + run-platform: name: Run AWS tests if: github.repository == '{{ name }}' runs-on: ubuntu-latest steps: - # Launch workflow using Tower CLI tool action {%- raw %} - - name: Launch workflow via tower + # Launch workflow using Seqera Platform CLI tool action {%- raw %} + - name: Launch workflow via Seqera Platform uses: seqeralabs/action-tower-launch@v2 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} @@ -27,7 +27,7 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: Tower debug log file + name: Seqera Platform debug log file path: | - tower_action_*.log - tower_action_*.json + seqera_platform_action_*.log + seqera_platform_action_*.json diff --git a/nf_core/pipeline-template/README.md b/nf_core/pipeline-template/README.md index a3b141cf38..88e0f1719f 100644 --- a/nf_core/pipeline-template/README.md +++ b/nf_core/pipeline-template/README.md @@ -20,7 +20,7 @@ [![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) [![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/) [![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) -[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://tower.nf/launch?pipeline=https://github.com/{{ name }}) +[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/{{ name }}) {% endif -%} {%- if branded -%}[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23{{ short_name }}-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/{{ short_name }}){% endif -%} diff --git a/nf_core/utils.py b/nf_core/utils.py index 9261388a39..84b653ffe2 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -877,7 +877,7 @@ def prompt_pipeline_release_branch(wf_releases, wf_branches, multiple=False): Args: wf_releases (array): Array of repo releases as returned by the GitHub API wf_branches (array): Array of repo branches, as returned by the GitHub API - multiple (bool): Allow selection of multiple releases & branches (for Tower) + multiple (bool): Allow selection of multiple releases & branches (for Seqera Platform) Returns: choice (str): Selected release / branch name diff --git a/tests/test_cli.py b/tests/test_cli.py index d1dff0fe7b..54e420f5e4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -166,7 +166,7 @@ def test_cli_download(self, mock_dl): "outdir": "/path/outdir", "compress": "tar.gz", "force": None, - "tower": None, + "platform": None, "download-configuration": None, "container-system": "singularity", "container-library": "quay.io", @@ -186,7 +186,7 @@ def test_cli_download(self, mock_dl): params["outdir"], params["compress"], "force" in params, - "tower" in params, + "platform" in params, "download-configuration" in params, params["container-system"], (params["container-library"],), diff --git a/tests/test_download.py b/tests/test_download.py index 621379842b..14a96be26f 100644 --- a/tests/test_download.py +++ b/tests/test_download.py @@ -563,16 +563,16 @@ def test_download_workflow_with_success(self, tmp_dir, mock_download_image, mock download_obj.download_workflow() # - # Test Download for Tower + # Test Download for Seqera Platform # @with_temporary_folder @mock.patch("nf_core.download.DownloadWorkflow.get_singularity_images") - def test_download_workflow_for_tower(self, tmp_dir, _): + def test_download_workflow_for_platform(self, tmp_dir, _): download_obj = DownloadWorkflow( pipeline="nf-core/rnaseq", revision=("3.7", "3.9"), compress_type="none", - tower=True, + platform=True, container_system="singularity", ) @@ -592,7 +592,7 @@ def test_download_workflow_for_tower(self, tmp_dir, _): download_obj.get_revision_hash() - # download_obj.wf_download_url is not set for tower downloads, but the sha values are + # download_obj.wf_download_url is not set for Seqera Platform downloads, but the sha values are assert isinstance(download_obj.wf_sha, dict) and len(download_obj.wf_sha) == 2 assert isinstance(download_obj.wf_download_url, dict) and len(download_obj.wf_download_url) == 0 @@ -600,7 +600,7 @@ def test_download_workflow_for_tower(self, tmp_dir, _): assert bool(re.search(r"nf-core-rnaseq_\d{4}-\d{2}-\d{1,2}_\d{1,2}-\d{1,2}", download_obj.outdir, re.S)) download_obj.output_filename = f"{download_obj.outdir}.git" - download_obj.download_workflow_tower(location=tmp_dir) + download_obj.download_workflow_platform(location=tmp_dir) assert download_obj.workflow_repo assert isinstance(download_obj.workflow_repo, WorkflowRepo) @@ -614,7 +614,7 @@ def test_download_workflow_for_tower(self, tmp_dir, _): # assert that the download has a "latest" branch. assert "latest" in all_heads - # download_obj.download_workflow_tower(location=tmp_dir) will run container image detection for all requested revisions + # download_obj.download_workflow_platform(location=tmp_dir) will run container image detection for all requested revisions assert isinstance(download_obj.containers, list) and len(download_obj.containers) == 33 assert ( "https://depot.galaxyproject.org/singularity/bbmap:38.93--he522d1c_0" in download_obj.containers