Skip to content

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

License

Notifications You must be signed in to change notification settings

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

No packages published

Contributors 2

  •  
  •