Skip to content
DocsAll docs
Console

Definitions and versions

Change a pipeline as a new version, read earlier versions, go back to one, and delete versions and pipelines.

Last updated

On this page

Description and operation

General

A pipeline is a name for an owner and a list of numbered versions. Each version holds one definition and never changes. A run records the version that it ran, so a later change does not alter a run that exists. The format of a definition is in Pipeline definition.

ActionResult
CreateSaves version 1 and answers 201. The name in the definition is the name of the pipeline. It has 1 to 63 lowercase letters, digits and inner hyphens.
Update with a changed definitionSaves the next version. A run that starts later uses it.
Update with an equal definitionSaves nothing and answers 200 with the newest version.
Go backSend an earlier definition again. It becomes the next version.
Delete a versionRemoves one old version that no queued or running run uses.
Delete the pipelineRemoves the pipeline and all its versions. Finished runs stay.

A save checks the whole definition and reports every problem at once, each with its job and step. A save also checks facts about the owner. Each secret that the definition names exists. The pipeline of an after trigger exists. Each volume or snapshot that a job names exists, or an earlier job saves to it.

A definition larger than 64 KiB is refused with 422 before any other check. A definition that saves is a definition that can run.

To do these tasks with an AI agent, see Agentic workflows – General.

Canonical form

The platform stores each definition in a canonical form. It keeps the order of jobs, inputs and each matrix as you wrote them, sorts every other map and leaves out every default value. Two spellings of one definition have the same definitionSha256, so a save of an equal definition makes no new version.

Field of the answerMeaning
owner, nameThe owner and the name of the pipeline.
versionThe version that the answer shows.
latestVersionThe newest version of the pipeline.
definitionSha256The SHA-256 hash of the canonical definition. A run records the same hash.
createdBy, createdAtMsWho saved the version, and when, in milliseconds since the epoch.
definitionThe definition of the version, with jobs in the order that you wrote them.
triggersThe schedule, webhook and after trigger of the version.
webhookset is true when the pipeline has a webhook secret.
webhookUrlThe webhook URL. Only in the answer of the save that made the webhook secret.

Delete rules

You cannot delete the newest version. You cannot delete a version, or a pipeline, while a queued or running run uses it. A finished run of a deleted version stays readable, without its definition. Run records are kept for 90 days after the run ends.

Tasks

Save a new version

Reason for the task: Change what a pipeline does, and keep the earlier definition.

Job set-up

  • Access: you. For a team, an admin.
  • Conditions: the pipeline nightly-report exists, and nightly-report.json holds its changed definition. The name in the file is nightly-report.
  • References: PUT /v1/pipelines/{owner}/{name}, SDK pipelines.update. In the CLI, --file - reads the definition from standard input, and --owner defaults to your handle.

Procedure

  1. Send the changed definition as the next version.

    Python
    import jsonfrom kloudlite import Kloudlitekl = Kloudlite()with open("nightly-report.json") as f:    doc = kl.pipelines.update(owner="acme", name="nightly-report", definition=json.load(f))print(doc["version"], doc["latestVersion"])
    TypeScript
    import { readFileSync } from "node:fs";import { Kloudlite } from "./index.ts";const kl = new Kloudlite();const definition = JSON.parse(readFileSync("nightly-report.json", "utf8"));const doc = await kl.pipelines.update({ owner: "acme", name: "nightly-report", definition });console.log(doc.version, doc.latestVersion);
    Go
    kl := kloudlite.New(kloudlite.Options{})raw, err := os.ReadFile("nightly-report.json")if err != nil {    log.Fatal(err)}var d kloudlite.PipelineDefinitionif err := json.Unmarshal(raw, &d); err != nil {    log.Fatal(err)}doc, err := kl.Pipelines.Update("acme", "nightly-report", d)if err != nil {    log.Fatal(err)}fmt.Println(doc.Version, doc.LatestVersion)
    Ruby
    require "json"require_relative "kloudlite"kl = Kloudlite::Client.newdoc = kl.pipelines.update(owner: "acme", name: "nightly-report", definition: JSON.parse(File.read("nightly-report.json")))puts doc.values_at("version", "latestVersion").join(" ")
    Java
    var kl = new Kloudlite();System.out.println(kl.request(new Kloudlite.RawRequest().method("PUT").path("/v1/pipelines/acme/nightly-report")    .body(Files.readString(Path.of("nightly-report.json")))));
    CLI
    kloudlite pipelines update acme/nightly-report --file nightly-report.json

