Skip to content

Map: action-seqera-launch v1 #1

Description

@edmundmiller

Destination

A decision-complete route to v1.0.0 of action-seqera-launch: a TypeScript
GitHub Action that launches and monitors Seqera Platform workflows by calling
the Platform REST API directly (no Docker, no tw CLI), with first-class error
reporting. Reached when the client approach, input/output contract,
monitoring/error UX, repo scaffold, release process, and repo visibility are
each decided — nothing left for an implementer to design.

Notes

  • Planning-only effort (wayfinder default): tickets resolve decisions, not code.
    Building the action is a separate effort that starts once this map is empty.
  • Origin: Refactor to use javascript action-tower-launch#28 — deliberate clean break. nf-core
    pipelines stay pinned to action-tower-launch v2, so v1 carries no
    input-for-input back-compat obligation.
  • Grilling tickets: use the grilling and domain-modeling skills.
    Research tickets: the research skill. Prototype tickets: the prototype
    skill.
  • Reference docs: GitHub "release and maintain actions", "creating a JavaScript
    action", "creating a composite action"; Seqera Platform OpenAPI spec at
    https://cloud.seqera.io/openapi/seqera-api-latest.yml
  • Decision records: closing a grilling ticket writes an ADR under
    docs/decisions/ in this repo; the ticket's resolution comment is a short
    pointer to it, and the Decisions-so-far line below links the ADR. ADR 0001
    (repository name) predates this map and is not indexed here.
  • The action is built on Effect (Schema, Schedule, tagged errors —
    effect@4.0.0-rc.110, pinned exact). Later tickets should assume decoding,
    retry, and the error channel are Effect's, and note that v4's API differs from
    every pre-v4 example online. See ADR 0004.

