Skip to content

Pipelight

Automation pipelines but easier.

Elevate your bash scripts to generic, debuggable and auto-triggered pipelines.

pipelight_logo

Command-line Interface

Stay in the comfort of your terminal

[g@ku ~]

[g@ku ~]

● succeeded-Fri, 5 Jul 2023 16:52:58 +0200
branch: dev
action: pre-commit
commit: y54rr75f5fe3fcac3e461x9
pipeline: vitest_unit_test(6s219ms)
● running-Fri, 5 Jul 2023 17:20:58 +0200
branch: master
action: manual
commit: 8hhg75f5fe3fcac3e46117f
pipeline: my_pipe(6s319ms)

Write readable and reusable blocks.

Your shell commands..

sh
#simple_example.sh
## List files
ls;
## Get working directory
pwd;
#simple_example.sh
## List files
ls;
## Get working directory
pwd;

..wrapped into Typescript..

ts
{
  name: "simple_example",
  steps: [
    {
      name: "list files",
      commands: ["ls"]
    },
    {
      name: "get directory",
      commands: ["pwd"]
    }
  ]
}
{
  name: "simple_example",
  steps: [
    {
      name: "list files",
      commands: ["ls"]
    },
    {
      name: "get directory",
      commands: ["pwd"]
    }
  ]
}

..boosted with syntactic sugar

ts
pipeline("simple_example", () => [
  step("list files",() => ["ls"]),
  step("get directory", () => ["pwd"])
]);
pipeline("simple_example", () => [
  step("list files",() => ["ls"]),
  step("get directory", () => ["pwd"])
]);

Code in your config file.

ts
import { makeDeployPipe } from "./template/deploy.ts";

const env = await load({ envPath: `./.env.production` });

const params = {
  remote: {
    domain: "myserver.com",
    path: "/remote/directory"
  },
  local: {
    path: "/my/build/directory"
  }
};

const deploy_pip = makeDeployPipe(params, env);

export default {
  pipelines: [deploy_pipe]
};
import { makeDeployPipe } from "./template/deploy.ts";

const env = await load({ envPath: `./.env.production` });

const params = {
  remote: {
    domain: "myserver.com",
    path: "/remote/directory"
  },
  local: {
    path: "/my/build/directory"
  }
};

const deploy_pip = makeDeployPipe(params, env);

export default {
  pipelines: [deploy_pipe]
};

Define complex operations with less code.

with the Pipelight Helpers

ts
pipeline("docker_deploy", () => [
  step("build images and run containers", () => [
    ...docker.images.create(),
    ...docker.containers.create()
  ])
]);
pipeline("docker_deploy", () => [
  step("build images and run containers", () => [
    ...docker.images.create(),
    ...docker.containers.create()
  ])
]);

Troubleshoot the pipe in a breeze.

Get aggressively verbose

Gather every process outputs.

[g@ku ~]

[g@ku ~]

● running-Fri, 5 Jul 2023 16:52:58 +0200
branch: dev
action: manual
commit: 5f5fe3fcac3e46117fcbfr
pipeline: deploy_to_host(6s619ms)
  • step: build_files(4s619ms)
    • pnpm install(919ms)
      • stdout: Lockfile is up to date, resolution step is skipped Already up to date Done in 924ms
      • stderr:
    • vite build(3s919ms)
      • stdout: vite v4.3.1 building for production... transforming... 🌼 daisyUI 3.0.20 ✓ 669 modules transformed. rendering chunks... computing gzip size... dist/index.html 0.45 kB │ gzip: 0.30 kB dist/assets/product-bbe8489e.css 0.36 kB │ gzip: 0.17 kB dist/assets/collection-c3ae63aa.css 0.36 kB │ gzip: 0.17 kB dist/assets/index-dc1b6ad3.js 58.72 kB │ gzip: 10.54 kB 161.97 kB │ gzip: 60.82 kB ✓ built in 3.24s
      • stderr:
  • parallel
    • step: build image itsdizygote.com/front:production(1s419ms)
      • docker build --tag itsdizygote.com/front:production --file .docker/Dockerfile.front .(1s419ms)
        • stdout:
        • stderr: #0 building with "default" instance using docker driver #1 [internal] load .dockerignore #1 transferring context: 2B done #1 DONE 0.0s #2 [internal] load build definition from Dockerfile.front #2 transferring dockerfile: 277B done #2 DONE 0.0s #3 [internal] load metadata for docker.io/library/archlinux:latest #3 DONE 1.2s #12 exporting layers done #12 writing image sha256:f0547343647bb06a2489c4d25cb44592d992dcada04a7e3566fee95190259fa4 done #12 naming to itsdizygote.com/front:production done #12 DONE 0.0s
  • parallel
    • step: send image itsdizygote.com/front:production to remote
      • docker save itsdizygote.com/front:production | ssh -o TCPKeepAlive=no -C linode "docker load"
        • stdout:
        • stderr:
  • parallel
    • step: clean containers production.front.itsdizygote.com
      • ssh -o TCPKeepAlive=no -C linode "docker container stop production.front.itsdizygote.com && docker container rm production.front.itsdizygote.com"
        • stdout:
        • stderr:
  • parallel
    • step: run containers production.front.itsdizygote.com
      • ssh -o TCPKeepAlive=no -C linode "docker run --detach --publish 127.0.0.1:9280:3000 --name production.front.itsdizygote.com itsdizygote.com/front:production"
        • stdout:
        • stderr:

Trigger pipelines automatically.

On file change

ts
// When saving/deleting/modifying a file
// on branch dev and feature/<something>
{
    actions: ["watch"],
    branches: ["dev", "feature/*"]
}
// When saving/deleting/modifying a file
// on branch dev and feature/<something>
{
    actions: ["watch"],
    branches: ["dev", "feature/*"]
}
sh
# Using vim (saves changes)
:w
# Using vim (saves changes)
:w

On git hooks

ts
// When on tag v<something> and pushing to remote
{
    actions: ["pre-push"],
    tags: ["v*"]
}
// When on tag v<something> and pushing to remote
{
    actions: ["pre-push"],
    tags: ["v*"]
}
sh
git tag -a v0.1
#or
git checkout v0.1
git push
git tag -a v0.1
#or
git checkout v0.1
git push

Write small pipelines for atomic tasks.

Use minimal configuration formats

Old-school flavors

toml
[[pipelines]]
name =  "simple_example"

[[pipelines.steps]]
name = "list directory"
commands = ["ls"]

[[pipelines.steps]]
name = "get working directory"
commands = ["pwd"]
[[pipelines]]
name =  "simple_example"

[[pipelines.steps]]
name = "list directory"
commands = ["ls"]

[[pipelines.steps]]
name = "get working directory"
commands = ["pwd"]
yml
pipelines:
  - name: simple_example
    steps:
      - name: list directory
        commands:
          - ls
      - name: get working directory
        commands:
          - pwd
pipelines:
  - name: simple_example
    steps:
      - name: list directory
        commands:
          - ls
      - name: get working directory
        commands:
          - pwd

tl;dr

⚡ Light and Fast
Written in Rust to be as low level as possible and stick to bare script performances.
🫦 Pretty Logs
Easily troubleshoot your scripts with pretty and verbose logs right in your terminal.
🚦 Automatic Triggers
Your pipelines are executed in background on some events. You don't leave your editor.
🤌 Typescript { Bash }
Enjoy wrapping your Bash with Typescript delicious and simple syntax. Uses Deno for its quick Typechecking.

Rust based.

Made with passion

for conscientious programmers.

♥️