Close-out

  1. Make sure that version is one more than before. An equal definition returns the same version.

Show the versions of a pipeline

Reason for the task: Find which definition a version holds, for example the version that a run used.

Job set-up

Procedure

  1. Show the list of versions, oldest first.

    Python
    print(kl.pipelines.versions(owner="acme", name="nightly-report"))
    TypeScript
    console.log(await kl.pipelines.versions({ owner: "acme", name: "nightly-report" }));
    Go
    versions, err := kl.Pipelines.Versions("acme", "nightly-report")if err != nil {    log.Fatal(err)}fmt.Printf("%+v\n", versions)
    Ruby
    p kl.pipelines.versions(owner: "acme", name: "nightly-report")
    Java
    System.out.println(kl.pipelines().versions("acme", "nightly-report"));
    CLI
    kloudlite pipelines versions acme/nightly-report
  2. Show the definition of version 1. Leave out the version to show the newest.

    Python
    print(kl.pipelines.get(owner="acme", name="nightly-report", version=1)["definition"])
    TypeScript
    console.log((await kl.pipelines.get({ owner: "acme", name: "nightly-report", version: 1 })).definition);
    Go
    doc, err := kl.Pipelines.Get(kloudlite.GetPipeline{Owner: "acme", Name: "nightly-report", Version: 1})if err != nil {    log.Fatal(err)}fmt.Printf("%+v\n", doc.Definition)
    Ruby
    p kl.pipelines.get(owner: "acme", name: "nightly-report", version: 1)["definition"]
    Java
    System.out.println(kl.pipelines().get("acme", "nightly-report", 1));
    CLI
    kloudlite pipelines get acme/nightly-report --version 1

Close-out

  1. Examine definitionSha256 of the version and of a run. Equal values mean that the run used that definition.

Go back to an earlier version

Reason for the task: Undo a change that broke a pipeline, and keep a record of the change.

Job set-up

  • Access: you. For a team, an admin.
  • Conditions: the earlier version exists. See Show the versions of a pipeline.
  • References: SDK pipelines.get, pipelines.update.

Procedure

  1. Read the definition of the earlier version, then send it as the next version.

    Python
    old = kl.pipelines.get(owner="acme", name="nightly-report", version=1)["definition"]doc = kl.pipelines.update(owner="acme", name="nightly-report", definition=old)print(doc["version"])
    TypeScript
    const old = await kl.pipelines.get({ owner: "acme", name: "nightly-report", version: 1 });const doc = await kl.pipelines.update({ owner: "acme", name: "nightly-report", definition: old.definition });console.log(doc.version);
    Go
    old, err := kl.Pipelines.Get(kloudlite.GetPipeline{Owner: "acme", Name: "nightly-report", Version: 1})if err != nil {    log.Fatal(err)}doc, err := kl.Pipelines.Update("acme", "nightly-report", old.Definition)if err != nil {    log.Fatal(err)}fmt.Println(doc.Version)
    Ruby
    old = kl.pipelines.get(owner: "acme", name: "nightly-report", version: 1)["definition"]puts kl.pipelines.update(owner: "acme", name: "nightly-report", definition: old)["version"]
    Java
    // The SDK returns raw JSON. Take "definition" from it with your JSON library, here Jackson.String doc = kl.pipelines().get("acme", "nightly-report", 1);String old = new ObjectMapper().readTree(doc).get("definition").toString();System.out.println(kl.request(new Kloudlite.RawRequest().method("PUT").path("/v1/pipelines/acme/nightly-report").body(old)));
    CLI
    kloudlite pipelines get acme/nightly-report --version 1 --json | jq .definition > old.jsonkloudlite pipelines update acme/nightly-report --file old.json

