Skip to content

Contributor Guide

Target audience: Contributors and Maintainers Goal: Learn how to contribute to StageX.

Introduction

StageX consists of packages defined as verifiable OCI container images with metadata. Each package lives in a directory under packages/{stage}/{name}/ and is defined by two files: package.toml (metadata and source download information) and Containerfile (build instructions).

Packages are divided into four stages based on their role in the bootstrap chain:

Stage Description
bootstrap Seeds from minimal tools to a usable C compiler
core Compilers, interpreters, and libraries that are part of language toolchains
pallet Language toolchains that ship all dependencies included
user Everything else — applications, CLI tools, non-toolchain libraries

Unless you are adding a compiler or a new programming language, you likely want user.

Prerequisites

  • A Codeberg account and fork of the stagex/stagex repository
  • Podman v4+ installed (or Docker v24+ with BuildKit enabled)
  • Python 3 and make
  • Familiarity with OCI container images and the TOML format
  • A signed Git commit key (PGP or SSH)

Containerfile Structure

The Containerfile defines how a package is built. It is a Dockerfile built with BuildKit that must produce bit-for-bit reproducible outputs.

Every Containerfile has two stages: build (compiles the package) and package (packages the output into an OCI image). Key conventions include starting with FROM scratch AS build, copying minimal required images from stagex/core-*, unpacking source with ADD fetch/${PACKAGE_NAME}-${VERSION}.tar.gz ., and running the build inside RUN --network=none to guarantee reproducibility.

Output is installed to DESTDIR=/rootfs and copied into the final stage with COPY --from=build /rootfs/ /. See the Add a New Package guide for detailed walkthroughs and examples.

Build Environment Variables

These variables are automatically available inside Containerfile build scripts:

Variable Value
VERSION Package version from package.toml
SRC_FILE Computed source filename with placeholders expanded
SRC_HASH Source SHA-256 hash
SRC_MIRRORS Comma-separated mirror URLs
SOURCE_DATE_EPOCH 1 (enables reproducible builds)

Language-Specific Patterns

Each language has a dedicated pallet image and a how-to guide with full Containerfile examples:

PR Submission Workflow

  1. Fork the repository and clone your fork locally
  2. Create a branch based on staging (or main for docs)
  3. Make your changes — create or update package definitions, Containerfiles, documentation, and related files
  4. Test your changes — build the package and verify reproducibility
  5. Commit with Conventional Commits format: type(scope): description (see the Style Guide for the full type/scope reference)
  6. Sign your commits — use git config commit.gpgsign true
  7. Push and open a PR — reference any related issues with Closes #<issue-number>

Packaging Standards

All software added to StageX must:

  • Be reviewed for malicious code
  • Use legitimate, auditable source URLs
  • NOT use pre-compiled binaries during the build
  • Be bit-for-bit reproducible
  • Be free of known significant vulnerabilities

Common Pitfalls

  • Missing dependency: If the build fails with "command not found", add the missing tool to the COPY --from=stagex/core-* list.
  • Unreproducible builds: Ensure SOURCE_DATE_EPOCH=1 is respected, avoid network calls during the build, and use --disable-dependency-tracking where available.
  • Wrong stage: Compilers go to core, language toolchains go to pallet, everything else goes to user.
  • Hash mismatch: Re-download the source and run sha256sum file.tar.gz to verify.

Contact

See Also