Skip to content

Comments

feat: add pipeline versioning support#582

Open
JaimeSeqLabs wants to merge 29 commits intomasterfrom
PLAT-3660-pipeline-versioning-support
Open

feat: add pipeline versioning support#582
JaimeSeqLabs wants to merge 29 commits intomasterfrom
PLAT-3660-pipeline-versioning-support

Conversation

@JaimeSeqLabs
Copy link
Contributor

@JaimeSeqLabs JaimeSeqLabs commented Feb 19, 2026

Summary

  • Adds pipelines versions subcommand group (list, view, update) to manage pipeline versions
  • Wires --version-id / --version-name into existing commands: pipelines view, pipelines export, pipelines update, and launch
  • pipelines add gains --version-name to name the initial version on creation
  • pipelines update detects when a versionable field change creates a new version: auto-generates a name (mirroring the frontend naming algorithm), assigns it, and promotes it to default. Use --allow-draft to skip auto-naming and keep the new version as an unnamed draft for manual management.
  • pipelines view displays version info (name, default flag, hash) when a version is specified
  • pipelines export includes the version name in the exported JSON so it survives import round-trips
  • Moves pipelines labels commands into a labels/ sub-package mirroring the versions/ structure

Test plan

  • ./gradlew test — all unit tests pass
  • TOWER_CLI=./build/native/nativeCompile/tw ./gradlew test — all unit tests pass in binary mode
  • Manual E2E testing against a Platform backend (see testing guidelines below)

Testing guidelines

Setup

export TOWER_ACCESS_TOKEN="<your-token>"
export TOWER_API_ENDPOINT="<your-platform-api-url>"

PIPELINE_NAME="AutoTest"
PIPELINE_URL="https://github.com/pditommaso/nf-sleep"

# Build the CLI native binary
./gradlew nativeCompile
TW="./build/native/nativeCompile/tw"
# when targeting localhost instance
# TW="./build/native/nativeCompile/tw --insecure"

Test 1: Create pipeline with initial version name

$TW pipelines add -n "$PIPELINE_NAME" --version-name "v1.0" "$PIPELINE_URL"

Verify: Pipeline is created successfully.

Test 2: List versions

$TW pipelines versions list -n "$PIPELINE_NAME"
$TW pipelines versions list -n "$PIPELINE_NAME" --filter "v1.0"
$TW pipelines versions list -n "$PIPELINE_NAME" --is-published
$TW pipelines versions list -n "$PIPELINE_NAME" --max 10 --offset 0

Verify: All list variants return v1.0 as the single published version.

Test 3: View version by name and by ID

$TW pipelines versions view -n "$PIPELINE_NAME" --version-name "v1.0"

VERSION_ID=$($TW -o json pipelines versions list -n "$PIPELINE_NAME" 2>/dev/null \
  | jq -r '.versions[0].id')

$TW pipelines versions view -n "$PIPELINE_NAME" --version-id "$VERSION_ID"

Verify: Both show version details (ID, name, hash, default flag, creator, timestamps).

Test 4: View pipeline with version targeting

$TW pipelines view -n "$PIPELINE_NAME" --version-name "v1.0"
$TW pipelines view -n "$PIPELINE_NAME" --version-id "$VERSION_ID"
$TW pipelines view -n "$PIPELINE_NAME"

Verify: The first two show Version Name, Version Is Default, and Version Hash rows. The third (no version) omits version info.

Test 5: Update non-versionable field (no new version)

$TW pipelines update -n "$PIPELINE_NAME" -d "Updated description"

Verify: Output says "Pipeline updated" without any new version message.

Test 6: Update versionable field (auto-names and promotes new version)

$TW pipelines update -n "$PIPELINE_NAME" --main-script "main.nf"

Verify: Output says "Pipeline updated" followed by "New version 'v1.0-1' created and set as default, available in the Launchpad." (name is derived from the current default version name).

Test 7: Confirm auto-named version appears in version list

$TW pipelines versions list -n "$PIPELINE_NAME"

Verify: Two published versions shown — v1.0 and v1.0-1 (or similar). The new one is marked as default.

Test 7b: Update versionable field with --allow-draft (keeps unnamed draft)

DRAFT_ID=$($TW -o json pipelines update -n "$PIPELINE_NAME" --main-script "main.nf" --allow-draft 2>/dev/null \
  | jq -r '.draftVersionId')
echo "Draft version ID: $DRAFT_ID"

Verify: DRAFT_ID is a non-null version ID. Output includes "New draft version created" message.

Test 8: Rename draft version

$TW pipelines versions update -n "$PIPELINE_NAME" --version-id "$DRAFT_ID" --new-name "v2.0"

Verify: Version updated successfully.

Test 9: Set version as default

$TW pipelines versions update -n "$PIPELINE_NAME" --version-name "v2.0" --set-default

Verify: Version updated successfully.

Test 10: Update a specific version by name

$TW pipelines update -n "$PIPELINE_NAME" --version-name "v1.0" -d "Non-versionable change to v1.0"

Verify: Pipeline updated without creating a new draft.

Test 11: Export with version targeting

$TW pipelines export -n "$PIPELINE_NAME" --version-name "v1.0"
$TW pipelines export -n "$PIPELINE_NAME" --version-id "$VERSION_ID"
$TW pipelines export -n "$PIPELINE_NAME"

Verify: The first two include "version": {"name": "v1.0"} in the JSON. The third (default version) omits the version field.

Test 12: Export + import round-trip

EXPORT_FILE=$(mktemp /tmp/pipeline-export-XXXXXX.json)
$TW pipelines export -n "$PIPELINE_NAME" --version-name "v1.0" "$EXPORT_FILE"
$TW pipelines import -n "${PIPELINE_NAME}_imported" "$EXPORT_FILE"
$TW pipelines view -n "${PIPELINE_NAME}_imported"
$TW pipelines delete -n "${PIPELINE_NAME}_imported"
rm -f "$EXPORT_FILE"

Verify: Imported pipeline exists and can be viewed.

Cleanup

$TW pipelines delete -n "$PIPELINE_NAME"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants