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:
- C/C++: Use
pallet-clang-gnu-busybox. See Build a C/C++ Application - Python: Use
pallet-pythonorpallet-cython. See Build a Python Application - Rust: Use
pallet-rust. See Build a Rust Application - Go: Use
pallet-goorpallet-cgo. See Build a Go Application - Node.js: Use
pallet-nodejs. See Build a Node.js Application
PR Submission Workflow
- Fork the repository and clone your fork locally
- Create a branch based on
staging(ormainfor docs) - Make your changes — create or update package definitions, Containerfiles, documentation, and related files
- Test your changes — build the package and verify reproducibility
- Commit with Conventional Commits format:
type(scope): description(see the Style Guide for the full type/scope reference) - Sign your commits — use
git config commit.gpgsign true - 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=1is respected, avoid network calls during the build, and use--disable-dependency-trackingwhere available. - Wrong stage: Compilers go to
core, language toolchains go topallet, everything else goes touser. - Hash mismatch: Re-download the source and run
sha256sum file.tar.gzto verify.
Contact
See Also
- Package.toml Format — field reference for package metadata
- Add a New Package — step-by-step add-package workflow
- Upgrade a Package — package upgrade workflow
- Build a Rust Application — Rust-specific build patterns
- Build a Python Application — Python-specific build patterns
- Build a Go Application — Go-specific build patterns