Custom Nix derivations for tools (go, python, ejson, pkl, golang-migrate, ...) consumable from
flake-parts, devenv, and other Nix-based setups.
Each derivation pins a single upstream version and ships prebuilt binaries from the official release
channel for the four supported systems: aarch64-darwin, x86_64-darwin, aarch64-linux,
x86_64-linux. The goal is reproducible, version-locked toolchains across Draftea repositories
without committing build artifacts or trusting drift in upstream channels.
| Package | Version | Source |
|---|---|---|
ejson |
1.5.4 | Shopify/ejson |
go |
1.26.4 | go.dev/dl |
go-migrate |
4.19.1 | golang-migrate/migrate |
pkl |
0.31.1 | apple/pkl |
python |
3.14.5 | astral-sh/python-build-standalone |
Add this repo as an input and reference the package you need by name.
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
draftea-pkgs.url = "github:Drafteame/nixpkgs";
draftea-pkgs.inputs.nixpkgs.follows = "nixpkgs";
};
outputs =
inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "aarch64-darwin" "x86_64-linux" ];
perSystem =
{ pkgs, system, ... }:
{
devShells.default = pkgs.mkShell {
buildInputs = [
inputs.draftea-pkgs.packages.${system}.go
inputs.draftea-pkgs.packages.${system}.pkl
inputs.draftea-pkgs.packages.${system}.ejson
];
};
};
};
}Pin to a specific tag (github:Drafteame/nixpkgs/v0.1.0) when you need reproducibility across
machines and CI.
{ inputs, pkgs, ... }:
{
packages = [
inputs.draftea-pkgs.packages.${pkgs.stdenv.hostPlatform.system}.go
inputs.draftea-pkgs.packages.${pkgs.stdenv.hostPlatform.system}.python
];
}flake.nix # flake-parts entrypoint; declares inputs and supported systems
nix/
overlays/ # nixpkgs instantiation per system (allowUnfree, etc.)
packages/ # one .nix file per derivation, wired via default.nix
checks/ # smoke-test derivations, one per package
shells/ # devShells (dev shell for working on this repo)
The flake exposes:
packages.<system>.<name>for every derivation undernix/packages.checks.<system>.<name>— one smoke-test derivation per package; see Tests below.devShells.<system>.default— Nix linters, formatters, markdown/yaml/shell checkers, and the pre-commit framework.
Each package has a corresponding smoke-test derivation under nix/checks/. Tests build only
when their assertions pass — a failed assertion fails the derivation.
# Run the whole suite (skips already-built tests, builds the rest)
nix flake check
# Run a single test
nix build .#checks.aarch64-darwin.go
nix build .#checks.aarch64-darwin.python
# Watch a test build with full logs
nix build .#checks.aarch64-darwin.pkl --print-build-logsThe tests cover, per package:
| Package | Coverage |
|---|---|
ejson |
keygen produces a 32-byte Curve25519 keypair; full encrypt/decrypt round trip |
go |
version matches pin; GOROOT resolves; go build compiles a stdlib-only program |
go-migrate |
migrate -version matches pin; migrate -help advertises the usage banner |
pkl |
pkl --version matches pin; pkl eval renders a minimal module |
python |
version matches pin; sys.version_info correct; stdlib round trip; runs a script |
When updating a derivation, also update the expectedVersion in the corresponding
nix/checks/<name>.nix so the version assertion stays in sync with the pin.
Requires Nix with flakes enabled and (recommended) direnv.
# With direnv — auto-enters the dev shell on cd into the repo
direnv allow
# Or manually
nix developEntering the dev shell installs pre-commit hooks (pre-commit and commit-msg) on first run.
# Build a single derivation locally to validate it
nix build .#go
nix build .#pkl
# Run all configured pre-commit hooks
pre-commit run --all-files
# Format every Nix file
nixpkgs-fmt nix flake.nix-
Edit the
version(andrelease, where present) innix/packages/<name>.nix. -
Refresh hashes for every platform listed under
sources/platforms. Most derivations embed a comment with the exact prefetch command. As a generic recipe:nix-prefetch-url --type sha256 <url> # If the file requires a SRI hash, convert it: nix hash convert --hash-algo sha256 --to sri <base32>
-
Update the
expectedVersioninnix/checks/<name>.nixto match. -
nix build .#<name>on at least one local platform, thennix flake checkto run the suite. -
Commit with a Conventional Commits message —
depsorbuildscope is appropriate for upstream bumps.
Two workflows live under .github/workflows/:
Runs on every pull request and validates the change end-to-end inside this repo's dev shell:
- commit-check —
cz checkagainst PR commits and the PR title. - lint —
nixpkgs-fmt,statix,deadnix,shellcheck,shfmt,yamllint,markdownlint-cli2, andgitleaks. Steps useif: always()so every linter still reports when an earlier one fails. - tests —
nix flake checkbuilds every derivation undernix/checks/, exercising the smoke tests for all packages.
Nix is installed and the store cache is restored via Draftea's
configure-nix
composite action; the tests job saves the cache after a successful run.
Runs on pushes to main. Uses backend-ci's cz-bump composite action with the re-exported
ci-deploy devshell (commitizen + git) to bump the version, write a changelog increment, and
push the tag back to main. Then softprops/action-gh-release
publishes a GitHub release and a follow-up job moves the floating v<major> tag to the new
release.
| Secret | Used by | Purpose |
|---|---|---|
ACCESS_TOKEN |
both workflows | Fetches the private backend-ci flake input over HTTPS; release checkout |
GIT_NAME |
release workflow | user.name on the bump commit |
GIT_EMAIL |
release workflow | user.email on the bump commit |
GITHUB_TOKEN is provided by GitHub Actions automatically.
- Conventional Commits via commitizen — enforced
by a
commit-msgpre-commit hook. - Nix formatting via
nixpkgs-fmt; linting viastatixanddeadnix. - Markdown lint via
markdownlint-cli2. - YAML lint via
yamllint. - Shell scripts via
shellcheckandshfmt. - Secret scanning via
gitleaks.