Close-out

  1. Make sure that the new version is the newest, and that its definitionSha256 equals that of version 1.

Delete an old version

Reason for the task: Remove a version that is no longer needed. Version numbers are never reused, so this does not free a number.

Job set-up

  • Access: you. For a team, an admin.
  • Conditions: the version is not the newest, and no queued or running run uses it.
  • References: DELETE /v1/pipelines/{owner}/{name}/versions/{n}. The SDKs have no method for this route, so the procedure sends it as a raw request.

Procedure

  1. Send the delete for version 1.

    Python
    kl.request("DELETE", "/v1/pipelines/acme/nightly-report/versions/1")
    TypeScript
    await kl.request("DELETE", "/v1/pipelines/acme/nightly-report/versions/1");
    Go
    if err := kl.Request("DELETE", "/v1/pipelines/acme/nightly-report/versions/1", kloudlite.RequestOptions{}); err != nil {    log.Fatal(err)}
    Ruby
    kl.request("DELETE", "/v1/pipelines/acme/nightly-report/versions/1")
    Java
    kl.request("DELETE", "/v1/pipelines/acme/nightly-report/versions/1");

Close-out

  1. Show the versions of the pipeline. Make sure that version 1 is not listed.

Delete a pipeline

Reason for the task: Remove a pipeline that is no longer used, with all its versions and triggers.

Job set-up

WARNING

The definitions of all versions are deleted, and the schedule and the webhook URL stop. Save the definition in a file first to keep it.

Procedure

  1. Delete the pipeline.

    Python
    kl.pipelines.delete(owner="acme", name="nightly-report")
    TypeScript
    await kl.pipelines.delete({ owner: "acme", name: "nightly-report" });
    Go
    if err := kl.Pipelines.Delete("acme", "nightly-report"); err != nil {    log.Fatal(err)}
    Ruby
    kl.pipelines.delete(owner: "acme", name: "nightly-report")
    Java
    kl.pipelines().delete("acme", "nightly-report");
    CLI
    kloudlite pipelines delete acme/nightly-report

Close-out

  1. Show the pipelines of the owner. Make sure that nightly-report is not listed.
  2. Read a finished run of the pipeline. It stays readable for 90 days after it ended.

Troubleshooting

SymptomPossible causeCorrective action
422 with pipeline nightly-report is invalid: and a list of linesThe definition has errors. Each line names the job and the step.Correct each line and send the definition again.
422 with `name` is nightly but the path names nightly-reportThe name in the definition differs from the pipeline that you update.Use the same name. To rename, create a new pipeline and delete the old one.
422 with secret DB_URL does not existThe definition names a secret that the owner does not have.Set the secret, then save again.
422 with `triggers.after`: no pipeline buildThe after trigger names a pipeline that does not exist.Create that pipeline first, or correct the name.
409 with pipeline nightly-report existsA create used the name of a pipeline that exists.Send an update to save a new version.
409 with pipeline nightly-report changed; retryAnother save won the race.Read the pipeline again and send the save again.
409 with pipeline nightly-report has 100 versions; delete an old versionThe newest version number is 100, and a deleted version does not free a number.Create a new pipeline with the definition.
409 with version 3 is the latest; it cannot be deletedYou tried to delete the newest version.Save a new version first, or delete the pipeline.
409 with version 1 is used by run 1760400000000-0a1b2cA queued or running run uses the version.Wait for the run to end, or cancel it.
409 with pipeline nightly-report has a queued or running runA run has not ended.Cancel the run, or wait for it to end.
409 with pipeline nightly-report is being deleted; retryA pipeline of this name is still being deleted.Send the save again.
404 with not foundAn update names a pipeline that does not exist.Create the pipeline first.
404 with version 1 of nightly-report is goneThe version was deleted, or never existed.Show the versions and use one that is listed.
400 with version is not a numberThe version in the request is not a number.Give the version as a number, for example 2.
503 with secrets cannot be read right now; retry, or the same text with pipelines or volumesA check of the save could not read its data.Send the save again.