#artifact #sdk #go #step #source #python #linux #vorpal

vorpal-sdk

Vorpal SDK for building Vorpal configurations

1 unstable release

new 0.1.0-alpha Apr 22, 2025

#9 in #step

Download history 53/week @ 2025-04-16

53 downloads per month

Apache-2.0

145KB
4.5K SLoC

vorpal

Build and ship software with one powerful tool.

Overview

Vorpal uses declarative "bring-your-own-language" configurations to build software distributively and natively in a repeatable and reproducible way.

Examples of building a Rust application in multiple languages:

Rust

use anyhow::Result;
use vorpal_sdk::{
    artifact::language::rust::RustArtifactBuilder,
    context::get_context,
};

#[tokio::main]
async fn main() -> Result<()> {
    // 1. Get context
    let context = &mut get_context().await?;

    // 2. Create artifact
    let example = RustArtifactBuilder::new("example")
        .build(context)
        .await?;

    // 3. Run context with artifacts
    context.run(vec![example]).await
}

Go

package main

import (
    "log"

    "github.com/ALT-F4-LLC/vorpal/sdk/go/internal/artifact/language"
    "github.com/ALT-F4-LLC/vorpal/sdk/go/internal/config"
)

func main() {
    // 1. Get context
    context := config.GetContext()

    // 2. Create artifact
    example, err := language.
        NewRustBuilder("example").
        Build(context)
    if err != nil {
        log.Fatalf("failed to build artifact: %v", err)
    }

    // 3. Run context with artifacts
    context.Run([]*string{example})
}

Python

from vorpal_sdk.config import get_context
from vorpal_sdk.config.artifact.language.rust import rust_artifact

def main():
    # 1. Get context
    context = get_context()

    # 2. Create artifact
    example = rust_artifact(context, "example")

    # 3. Run context with artifacts
    context.run([example])

if __name__ == "__main__":
    main()

TypeScript

import { getContext } from '@vorpal/sdk';
import { RustArtifactBuilder } from '@vorpal/sdk/config/artifact/language/rust';

async function main() {
    // 1. Get context
    const context = await getContext();

    // 2. Create artifact
    const example = await new RustArtifactBuilder('example')
        .build(context);

    // 3. Run context with artifacts
    await context.run([example]);
}

main().catch(console.error);

Components

Below is the existing working diagram that illustrates the platform's design:

Caution

This design is subject to change at ANY moment and is a work in progress.

vorpal-domains

Artifacts

Vorpal uses artifacts to describe every aspect of your software in the language of your choice:

Artifact {
    // name of artifact
    name: "example".to_string(),

    // source paths for artifact
    sources: vec![
        ArtifactSource {
            name: "example", // required, unique per source
            excludes: vec![], // optional, to remove files
            hash: None, // optional, to track changes
            includes: vec![], // optional, to only use files
            path: ".", // required, relative location to context
        }
    ],

    // steps of artifact (in order)
    steps: vec![
        ArtifactStep {
            entrypoint: Some("/bin/bash"), // required, host path for command (can be artifact)
            arguments: vec![], // optional, arguments for entrypoint
            artifacts: vec![], // optional, artifacts included in step
            environments: vec![], // optional, environment variables for step
            script: Some("echo \"hello, world!\" > $VORPAL_OUTPUT/hello_world.txt"), // optional, script passed to executor
        },
    ],

    // systems for artifact
    systems: vec![Aarch64Darwin, Aarch64Linux],

    // target
    target: Aarch64Darwin
};

Artifacts can be wrapped in language functions and/or modules to be shared within projects or organizations providing centrally managed and reusable configurations with domain-specific overrides (see examples in overview).

Sources

Coming soon.

Steps

Steps provided by the SDKs are maintained to provide reproducibile cross-platform environments for them. These environments include strictly maintained low-level dependencies that are used as a wrapper for each step.

Note

Vorpal enables developers to create their own build steps instead of using the SDKs which are provided to handle "common" scenarios.

Linux

On Linux, developers can run steps in a community maintained sandbox which is isolated similiar to containers.

The following are included in the sandbox:

  • bash
  • binutils
  • bison
  • coreutils
  • curl
  • diffutils
  • file
  • findutils
  • gawk
  • gcc
  • gettext
  • glibc
  • grep
  • gzip
  • libidn2
  • libpsl
  • libunistring
  • linux-headers
  • m4
  • make
  • ncurses
  • openssl
  • patch
  • perl
  • python
  • sed
  • tar
  • texinfo
  • unzip
  • util-linux
  • xz
  • zlib

macOS

Coming soon.

Windows

Coming soon.

Systems

Coming soon.

Development

Requirements

macOS

On macOS, install the native tools with Xcode:

xcode-select --install

Linux

On Linux, install dependencies with the distro's package manger (apt, yum, etc):

Important

If you are using NixOS, there is a shell.nix configuration included for the development environment.

  • bubblewrap (sandboxing)
  • curl (downloading)
  • docker (sandboxing)
  • protoc (compiling)
  • unzip (downloading)

The helpful ./script/debian.sh used for setting up systems in continuous integration can also be used to setup any similiar Debian-based systems.

Setup

The helpful ./script/dev.sh used to run development commands in an isolated way without having to update your environment.

Important

If you are using NixOS, there is a shell.nix configuration included for the development environment.

The following installs missing dependencies then runs cargo build inside the development environment:

$ ./script/dev.sh cargo build

Direnv

To develop inside the environment the supported solution is to use direnv which manages all of this for you. Direnv will automatically run "./script/dev.sh" under the hood and export environment variables to your shell when you enter the directory.

Once you've installed direnv on your system navigate to Vorpal's source code and run:

$ direnv allow

Testing

At this point, you should be able to run cargo build successfully in the repository. If that doesn't work, go back to "Setup" and verify you have done all the required steps.

These steps guide how to compile from source and also test compiling Vorpal with Vorpal.

  1. Build without Vorpal:
make build
  1. Run the initial install script, which will create all relevant directories and permissions needed to run the next steps.

Caution

This step requires access to protected paths on your host filesystem. As such, it will likely require sudo privileges (or your system's equivalent) to run.

bash ./script/install.sh
  1. Generate keys for Vorpal:
./target/debug/vorpal keys generate
  1. Start services for Vorpal:
./target/debug/vorpal start
  1. Build with Vorpal:
./target/debug/vorpal artifact --name "vorpal"

The entire stack of has now been tested by building itself.

Makefile

There is makefile which can be used as a reference for common commands used when developing.

Here are some frequently used:

  • make (default build)
  • make lint (before pushing)
  • make dist (package in ./dist path)
  • make vorpal-start (runs services with cargo)
  • make vorpal (builds vorpal-in-vorpal with cargo)

Dependencies

~6–14MB
~158K SLoC