Decisions so far

  • Research: Seqera Platform launch + monitor API surfacePOST /workflow/launch?workspaceId= with a {launch:{...}} body returns workflowId; poll GET /workflow/{id}?workspaceId= for a 6-value status enum; no official JS/TS SDK, but a codegen-ready OpenAPI spec and a 20 req/s token limit.
  • Research: TypeScript action toolchain baselineactions/typescript-action is now node24 + ESM + Rollup 4 + Jest 30 with a committed dist/ guarded by check-dist; @actions/* majors are core 3, github 9, http-client 4, all ESM-only.
  • Decide: JS action vs composite, and repo scaffold — TypeScript JS action (node24), single root action.yml, hand-rolled scaffold: Rolldown → committed dist/, Vitest, oxlint + oxfmt, npm. See ADR docs/decisions/0002-javascript-action-and-scaffold.md.
  • Decide: generated API client vs hand-rolled fetch wrapper — generated types, hand-rolled calls: committed openapi/seqera-api-1.198.0.ymlopenapi-typescript → committed src/api/schema.d.ts, narrow aliases in src/api/types.ts, hand-rolled wrapper over @actions/http-client (11.8 kB marginal; undici is inlined by @actions/core regardless), Enterprise-configurable api-endpoint. See ADR docs/decisions/0003-api-client-generated-types-hand-rolled-calls.md — partly revised by ADR 0004 below.
  • Decide: generated API client vs hand-rolled fetch wrapper (amendment) — Effect adopted for decoding, retry, and errors: Schema replaces hand-written narrowing, Schedule replaces the backoff loop, tagged errors replace exceptions; effect@4.0.0-rc.110 pinned exact (+73.6 kB measured). openapi-typescript stays as the compile-time cross-check — JsonSchema.fromSchemaOpenApi3_1 is dialect conversion, not codegen. See ADR docs/decisions/0004-effect-for-decoding-retry-and-errors.md.
  • Decide: input/output contract for v1 — inputs are kebab-case (breaking: access_tokenaccess-token); compute-env-id and compute-env both accepted with the id winning, since ListComputeEnvs has no name filter; v2's ten launch fields plus eight low-risk additions (postRunScript, labelIds, outputDir, stubRun, pullLatest, nextflowVersion, headJobCpus, headJobMemoryMb), with resume/sessionId deliberately excluded; four outputs (workflow-id, workflow-url, workspace-id, workspace-ref) — v2's json dropped so the response shape is not a public contract. WorkflowLaunchRequest declares no required fields, so requiredness is entirely ours to enforce. See ADR docs/decisions/0005-input-output-contract-for-v1.md.
  • Decide: run monitoring and error-reporting UXwait is an enum running | completion | none defaulting to running, replacing v2's boolean: most launch failures happen at submit/validation time, so confirming the run started catches them without holding a runner for a whole pipeline (green means launched, and the log says so). timeout input, unset polls until the job dies; exponential backoff 5s→60s. Only SUCCEEDED passes — FAILED/CANCELLED/UNKNOWN and any unrecognised status all fail loudly. SUBMITTED past a bounded wait fails naming the compute env. On failure: errorMessage/errorReport/exitStatus, failed-task list, truncated .command.err tails; job summary always written; no artifact upload and no PR commenting (callers compose those). Adds status + error-message outputs, resolving Decide: input/output contract for v1 #4's deferral; ConfigError translated to one sentence naming the input; verbosity via ACTIONS_STEP_DEBUG, dropping v2's verbose. See ADR docs/decisions/0006-run-monitoring-and-error-reporting.md.
  • Decide: release and versioning process — SemVer vX.Y.Z Releases plus a floating v1 with no Release attached, the mechanism action-tower-launch already uses (its v2 is a bare tag on the same commit as v2.3.0), since immutable releases freeze only Release-attached tags. No minor-level floating tags. Internal seqeralabs consumers must pin SHAs regardless, per org policy. Release is a workflow triggered by pushing a vX.Y.Z tag; it rebuilds dist/ and refuses to release on any diff. Release Please/changesets rejected as too heavy. v1.0.0-rc.1 precedes v1.0.0 (the effect rc pin is not GA and nothing has launched in anger); Marketplace listing at v1.0.0, not at the rc. Spec bumps imply a release only when the types we use change behaviour. Branding icon: play, color: green — v2's purple is off-brand. See ADR docs/decisions/0007-release-and-versioning.md.

Not yet specified

  • E2E test strategy against a live Platform workspace: which org/workspace,
    which pipeline to launch from CI, how the access token is stored. Now
    unblocked — the I/O contract (ADR 0005) and monitoring (ADR 0006) are both
    decided.
  • Migration guidance for action-tower-launch users — unblocked. Three things
    callers must be told: the kebab-case rename table, the loss of the json
    output, and that wait: true becomes wait: completion while the new
    default waits for the run to start.
  • Marketplace listing copy and README structure. Branding is decided (ADR 0007:
    icon: play, color: green); anyone revisiting it should read the exact hex
    off brand.seqera.net directly — the site is client-rendered, so scraping it
    returns a shell whose --color-kumo-* variables are docs-site theme, not the
    brand palette.
  • Deprecation messaging on the action-tower-launch repo once v1 ships.
  • Where the advisory spec-drift PR job lives — unblocked. ADR 0007 settles that
    a spec bump implies a release only when the types we use change behaviour;
    the job's CI wiring is still unwritten.
  • Whether Effect extends past decoding/retry/errors into @effect/platform
    HttpClient and a Layer-based runtime. Bounded out of ADR 0004 for v1.
    ADR 0006's polling loop is a backoff schedule plus a status match, which does
    not on its own justify a Layer runtime.
  • Migration to effect 4.0.0 stable once it ships, and whether the rc pin
    blocks a v1 release.

Out of scope

  • Any further work on action-tower-launch itself; the rewrite in its PR #28 is
    superseded by this effort.
  • Guaranteed input-for-input compatibility with action-tower-launch v2.
  • Launching a Seqera Studio from the action. Raised while deciding the
    scaffold and consciously deferred: this map's destination is launching and
    monitoring pipeline runs, and Studios are a different Platform resource with
    their own API surface and lifecycle. It returns as its own effort if the
    destination is ever redrawn, not as fog on this map.

Metadata

Metadata

Assignees

No one assigned

    Labels

    wayfinder:mapWayfinder map (index issue)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions