11 KiB
name, description
| name | description |
|---|---|
| flox-publish | Use for publishing user packages to flox for use in Flox environments. Use for package distribution and sharing of builds defined in a flox environment. |
Flox Package Publishing Guide
Core Commands
flox publish # Publish all packages
flox publish my_package # Publish single package
flox publish -o myorg package # Publish to organization
flox publish -o myuser package # Publish to personal namespace
flox auth login # Authenticate before publishing
Publishing Workflow: Development to Runtime
Publishing packages enables a clear separation between development and runtime/consumption:
The Complete Workflow
Phase 1: Development Environment
# .flox/env/manifest.toml (in git with source code)
[install]
gcc.pkg-path = "gcc13"
make.pkg-path = "make"
python.pkg-path = "python311Full"
[build.myapp]
command = '''
python setup.py build
mkdir -p $out/bin
cp build/myapp $out/bin/
'''
version = "1.0.0"
Developers work in this environment, commit .flox/ to git alongside source code.
Phase 2: Build and Publish
# Build the package
flox build myapp
# Publish to catalog
flox publish -o myorg myapp
The published package contains BINARIES/ARTIFACTS (what's in $out/), NOT source code.
Phase 3: Runtime Environment
# Separate environment (can be pushed to FloxHub)
[install]
myapp.pkg-path = "myorg/myapp" # The published package
Consumers create runtime environments and install the published package. No build tools needed, no source code exposed.
Key insight: You don't install the published package back into the development environment - that would be circular. Published packages are installed into OTHER environments (different projects, production, etc.).
Publishing to Flox Catalog
Prerequisites
Before publishing:
- Package defined in
[build]section or.flox/pkgs/ - Environment in Git repo with configured remote
- Clean working tree (no uncommitted changes)
- Current commit pushed to remote
- All build files tracked by Git
- At least one package installed in
[install]
Authentication
Run authentication before first publish:
flox auth login
Publishing Commands
# Publish single package
flox publish my_package
# Publish all packages
flox publish
# Publish to organization
flox publish -o myorg my_package
# Publish to personal namespace (for testing)
flox publish -o mypersonalhandle my_package
Catalog Types
Personal catalogs: Only visible to you (good for testing)
- Published to your personal namespace
- Example: User "alice" publishes "hello" → available as
alice/hello - Useful for testing before publishing to organization
Organization catalogs: Shared with team members (paid feature)
- Published to organization namespace
- Example: Org "acme" publishes "tool" → available as
acme/tool - All organization members can install
Build Validation
Flox clones your repo to a temp location and performs a clean build to ensure reproducibility. Only packages that build successfully in this clean environment can be published.
This validation ensures:
- All dependencies are declared
- Build is reproducible
- No reliance on local machine state
- Git repository is clean and up-to-date
After Publishing
- Package available in
flox search,flox show,flox install - Metadata sent to Flox servers
- Package binaries uploaded to Catalog Store
- Install with:
flox install <catalog>/<package>
Users can then:
# Search for your package
flox search my_package
# See package details
flox show myorg/my_package
# Install the package
flox install myorg/my_package
What Gets Published
Published packages contain:
- Binaries and compiled artifacts (everything in
$out/) - Runtime dependencies specified in
runtime-packages - Package metadata (version, description)
Published packages do NOT contain:
- Source code (unless explicitly copied to
$out/) - Build tools or build-time dependencies
- Development environment configuration
- The
.flox/directory itself
This separation allows you to share built artifacts without exposing source code.
Real-world Publishing Workflows
Application Development Workflow
Developer workflow:
-
Create development environment with build tools:
mkdir myapp && cd myapp flox init flox install gcc make python311Full -
Add source code and build definition to
.flox/env/manifest.toml:[build.myapp] command = '''make && cp myapp $out/bin/''' version = "1.0.0" -
Commit to git (environment definition + source code):
git add .flox/ src/ git commit -m "Add development environment and source" git push origin main -
Build and publish package (binaries/artifacts):
flox build myapp flox publish -o myorg myapp
Other developers:
- Clone repo:
git clone <repo> && cd myapp && flox activate - Get the same development environment with build tools
Consumers:
- Create new runtime environment:
flox init && flox install myorg/myapp - OR install into existing environment:
flox install myorg/myapp - Get the BUILT package (binaries), not source code
- Can push runtime environment to FloxHub without exposing source
Fork-based Development Pattern
- Fork upstream repo (e.g.,
user/projectfromupstream/project) - Add
.flox/to fork with build definitions - Commit and push:
git push origin main - Publish package:
flox publish -o username package-name - Others can install:
flox install username/package-name
Versioning Strategies
Semantic Versioning
[build.mytool]
version = "1.2.3" # Major.Minor.Patch
description = "My awesome tool"
Git-based Versioning
[build.mytool]
version.command = "git describe --tags"
description = "My awesome tool"
File-based Versioning
[build.mytool]
version.file = "VERSION.txt"
description = "My awesome tool"
Dynamic Versioning from Source
[build.rustapp]
version.command = "cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version'"
Publishing Multiple Variants
You can publish multiple variants of the same project:
[build.myapp]
command = '''
cargo build --release
mkdir -p $out/bin
cp target/release/myapp $out/bin/
'''
version = "1.0.0"
description = "Production build"
sandbox = "pure"
[build.myapp-debug]
command = '''
cargo build
mkdir -p $out/bin
cp target/debug/myapp $out/bin/myapp-debug
'''
version = "1.0.0"
description = "Debug build with symbols"
sandbox = "off"
Both can be published and users can choose which to install.
Testing Before Publishing
Local Testing
- Build the package:
flox build myapp
- Test the built artifact:
./result-myapp/bin/myapp --version
- Install locally to test:
flox install ./result-myapp
Personal Catalog Testing
Publish to your personal namespace first:
flox publish -o myusername myapp
Then test installation:
flox install myusername/myapp
Once validated, republish to organization:
flox publish -o myorg myapp
Common Gotchas
Branch names
Many repos use master not main - check with git branch
Auth required
Run flox auth login before first publish
Clean git state
Commit and push ALL changes before flox publish:
git status # Check for uncommitted changes
git add .flox/
git commit -m "Add flox build configuration"
git push origin master
runtime-packages
List only what package needs at runtime, not build deps:
[install]
gcc.pkg-path = "gcc"
make.pkg-path = "make"
[build.myapp]
command = '''make && cp myapp $out/bin/'''
runtime-packages = [] # No runtime deps needed
Git-tracked files only
All files referenced in build must be tracked:
git add .flox/pkgs/*
git add src/
git commit -m "Add build files"
Publishing Nix Expression Builds
For Nix expression builds in .flox/pkgs/:
- Create the Nix expression:
mkdir -p .flox/pkgs
cat > .flox/pkgs/hello.nix << 'EOF'
{ hello }:
hello.overrideAttrs (oldAttrs: {
patches = (oldAttrs.patches or []) ++ [ ./my.patch ];
})
EOF
- Track with Git:
git add .flox/pkgs/*
git commit -m "Add hello package"
git push
- Publish:
flox publish hello
Publishing Configuration and Assets
You can publish non-code artifacts:
Configuration templates
[build.nginx-config]
command = '''
mkdir -p $out/etc
cp nginx.conf $out/etc/
cp -r conf.d $out/etc/
'''
version = "1.0.0"
description = "Organization Nginx configuration"
Protocol buffers
[build.api-proto]
command = '''
mkdir -p $out/share/proto
cp proto/**/*.proto $out/share/proto/
'''
version = "2.1.0"
description = "API protocol definitions"
Teams install and reference via $FLOX_ENV/etc/ or $FLOX_ENV/share/.
Continuous Integration Publishing
GitHub Actions Example
name: Publish to Flox
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Flox
run: |
curl -fsSL https://downloads.flox.dev/by-env/stable/install | bash
- name: Authenticate
env:
FLOX_AUTH_TOKEN: ${{ secrets.FLOX_AUTH_TOKEN }}
run: flox auth login --token "$FLOX_AUTH_TOKEN"
- name: Publish package
run: flox publish -o myorg mypackage
GitLab CI Example
publish:
stage: deploy
only:
- tags
script:
- curl -fsSL https://downloads.flox.dev/by-env/stable/install | bash
- flox auth login --token "$FLOX_AUTH_TOKEN"
- flox publish -o myorg mypackage
Package Metadata Best Practices
Good Descriptions
[build.cli]
description = "High-performance log shipper with filtering" # Good: specific, descriptive
# Avoid:
# description = "My tool" # Too vague
# description = "CLI" # Not descriptive enough
Proper Versioning
- Use semantic versioning: MAJOR.MINOR.PATCH
- Increment MAJOR for breaking changes
- Increment MINOR for new features
- Increment PATCH for bug fixes
Runtime Dependencies
Only include what's actually needed at runtime:
[install]
# Build-time only
gcc.pkg-path = "gcc"
make.pkg-path = "make"
# Runtime dependency
libssl.pkg-path = "openssl"
[build.myapp]
runtime-packages = ["libssl"] # Only runtime deps
Related Skills
- flox-builds - Building packages before publishing, dual-environment workflow
- flox-environments - Setting up development and runtime environments
- flox-sharing - Sharing environment definitions (via git or FloxHub) vs publishing packages (binaries/artifacts)