Skip to content

LucaTools/LucaWorkflows

Repository files navigation

LucaWorkflows

Ready-to-use GitHub Actions workflows that build, package, and publish CLI tool releases on github.com — compatible with Luca.

Why

Luca is a lightweight tool manager that installs CLI tools directly from GitHub Releases. It follows a distributed model: no central registry, no package index — just a zip file attached to a GitHub Release.

Many open-source projects don't publish pre-built binaries in their GitHub Releases. These workflows solve that by giving developers a copy-paste CI pipeline that builds, bundles, and publishes release assets in the format Luca expects.

Push a tag, get a release with binaries. That's it.

Supported languages

Workflow Language Build tooling Binary type
publish_release_swift.yml Swift swift build, lipo Native universal binary
publish_release_go.yml Go go build with cross-compilation Native universal binary
publish_release_rust.yml Rust cargo build per target triple Native universal binary
publish_release_dotnet.yml C# / .NET dotnet publish with Native AOT Native universal binary
publish_release_python.yml Python PyInstaller --onefile Bundled standalone binary
publish_release_zig.yml Zig zig build per target Native universal binary

Quick start

  1. Copy the workflow for your language into your repository at .github/workflows/
  2. Replace the placeholders (see table below) with your project's values
  3. Push a tag:
    git tag 1.0.0
    git push --tags
  4. The workflow will build your tool, create a GitHub Release, and upload the assets automatically

Placeholders

Each workflow has a small set of placeholders in the env: block at the top of the file. Replace them before committing.

Swift

Placeholder Description Example
[TOOL_NAME] Executable product name (as in Package.swift) swiftlint

Go

Placeholder Description Example
[TOOL_NAME] Output binary name mytool
[GO_VERSION] Go version 1.23
[MAIN_PACKAGE] Path to main package . or ./cmd/mytool

Rust

Placeholder Description Example
[TOOL_NAME] Binary name (as in Cargo.toml [[bin]]) ripgrep
[RUST_TOOLCHAIN] Rust toolchain stable or 1.82

C# / .NET

Placeholder Description Example
[TOOL_NAME] Output binary name mytool
[DOTNET_VERSION] .NET SDK version 9.0.x
[PROJECT_PATH] Path to .csproj file src/MyTool/MyTool.csproj

Python

Placeholder Description Example
[TOOL_NAME] Output binary name mytool
[PYTHON_VERSION] Python version 3.12
[ENTRY_POINT] Path to main script src/main.py

Zig

Placeholder Description Example
[TOOL_NAME] Binary name (as in build.zig addExecutable) mytool
[ZIG_VERSION] Zig version 0.13.0

What gets published

Every workflow produces three release assets attached to the GitHub Release:

Asset Contents
<name>-macOS.zip macOS universal binary (arm64 + x86_64)
<name>-Linux.zip Linux x86_64 binary
<name>.artifactbundle.zip Swift artifact bundle containing both binaries

The artifact bundle is a standard format defined by Swift Package Manager. It includes an info.json manifest with platform-specific binary paths, making it usable as a SwiftPM binary target as well.

How it works

Each workflow follows the same 4-job pipeline:

build-macos ──┐
              ├── generate-artifactbundle ── create-release
build-linux ──┘
  1. build-macos — Runs on macos-15. Builds arm64 and x86_64 binaries, merges them into a universal binary with lipo
  2. build-linux — Runs on ubuntu-latest. Builds a statically-linked x86_64 binary
  3. generate-artifactbundle — Assembles the .artifactbundle directory structure with info.json
  4. create-release — Creates a GitHub Release (idempotent — reuses existing if found) and uploads all three zip assets

Authentication

All workflows use the built-in GITHUB_TOKEN — no Personal Access Token required. The create-release job declares permissions: contents: write for release creation and asset uploads.

External dependencies

Workflows depend only on official GitHub-maintained actions:

  • actions/checkout@v4
  • actions/upload-artifact@v4
  • actions/download-artifact@v4
  • Language setup actions (actions/setup-go@v5, actions/setup-python@v5, actions/setup-dotnet@v4)

Release creation and asset uploads use direct GitHub REST API calls — no third-party release actions.

Language-specific notes

Swift

  • Requires macOS runner for lipo and swift build --arch
  • Linux build uses the official swift:6.0-jammy Docker image inside ubuntu-latest
  • Uses -Xswiftc -static-stdlib for statically-linked Linux binaries

Go

  • Cross-compilation is done natively via GOOS/GOARCH environment variables
  • CGO_ENABLED=0 ensures fully static binaries with no system library dependencies
  • Build flags include -trimpath -ldflags="-s -w" to strip debug info and reduce binary size

Rust

  • Builds per target triple: aarch64-apple-darwin, x86_64-apple-darwin, x86_64-unknown-linux-gnu
  • Installs musl-tools on Linux for static linking support
  • Uses lipo on macOS to merge the two Darwin builds into a universal binary

C# / .NET

  • Defaults to Native AOT (/p:PublishAot=true) for small, fast, self-contained binaries
  • If your project doesn't support AOT, switch to /p:PublishSingleFile=true /p:SelfContained=true
  • Linux AOT builds require clang and zlib1g-dev (installed automatically)

Python

  • Uses PyInstaller to bundle the Python interpreter and all dependencies into a single executable
  • Resulting binaries are larger than compiled languages (~20–50 MB)
  • macOS build is not a universal binary — it runs on the runner's native architecture (arm64 on macos-15)
  • Automatically installs dependencies from requirements.txt or pyproject.toml if present

Zig

  • Zig has excellent built-in cross-compilation support
  • Installs Zig by downloading the official release tarball (no third-party setup action needed)
  • Output paths may vary depending on your build.zig configuration — see inline comments in the workflow

Customisation

These workflows are designed to be copied and modified. Common customisations:

  • Remove the Linux job if you only target macOS (update generate-artifactbundle to remove the Linux variant from info.json)
  • Remove the artifactbundle job if you don't need Swift Package Manager compatibility (have create-release depend directly on the build jobs)
  • Add more platforms (e.g. windows-latest) by adding a build job and extending the release/bundle steps
  • Inject version numbers into your binary (e.g. via ldflags in Go, --define in Swift, etc.)
  • Add code signing for macOS binaries using codesign after the lipo step

License

These workflows are provided under the same license as Luca. See LICENSE for details.

About

Ready-to-use GitHub Actions workflows that build, package, and publish CLI tool releases on github.com making them compatible with Luca

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors