### Plugin Installation Output Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-install-task.md This is an example of the console output when a plugin is successfully installed. ```text Plugin installed successfully! Installation location: Installation location determined by - ``` ```text Plugin nf-amazon installed successfully! Installation location: /home/user/.nextflow/plugins Installation location determined by - Default location (~/.nextflow/plugins) ``` -------------------------------- ### Loading an Installed Plugin in Nextflow Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-install-task.md Demonstrates how an installed plugin becomes available for use in a Nextflow workflow. After installation, Nextflow scans the plugins directory. ```bash # The installed plugin can now be loaded nextflow run my-workflow.nf ``` -------------------------------- ### Install to Local Maven Repository Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/CLAUDE.md Install the plugin to the local Maven repository for local testing. ```bash ./gradlew publishToMavenLocal ``` -------------------------------- ### Registry URL Configuration Examples Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/configuration.md Examples demonstrating how to configure the registry URL. The URL must include '/api' and should point to the registry API endpoint. ```groovy registry { url = 'https://registry.nextflow.io/api' } ``` ```groovy registry { url = 'https://my-internal-registry.com/api' } ``` -------------------------------- ### PluginInstallTask Key Methods Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/types.md Abstract class for PluginInstallTask. Includes getNextflowPluginsDir() to determine the installation directory with precedence. ```groovy static List getNextflowPluginsDir() ``` -------------------------------- ### Getting the Nextflow Plugins Directory Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-install-task.md This example demonstrates how to call the static method getNextflowPluginsDir() to determine the installation path for Nextflow plugins. It retrieves both the directory path and the reason for its selection based on environment variables or default locations. ```groovy def (pluginsDir, reason) = PluginInstallTask.getNextflowPluginsDir() // pluginsDir = "/home/user/.nextflow/plugins" // reason = "Default location (~/.nextflow/plugins)" ``` -------------------------------- ### Install Plugin to Default Location Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-install-task.md Run this command to install the plugin to the default Nextflow plugins directory. ```bash ./gradlew installPlugin ``` -------------------------------- ### Execute installPlugin Task Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/gradle-tasks.md Installs the plugin locally using the `installPlugin` Gradle task. The installation location can be influenced by environment variables. ```bash NXF_PLUGINS_DIR=/custom/path ./gradlew installPlugin ``` ```bash NXF_HOME=/opt/nextflow ./gradlew installPlugin # Installs to /opt/nextflow/plugins/ ``` ```bash # Default (if neither set) ~/.nextflow/plugins/ ``` -------------------------------- ### Install Plugin to Custom Location via NXF_PLUGINS_DIR Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-install-task.md Use the NXF_PLUGINS_DIR environment variable to specify a custom installation directory for the plugin. ```bash # Install to a specific directory NXF_PLUGINS_DIR=/opt/nextflow/plugins ./gradlew installPlugin # Or set in shell export NXF_PLUGINS_DIR=/opt/nextflow/plugins ./gradlew installPlugin ``` -------------------------------- ### Draft Release Request Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-client.md Example of a POST request to draft a plugin release, including required headers and JSON payload. ```http POST /api/v1/plugins/release HTTP/1.1 Host: registry.nextflow.io Authorization: Bearer Content-Type: application/json Content-Length: { "id": "my-plugin", "version": "1.0.0", "checksum": "sha512:...", "spec": "...", "provider": "My Organization", "description": "..." } ``` -------------------------------- ### Duplicate Plugin Handling Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md Shows the informational message when a plugin version already exists in the registry and is skipped. ```text â„šī¸ Plugin 'my-plugin' version 1.0.0 already exists in registry [https://registry.nextflow.io/api] - skipping upload ``` -------------------------------- ### Common Gradle Task Combinations Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/gradle-tasks.md Provides examples of common Gradle command sequences for typical build operations. ```bash # Clean rebuild ./gradlew clean build # Build and test ./gradlew build # Build and install locally ./gradlew installPlugin # Build and publish to registry ./gradlew releasePluginToRegistry # Safe re-run (handles duplicates) ./gradlew releasePluginIfNotExists # Full CI/CD pipeline ./gradlew clean build releasePluginIfNotExists ``` -------------------------------- ### Install Plugin to Custom Location via NXF_HOME Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-install-task.md If Nextflow is installed in a custom location, you can use NXF_HOME to direct the plugin installation. ```bash # If Nextflow is installed in a custom location export NXF_HOME=/opt/nextflow ./gradlew installPlugin # Installs to /opt/nextflow/plugins/-/ ``` -------------------------------- ### Artifact Upload Response Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-client.md Example JSON response indicating a successful artifact upload. ```json { "success": true } ``` -------------------------------- ### Basic Idempotent Release Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md Demonstrates the basic usage of the `releasePluginToRegistryIfNotExists` task. Shows successful output for the first run and a skipping message for the second run with the same version. ```bash # First run ./gradlew releasePluginToRegistryIfNotExists # Output: 🎉 SUCCESS! Plugin '...' has been successfully released... # Second run (same version) ./gradlew releasePluginToRegistryIfNotExists # Output: â„šī¸ Plugin '...' already exists in registry - skipping upload # Both succeed! ``` -------------------------------- ### CI/CD Pipeline Example for GitHub Actions Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/README.md An example of a GitHub Actions workflow to build, test, and release the Nextflow plugin. It demonstrates setting environment variables for API URL and key. ```yaml # GitHub Actions example - name: Build and test run: ./gradlew build - name: Release plugin run: ./gradlew releasePluginIfNotExists env: NPR_API_URL: ${{ secrets.NPR_API_URL }} NPR_API_KEY: ${{ secrets.NPR_API_KEY }} ``` -------------------------------- ### CI/CD Pipeline Integration Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md Shows how to integrate the `releasePluginToRegistryIfNotExists` task into a GitHub Actions workflow. It includes setting necessary environment variables for registry authentication. ```yaml # GitHub Actions example - name: Release plugin run: ./gradlew releasePluginToRegistryIfNotExists env: NPR_API_URL: ${{ secrets.NPR_API_URL }} NPR_API_KEY: ${{ secrets.NPR_API_KEY }} ``` -------------------------------- ### Draft Release Response Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-client.md Example JSON response received after successfully drafting a release, containing the release ID. ```json { "releaseId": 12345 } ``` -------------------------------- ### Artifact Upload Request Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-client.md Example of a POST request to upload a plugin artifact using multipart/form-data, referencing the release ID. ```http POST /api/v1/plugins/release/12345/upload HTTP/1.1 Host: registry.nextflow.io Authorization: Bearer Content-Type: multipart/form-data; boundary=----Boundary... Content-Length: ------Boundary... Content-Disposition: form-data; name="payload"; filename="plugin.zip" Content-Type: application/zip ------Boundary...-- ``` -------------------------------- ### Debug Logging Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md Illustrates the debug log output when the `--debug` flag is used, indicating that a plugin already exists and the release is being skipped. ```text Reading description from README.md Releasing plugin my-plugin@1.0.0 using two-step upload (if not exists) ... Plugin my-plugin@1.0.0 already exists, skipping ``` -------------------------------- ### Missing README Error Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md Displays the error message when the required README.md file is not found in the project root. ```text README.md file not found in the project root directory. ``` -------------------------------- ### Network/Server Error Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md Illustrates a typical error message when a connection to the plugin registry fails. ```text Unable to connect to plugin repository at https://registry.nextflow.io/api: Connection refused ``` -------------------------------- ### Run packagePlugin Task from Command Line Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-package-task.md Executes the `packagePlugin` task to create a distributable zip file for local installation or publishing. ```bash ./gradlew packagePlugin ``` -------------------------------- ### Example Spec JSON Output Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/generate-spec-task.md An example of the 'spec.json' file structure for a plugin with extension points, including version and extension point definitions. ```json { "version": "1.0.0", "extensionPoints": [ { "name": "com.example.MyObserver", "type": "observer" }, { "name": "com.example.MyFunctions", "type": "function_library" } ] } ``` -------------------------------- ### Registering the installPlugin Task Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-install-task.md This snippet shows how to register the 'installPlugin' task, which is an instance of PluginInstallTask. It also sets a dependency on the 'assemble' task, ensuring the plugin is built before installation. ```groovy project.tasks.register('installPlugin', PluginInstallTask) project.tasks.installPlugin.dependsOn << project.tasks.assemble ``` -------------------------------- ### Gradle Task Failure Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/errors.md Illustrates the standard format for a Gradle task failure, including the exception type and error details. ```text > Task :releasePluginToRegistry FAILED FAILURE: Build failed with an exception. * What went wrong: Registry release failed RegistryReleaseException: Failed to release plugin to registry https://registry.nextflow.io/api: HTTP 409 ... ``` -------------------------------- ### Registry API Key Configuration Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/configuration.md Examples for configuring the registry API key. It is strongly recommended to use environment variables or gradle.properties for security, rather than hardcoding the key. ```groovy // Explicit (NOT RECOMMENDED - security risk) registry { apiKey = 'ghp_abc123...' } ``` ```groovy // From environment variable (RECOMMENDED) registry { apiKey = System.getenv('NPR_API_KEY') } ``` ```groovy // From gradle.properties (in ~/.gradle/ for security) // registry { } - uses pr.apiKey property ``` -------------------------------- ### Example Nextflow Plugin Gradle Configuration Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/nextflow-plugin.md Demonstrates how to apply the Nextflow plugin in a Gradle build script and configure its properties such as Nextflow version, provider, and extension points. ```groovy // build.gradle plugins { id 'io.nextflow.nextflow-plugin' version '1.0.0-beta.15' } nextflowPlugin { nextflowVersion = '25.10.0' provider = 'Example Inc' className = 'com.example.ExamplePlugin' description = 'My example plugin' extensionPoints = [ 'com.example.ExampleFunctions' ] } version = '0.0.1' ``` -------------------------------- ### Local Development Build and Test Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/README.md Commands to build and test the plugin locally. After building, the plugin can be installed locally for testing with Nextflow. ```bash # Build and test ./gradlew build # Install locally for testing with Nextflow ./gradlew installPlugin # Test in Nextflow nextflow run my-workflow.nf ``` -------------------------------- ### Example Runtime Error Message for Missing Plugin Class Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-package-task.md Illustrates the format of the error message thrown when the specified plugin class cannot be found in the source directories. ```text -------------------------------------------------------------------------------- Plugin class 'com.example.MyPlugin' not found in source directories: - /path/to/src/main/groovy - /path/to/src/main/java -------------------------------------------------------------------------------- ``` -------------------------------- ### Authentication Error Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-task.md This error occurs when the provided API key is invalid or missing. Verify your API key configuration for authentication. ```text Failed to release plugin to registry ...: HTTP 401 Error: UNAUTHORIZED Invalid API key ``` -------------------------------- ### RegistryReleaseConfig Usage Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/types.md Example of configuring registry release settings within the nextflowPlugin block in build.gradle. Use this to specify the registry URL and API key. ```groovy nextflowPlugin { registry { url = 'https://registry.nextflow.io/api' apiKey = 'secret-key' } } ``` -------------------------------- ### NextflowPluginConfig Usage Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/types.md Example of setting NextflowPluginConfig properties within a build.gradle file using the DSL block. This is where you configure core plugin settings. ```groovy nextflowPlugin { nextflowVersion = '25.10.0' provider = 'My Org' className = 'com.example.MyPlugin' // ... other properties } ``` -------------------------------- ### Complete Nextflow Plugin Configuration in build.gradle Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/configuration.md A comprehensive example of configuring the Nextflow plugin in your `build.gradle` file, including required and optional settings. ```groovy // build.gradle plugins { id 'io.nextflow.nextflow-plugin' version '1.0.0-beta.15' } group = 'io.nextflow' version = '1.0.0' nextflowPlugin { // Required nextflowVersion = '25.10.0' provider = 'Seqera Labs' className = 'io.nextflow.MyPlugin' // Optional metadata description = 'My useful Nextflow plugin' // Extension points extensionPoints = [ 'io.nextflow.MyObserverFactory', 'io.nextflow.MyFunctionLibrary' ] // Plugin dependencies requirePlugins = ['nf-amazon'] // Dependency management useDefaultDependencies = true generateSpec = true // Registry publishing (optional) registry { url = 'https://registry.nextflow.io/api' apiKey = System.getenv('NPR_API_KEY') ?: 'default-dev-key' } } dependencies { // Your custom dependencies here (if any) } ``` -------------------------------- ### Run Gradle Tasks by Pattern Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/gradle-tasks.md Use patterns to execute groups of related Gradle tasks. For example, 'release' runs all tasks associated with releasing. ```bash ./gradlew assemble install ./gradlew release ``` -------------------------------- ### Configure Plugin Class Location Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/errors.md This example shows how to configure the 'className' for your Nextflow plugin and the expected file structure. Ensure the 'className' in your configuration matches the actual class location in your source directories. ```groovy // If className = 'com.example.MyPlugin' // Expected location: src/main/groovy/com/example/MyPlugin.groovy // or: src/main/java/com/example/MyPlugin.java nextflowPlugin { className = 'com.example.MyPlugin' // Match this... } // Create file structure: // src/main/groovy/com/example/MyPlugin.groovy ``` -------------------------------- ### Configure zipFile Property Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-task.md Sets the plugin zip file to be uploaded to the registry. This example shows how to manually set the zipFile property for the task. ```groovy task.zipFile = project.file('build/distributions/my-plugin-1.0.0.zip') ``` -------------------------------- ### Retry Script Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md Provides a bash script that retries the `releasePluginToRegistryIfNotExists` task up to 3 times. This script leverages the task's idempotency to safely handle transient failures. ```bash #!/bin/bash # Retry up to 3 times (no fear of duplicate failures) for i in {1..3}; do ./gradlew releasePluginToRegistryIfNotExists && break sleep 5 done ``` -------------------------------- ### Use valid semver for plugin version Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/errors.md The project version must be a valid semantic version (semver) string. Examples of valid versions are shown. ```groovy version = '1.0.0' // Valid version = '1.0.0-beta' // Valid version = '2.1.0-rc.1' // Valid ``` -------------------------------- ### Duplicate Plugin Error Example Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-task.md This error is returned when attempting to release a plugin version that already exists in the registry. Use `releasePluginToRegistryIfNotExists` for idempotent uploads. ```text Failed to release plugin to registry ...: HTTP 409 Error: DUPLICATE_PLUGIN Plugin 'my-plugin' version 1.0.0 already exists ``` -------------------------------- ### Full Build and Test Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/CLAUDE.md Execute a full build including all tests. ```bash ./gradlew build ``` -------------------------------- ### Clean and Build Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/CLAUDE.md Perform a clean build from scratch, removing previous build artifacts. ```bash ./gradlew clean build ``` -------------------------------- ### Create RegistryClient Instance Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-client.md Instantiate the RegistryClient with the registry's base URL and an authentication token. Ensure the URL includes the '/api' path and the token is not null or empty. ```groovy def uri = new URI('https://registry.nextflow.io/api') def token = 'my-secret-api-key' def client = new RegistryClient(uri, token) ``` -------------------------------- ### Demonstrate Gradle Up-to-Date Checking Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/gradle-tasks.md Illustrates how Gradle uses up-to-date checking to avoid re-running tasks when inputs and outputs have not changed. ```bash ./gradlew packagePlugin # Runs ./gradlew packagePlugin # UP-TO-DATE (no changes) # After modifying source: ./gradlew packagePlugin # Runs again ``` -------------------------------- ### Get Resolved Registry URL Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-config.md Retrieves the registry URL by checking instance properties, project properties, environment variables, and finally a default value. Use this to get the effective registry endpoint. ```groovy def config = new RegistryReleaseConfig(project) // Case 1: Explicit configuration registry { url = 'https://example.com/api' } config.getResolvedUrl() // Returns 'https://example.com/api' // Case 2: Project property // In gradle.properties: npr.apiUrl=https://example.com/api config.getResolvedUrl() // Returns 'https://example.com/api' // Case 3: Environment variable // export NPR_API_URL=https://example.com/api config.getResolvedUrl() // Returns 'https://example.com/api' // Case 4: Default config.getResolvedUrl() // Returns 'https://registry.nextflow.io/api' ``` -------------------------------- ### Create 'specFile' Configuration and SourceSet Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/adr/20251024-plugin-specification-generation-task.md Sets up a dedicated configuration and source set named 'specFile'. This ensures that the Nextflow core library and the plugin's JAR are correctly included in the classpath for specification generation. ```groovy configurations.create('specFile') sourceSets.create('specFile') { compileClasspath += configurations.specFile runtimeClasspath += configurations.specFile } ``` -------------------------------- ### Registry Configuration Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-task.md Details on how to configure the registry for the release task, including explicit configuration in `build.gradle` and fallback options. ```APIDOC ## Configuration The task uses registry configuration from two sources: ### 1. Explicit Registry Configuration (build.gradle) ```groovy nextflowPlugin { registry { url = 'https://registry.nextflow.io/api' apiKey = 'your-api-key' } } ``` ### 2. Fallback Configuration If no explicit registry configuration exists, the task creates a default `RegistryReleaseConfig` that uses precedence resolution: 1. Project properties (`npr.apiUrl`, `npr.apiKey`) 2. Environment variables (`NPR_API_URL`, `NPR_API_KEY`) 3. Default registry (`https://registry.nextflow.io/api`) See `RegistryReleaseConfig` documentation for details. ``` -------------------------------- ### Use valid semver for nextflowVersion Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/errors.md The `nextflowVersion` must adhere to the semantic versioning (semver) format. Examples of valid and invalid formats are provided. ```groovy nextflowPlugin { nextflowVersion = '25.10.0' // Valid nextflowVersion = '25.09.0-edge' // Valid (normalized) nextflowVersion = '24.04.0' // Valid (normalized to 24.4.0) } ``` -------------------------------- ### Validation Errors for Nextflow Plugin Configuration Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/configuration.md Examples of validation errors that may occur during project evaluation if required properties are missing or invalid. ```text nextflowPlugin.nextflowVersion not specified nextflowPlugin.className not specified nextflowPlugin.provider not specified nextflowPlugin.provider cannot be empty nextflowPlugin.nextflowVersion '25.10.0' is invalid. Must be a valid semantic version (semver) string nextflowPlugin.className 'MyPlugin' is invalid. Must be a valid Java fully qualified class name with package Plugin id 'my-plugin' is invalid. Plugin ids can contain numbers, letters, and the '-' symbol Plugin version '1.0.0' is invalid. Plugin versions must be a valid semantic version (semver) string ``` -------------------------------- ### run() - Execute Registry Release Task Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-task.md Executes the registry release task, uploading the plugin to the configured registry. It handles configuration resolution, client creation, and the release process. ```APIDOC ## run() ### Description Executes the registry release task, uploading the plugin to the configured registry. ### Signature ```groovy @TaskAction def run() ``` ### Process 1. Gets plugin version from project 2. Gets NextflowPluginConfig from project extensions 3. Determines registry configuration: - If `plugin.registry` is configured, uses it - Otherwise creates default RegistryReleaseConfig (uses fallback resolution) 4. Creates RegistryClient with resolved URL and auth token 5. Reads README.md content for plugin description 6. Calls `client.release()` to upload plugin 7. Prints success message to console ### Throws - `RegistryReleaseException` if upload fails - `MissingReadmeException` if README.md not found ### Success Output ``` 🎉 SUCCESS! Plugin 'my-plugin' version 1.0.0 has been successfully released to Nextflow Registry [https://registry.nextflow.io/api]! ``` ``` -------------------------------- ### Info Output for Existing Plugin Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md This is the expected output message when a plugin already exists in the registry and the upload is skipped. ```text â„šī¸ Plugin 'my-plugin' version 1.0.0 already exists in registry [https://registry.nextflow.io/api] - skipping upload ``` -------------------------------- ### Run All Tests Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/CLAUDE.md Execute all tests defined in the project. ```bash ./gradlew test ``` -------------------------------- ### Initialize Registry Configuration Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/nextflow-plugin-config.md Demonstrates how to initialize and configure the nested registry settings within the nextflowPlugin block. This is used for publishing plugins to a registry. ```groovy nextflowPlugin { registry { url = 'https://registry.nextflow.io/api' apiKey = 'my-key' } } ``` -------------------------------- ### Configure Plugin Description Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/nextflow-plugin-config.md Add a human-readable description for your plugin. This is optional but recommended for clarity. ```groovy nextflowPlugin { description = 'My example plugin' } ``` -------------------------------- ### Configure Registry via Environment Variables Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-config.md Configure the registry URL and API key using environment variables. These settings are applied when running Gradle tasks. ```bash export NPR_API_URL=https://registry.nextflow.io/api export NPR_API_KEY=ghp_abc123... ``` ```groovy // build.gradle nextflowPlugin { // Uses values from environment } ``` -------------------------------- ### Basic Usage of releasePluginToRegistry Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-task.md Executes the `releasePluginToRegistry` task using Gradle. ```bash ./gradlew releasePluginToRegistry ``` -------------------------------- ### Set valid plugin ID in settings.gradle Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/errors.md Plugin IDs must be between 5 and 64 characters, containing only alphanumeric characters and hyphens. This example shows how to set a valid plugin ID. ```groovy // settings.gradle rootProject.name = 'my-plugin' // Valid: 8 chars, alphanumeric + hyphen ``` -------------------------------- ### Mixed Configuration Precedence Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-config.md Demonstrates the precedence order for registry configuration: explicit `build.gradle` settings override project properties, which in turn override environment variables. This example shows how `config.getResolvedUrl()` and `config.getResolvedAuthToken()` reflect the effective configuration. ```groovy // build.gradle nextflowPlugin { registry { url = 'https://explicit.registry/api' // No apiKey here - will look to project property then env var } } ``` ```properties # gradle.properties npr.apiUrl=https://project.registry/api npr.apiKey=project_key_123 ``` ```bash export NPR_API_URL=https://env.registry/api export NPR_API_KEY=env_key_456 ``` ```groovy config.getResolvedUrl() // Returns 'https://explicit.registry/api' config.getResolvedAuthToken() // Returns 'project_key_123' ``` -------------------------------- ### Get Resolved Auth Token Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-config.md Retrieves the registry API token by checking instance properties, project properties, and environment variables. Throws a RuntimeException if no token is found in any of these locations. Use this to obtain credentials for registry authentication. ```groovy def config = new RegistryReleaseConfig(project) // Case 1: Explicit configuration registry { apiKey = 'my-secret-token' } config.getResolvedAuthToken() // Returns 'my-secret-token' // Case 2: Project property // In gradle.properties: npr.apiKey=mytoken config.getResolvedAuthToken() // Returns 'mytoken' // Case 3: Environment variable // export NPR_API_KEY=mytoken config.getResolvedAuthToken() // Returns 'mytoken' // Case 4: No configuration config.getResolvedAuthToken() // Throws RuntimeException ``` -------------------------------- ### Configure Nextflow Plugin in Gradle Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/nextflow-plugin-config.md Example of how to configure the Nextflow plugin in a Gradle build script. This includes setting required properties like nextflowVersion, provider, and className, along with optional properties for description, extension points, and plugin requirements. ```groovy // build.gradle plugins { id 'io.nextflow.nextflow-plugin' version '1.0.0-beta.15' } nextflowPlugin { // Required nextflowVersion = '25.10.0' provider = 'Seqera Labs' className = 'com.example.MyPlugin' // Optional description = 'A useful plugin for bioinformatics workflows' extensionPoints = [ 'com.example.MyObserver', 'com.example.MyFunctions' ] requirePlugins = ['nf-amazon'] useDefaultDependencies = true generateSpec = true // Publishing (optional) registry { url = 'https://registry.nextflow.io/api' apiKey = System.getenv('NPR_API_KEY') } } version = '1.0.0' ``` -------------------------------- ### Run Extension Points Task Explicitly Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/extension-points-task.md You can execute the `extensionPoints` Gradle task directly from the command line to generate the `extensions.idx` file. ```bash ./gradlew extensionPoints ``` -------------------------------- ### Configure Main Plugin Class Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/nextflow-plugin-config.md Provide the fully qualified name of the main plugin class. This class will be instantiated by Nextflow when the plugin is loaded. ```groovy nextflowPlugin { className = 'com.example.ExamplePlugin' } ``` -------------------------------- ### Read README Content Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-task.md Reads the plugin description from README.md in the project root. Throws `MissingReadmeException` if README.md is not found. ```groovy private String readReadmeContent() ``` -------------------------------- ### Apply and Configure Nextflow Plugin Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/README.md Apply the Nextflow plugin and configure essential metadata like version, provider, description, and extension points in your build.gradle file. ```gradle plugins { id 'io.nextflow.nextflow-plugin' version '1.0.0-beta.15' } dependencies { // (optional) put any library dependencies here } // plugin version version = '0.0.1' nextflowPlugin { // minimum nextflow version nextflowVersion = '25.10.0' provider = 'Example Inc' description = 'My example plugin' className = 'com.example.ExamplePlugin' extensionPoints = [ 'com.example.ExampleObserver', 'com.example.ExampleFunctions' ] } ``` -------------------------------- ### Construct Registry Client Base URL Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-client.md Instantiate the RegistryClient with a base URI that includes '/api'. The client automatically handles trailing slashes and constructs endpoints. ```groovy new RegistryClient(new URI('https://registry.nextflow.io/api'), token) ``` -------------------------------- ### Publish to Gradle Plugin Portal Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/CLAUDE.md Publish the plugin to the Gradle Plugin Portal. Requires API keys. ```bash ./gradlew publishPlugins ``` -------------------------------- ### Release Plugin to Registry Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-client.md Uploads a plugin to the registry using a two-step process: creating a draft release and then uploading the artifact. Requires plugin details, spec file, and archive. Fails if the plugin already exists. ```groovy def specFile = new File('build/resources/main/META-INF/spec.json') def zipFile = new File('build/distributions/my-plugin-1.0.0.zip') def description = new File('README.md').text client.release('my-plugin', '1.0.0', specFile, zipFile, 'My Organization', description) ``` -------------------------------- ### View Gradle Task Details Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/gradle-tasks.md Displays detailed information about a specific Gradle task. ```bash ./gradlew help --task releasePlugin ``` -------------------------------- ### Configure Empty Extension Points Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/extension-points-task.md If your plugin does not provide any extension points, you can configure `extensionPoints` as an empty list or omit the property entirely. This will result in no `extensions.idx` file being created. ```groovy nextflowPlugin { extensionPoints = [] // or omitted entirely } ``` -------------------------------- ### Release Plugin to Registry with RegistryClient Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/types.md The `RegistryClient` facilitates releasing plugin versions to a registry. It requires the registry URL, an authentication token, and details about the release including specification and archive files. Use `releaseIfNotExists` to avoid duplicate releases. ```groovy class RegistryClient { RegistryClient(URI url, String authToken) def release(String id, String version, File spec, File archive, String provider, String description = null) def releaseIfNotExists(String id, String version, File spec, File archive, String provider, String description = null) } ``` -------------------------------- ### Execute releasePluginToRegistry Task Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/gradle-tasks.md Initiates the release of the plugin to the Nextflow plugin registry using the `releasePluginToRegistry` Gradle task. Requires API key and README.md. ```bash ./gradlew releasePluginToRegistry ``` ```bash NPR_API_KEY=secret ./gradlew releasePluginToRegistry ``` -------------------------------- ### Handle HTTP Connection Errors Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/errors.md These messages indicate issues connecting to the plugin repository. 'Connection refused' suggests the server is offline, while 'Unknown Host' points to a DNS or network resolution problem. ```text Unable to connect to plugin repository at https://registry.nextflow.io/api: Connection refused ``` ```text Unable to connect to plugin repository at https://registry.nextflow.io/api: (Temporary failure in name resolution) ``` ```text Unable to connect to plugin repository at https://registry.nextflow.io/api: ``` -------------------------------- ### Set API Key via Environment Variable Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/README.md Configure the API key using an environment variable, recommended for CI/CD environments. ```bash export NPR_API_KEY=secret-key ``` -------------------------------- ### Release using Environment Variables Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-task.md Configures the Nextflow plugin registry URL and API key using environment variables before running the Gradle task. ```bash export NPR_API_URL=https://registry.nextflow.io/api export NPR_API_KEY=your-secret-key ./gradlew releasePluginToRegistry ``` -------------------------------- ### RegistryReleaseIfNotExistsTask Constructor Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-if-not-exists-task.md Initializes the task with default configurations for group, description, zipFile, and specFile properties. This constructor ensures the task is ready for use with standard Nextflow plugin release settings. ```groovy RegistryReleaseIfNotExistsTask() { group = 'Nextflow Plugin' description = 'Release the assembled plugin to the registry, skipping if already exists' def projectName = project.name def projectVersion = project.version zipFile = layout.buildDirectory.file("distributions/${projectName}-${projectVersion}.zip") specFile = layout.projectDirectory.file("build/resources/main/META-INF/spec.json") // Ensure specFile is optional specFile.finalizeValue() // Make it immutable } ``` -------------------------------- ### Run Multiple Gradle Tasks Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/gradle-tasks.md Execute several Gradle tasks sequentially by listing them after the gradlew command. ```bash ./gradlew assemble install test ``` -------------------------------- ### Configure Optional Nextflow Plugin Settings Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/README.md Includes optional settings for plugin description, extension points, dependencies, and registry publishing details. Use these to enhance plugin metadata and control its behavior. ```groovy nextflowPlugin { description = 'What the plugin does' extensionPoints = [ // Capabilities provided 'com.example.MyObserver', 'com.example.MyFunctions' ] requirePlugins = ['nf-amazon'] // Dependencies useDefaultDependencies = true // Add standard deps generateSpec = true // Create spec.json // Registry publishing registry { url = 'https://registry.nextflow.io/api' apiKey = System.getenv('NPR_API_KEY') } } ``` -------------------------------- ### Execute releasePluginToRegistryIfNotExists Task Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/gradle-tasks.md Runs the `releasePluginToRegistryIfNotExists` Gradle task to release a plugin to the registry, treating duplicate versions as non-failing. ```bash ./gradlew releasePluginToRegistryIfNotExists ``` -------------------------------- ### run() - ExtensionPointsTask Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/extension-points-task.md Executes the task to generate the extensions.idx file. It writes extension point class names to a file if configured, otherwise, no file is created. The output is a plain text file with one class name per line. ```APIDOC ## run() ### Description Executes the task to generate the extensions.idx file. It writes extension point class names to a file if configured, otherwise, no file is created. The output is a plain text file with one class name per line. ### Signature ```groovy @TaskAction def run() ``` ### Behavior 1. If `extensionPoints` is configured and non-empty: - Creates parent directory structure if needed - Writes each extension point class name on a separate line to the output file - Adds trailing newline 2. If `extensionPoints` is empty: - No file is created ### Output Format Plain text file with one fully qualified class name per line ### Example Output (`extensions.idx`) ``` com.example.ExampleObserver com.example.ExampleFunctions ``` ``` -------------------------------- ### Configure Registry via Project Properties Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-release-config.md Set the registry URL and API key in `gradle.properties` for a project-wide configuration. No explicit configuration is needed in `build.gradle` if these properties are set. ```properties # gradle.properties npr.apiUrl=https://registry.nextflow.io/api npr.apiKey=ghp_abc123... ``` ```groovy // build.gradle nextflowPlugin { // Uses values from gradle.properties } ``` -------------------------------- ### RegistryReleaseTask Key Methods Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/types.md Defines key methods for RegistryReleaseTask, including run() for execution and readReadmeContent() for reading README.md. ```groovy void run() String readReadmeContent() ``` -------------------------------- ### ExtensionPointsTask Configuration Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/extension-points-task.md Details on how to configure the ExtensionPointsTask, including its properties and constructor. ```APIDOC ## Task: extensionPoints ### Description A Gradle task that generates a `META-INF/extensions.idx` file. This file lists all extension point class names provided by the plugin, enabling Nextflow's plugin system to discover and load extension implementations. ### Properties - **extensionPoints** (`ListProperty`): A list of fully qualified class names for extension points. This is automatically populated from `NextflowPluginConfig.extensionPoints`. - **Example Configuration**: ```groovy nextflowPlugin { extensionPoints = [ 'com.example.ExampleObserver', 'com.example.ExampleFunctions' ] } ``` - **outputFile** (`RegularFileProperty`): Specifies the output file path for the `extensions.idx`. The default location is `build/resources/main/META-INF/extensions.idx`. ### Constructor - **ExtensionPointsTask()**: Initializes the task with default configurations for input and output properties, and sets up dependency tracking for incremental builds. ``` -------------------------------- ### Configure Nextflow Plugin Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/configuration.md Configure the Nextflow plugin using the `nextflowPlugin` extension. Set required properties like `nextflowVersion`, `provider`, and `className`. Optional properties and registry configuration are also shown. ```groovy nextflowPlugin { // Required configuration nextflowVersion = '25.10.0' provider = 'Example Inc' className = 'com.example.ExamplePlugin' // Optional configuration description = 'My example plugin' extensionPoints = ['com.example.ExampleFunctions'] requirePlugins = [] useDefaultDependencies = true generateSpec = true // Registry configuration (optional) registry { url = 'https://registry.nextflow.io/api' apiKey = 'your-api-key' } } ``` -------------------------------- ### Apply NextflowPlugin to Project Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/types.md The `NextflowPlugin` is the main entry point for applying Nextflow-specific configurations to a Gradle project. It implements the `Plugin` interface. ```groovy class NextflowPlugin implements Plugin { void apply(Project project) private void addDefaultDependencies(Project project, String nextflowVersion) } ``` -------------------------------- ### Registry Configuration: Environment Variables Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/README.md Configure the Nextflow plugin registry URL and API key using environment variables in your shell. ```bash export NPR_API_URL=https://registry.nextflow.io/api export NPR_API_KEY=your-api-key ``` -------------------------------- ### Create Draft Release - Groovy Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/registry-client.md Creates a draft release with metadata and returns a release ID. It validates the provider, computes the SHA-512 checksum of the archive, and sends a POST request to the registry API. ```groovy private Long createDraftRelease(String id, String version, File spec, File archive, String provider, String description) { // ... implementation details ... } ``` ```json { "id": "my-plugin", "version": "1.0.0", "checksum": "sha512:abc123...", "spec": "{ ... }", "provider": "My Organization", "description": "Plugin description..." } ``` -------------------------------- ### registry(Closure config) Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/nextflow-plugin-config.md Initializes the nested registry configuration block for registry settings. ```APIDOC ## registry(Closure config) ### Description Initializes the nested registry configuration block. ### Signature def registry(Closure config) ### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | config | Closure | Yes | Configuration closure for registry settings | ### Example ```groovy nextflowPlugin { registry { url = 'https://registry.nextflow.io/api' apiKey = 'my-key' } } ``` ``` -------------------------------- ### Create Spec File Configuration Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/types.md Define a Gradle configuration named 'specFile'. This configuration is used to manage dependencies and classpath for the spec file generation process. ```groovy project.configurations.create('specFile') ``` -------------------------------- ### Release Plugin to Registry Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/README.md Commands to release the plugin to the registry. `releasePluginIfNotExists` is idempotent and suitable for CI/CD. ```bash # Build and publish ./gradlew releasePlugin # Or for CI/CD (idempotent) ./gradlew releasePluginIfNotExists ``` -------------------------------- ### PluginPackageTask Constructor Source: https://github.com/nextflow-io/nextflow-plugin-gradle/blob/master/_autodocs/api-reference/plugin-package-task.md Initializes the PluginPackageTask with default settings for packaging Nextflow plugins, including setting the task group, description, and configuring reproducible build options. ```groovy PluginPackageTask() ```