Patch stack and build orchestration for NetBSD/NeoBSD targets.
This repository separates release intent (what to patch) from execution context (how and where to build).
- Target (
targets/<name>/): defines the patch stack and pinned base source state. - Profile (
profiles/<name>): shell configuration consumed byscripts/run-pipeline.sh. - Patch set (
patches/...): actual patch payload grouped by one-letter set key.
In short:
targets/answers: what are we building?profiles/answers: how are we building and publishing it?
.
|- patches/ # patch payloads
|- profiles/ # pipeline profiles (shell files)
|- targets/ # target definitions (base/commit/series)
|- scripts/ # orchestrator + specialized helpers
`- README.md
Typical target layout:
targets/neobsd-11/
|- base # e.g. netbsd-11
|- commit # pinned git commit in src repo
`- series # ordered patch entries
scripts/run-pipeline.sh resolves values in this order:
- built-in defaults
- profile file (
--profile <path>) - CLI options (highest priority)
Auto profile loading:
- If
--profileis omitted and--targetis set, auto-load expectsprofiles/<target>-<machine>-<machine-architecture>.
The pipeline uses a single ordering strategy everywhere relevant:
target -> release-id -> platform-key
Definitions:
target: release line and patch stack identity, for exampleneobsd-11.release-id: technical run/release id, for example26.2.platform-key:<machine>-<machine-architecture>, or<machine>if arch is empty.
Path formulas:
- Object tree:
<obj-root>/<target>/<release-id>/<platform-key>/ - Release payload source:
<object-tree>/releasedir/ - Published destination (
PUBLISH_MODE=copy):<publish-dir>/<target>/<release-id>/<platform-key>/ - Reusable tools (
REUSE_TOOLS=1, no explicitTOOLS_DIR):<tools-root>/<target>/<release-id>/<platform-key>/
Important design decision:
base-name(for examplenetbsd-11) is intentionally not part of the tools path.- Reason: in this model,
targetalready represents the full build identity (including applied patch stack). Keepingbase-namein the tools path can look redundant or even misleading. release-idis part of the tools path to prevent accidental cross-release reuse of toolchains.- For iterative development where you want tools reuse across multiple runs, set a stable
--release-idexplicitly.
Current profiles in this repository:
profiles/neobsd-11-amd64-x86_64profiles/neobsd-11-evbarm-earmv7
Example resolved paths for release-id=26.2:
Profile: neobsd-11-amd64-x86_64
target = neobsd-11
platform-key = amd64-x86_64
tools = /build/tools/neobsd-11/26.2/amd64-x86_64
obj = /build/obj/neobsd-11/26.2/amd64-x86_64
publish = /dist/neobsd-11/26.2/amd64-x86_64
Profile: neobsd-11-evbarm-earmv7
target = neobsd-11
platform-key = evbarm-earmv7
tools = /build/tools/neobsd-11/26.2/evbarm-earmv7
obj = /build/obj/neobsd-11/26.2/evbarm-earmv7
publish = /dist/neobsd-11/26.2/evbarm-earmv7
Operator run-pipeline.sh prepare-repos.sh apply-patches.sh build-netbsd.sh publish-artifacts.sh Filesystem
| | | | | | |
|-- run --profile ->| | | | | |
| |-- load profile --->| | | | |
| |-- resolve -------> | | | | |
| | target=neobsd-11| | | | |
| | release=26.2 | | | | |
| | platform=amd64-x86_64 | | | |
| |-- preflight obj ---------------------------------------------------------------> | |
| | /build/obj/neobsd-11/26.2/amd64-x86_64 | |
| |-- stage: prepare --->| (sync src/xsrc) | | |
| |<-- repos ready ------| | | | |
| |-- stage: apply --------------------------->| apply series | | |
| |<-- patches applied ------------------------| | | |
| |-- stage: build ------------------------------------------------->| | |
| | obj=/build/obj/neobsd-11/26.2/amd64-x86_64 | | |
| | tools=/build/tools/neobsd-11/26.2/amd64-x86_64 | | |
| |<-- releasedir ready ---------------------------------------------| | |
| |-- stage: publish --------------------------------------------------------------------->| |
| | |-- copy releasedir ----------------------->|
| | | /dist/neobsd-11/26.2/amd64-x86_64 |
| |<-- done --------------------------------------------------------------------------------------------------------------------|
Operator run-pipeline.sh prepare-repos.sh apply-patches.sh build-netbsd.sh publish-artifacts.sh Filesystem
| | | | | | |
|-- run --profile ->| | | | | |
| |-- load profile --->| | | | |
| |-- resolve -------> | | | | |
| | target=neobsd-11| | | | |
| | release=26.2 | | | | |
| | platform=evbarm-earmv7 | | | |
| |-- preflight obj ---------------------------------------------------------------> | |
| | /build/obj/neobsd-11/26.2/evbarm-earmv7 | |
| |-- stage: prepare --->| (sync src/xsrc) | | |
| |<-- repos ready ------| | | | |
| |-- stage: apply --------------------------->| apply series | | |
| |<-- patches applied ------------------------| | | |
| |-- stage: build ------------------------------------------------->| | |
| | obj=/build/obj/neobsd-11/26.2/evbarm-earmv7 | | |
| | tools=/build/tools/neobsd-11/26.2/evbarm-earmv7 | | |
| |<-- releasedir ready ---------------------------------------------| | |
| |-- stage: publish --------------------------------------------------------------------->| |
| | |-- copy releasedir ----------------------->|
| | | /dist/neobsd-11/26.2/evbarm-earmv7 |
| |<-- done --------------------------------------------------------------------------------------------------------------------|
Create:
targets/<target>/basetargets/<target>/committargets/<target>/series
Example:
targets/neobsd-11/base -> netbsd-11
targets/neobsd-11/commit -> 1e7843549f865337fc095ab555d401dcad1702d7
For a series entry like:
c/0002-cells-core
expected patch path is:
patches/c/0002-cells-core/<base>.patch
Example: profiles/neobsd-11-amd64-x86_64
TARGET="neobsd-11"
# Optional: build branding passed to netbsd build.sh
BUILD_BRAND_NAME="NeoBSD"
BUILD_ID_PREFIX="neobsd"
# Optional: identity used by git am while applying patches
GIT_COMMITTER_NAME="NeoBSD Builder"
GIT_COMMITTER_EMAIL="builder@builder.lan"
SRC_DIR="/build/netbsd-src"
XSRC_DIR="/build/netbsd-xsrc"
SRC_REPO="https://github.com/NetBSD/src.git"
XSRC_REPO="https://github.com/NetBSD/xsrc.git"
FETCH_MODE="auto" # auto|none
MACHINE="amd64"
MACHINE_ARCHITECTURE="x86_64"
BUILD_STEPS="all" # space-separated list or all
NO_X=0 # 1/0
REUSE_TOOLS=1 # 1/0
TOOLS_ROOT="/build/tools"
OBJ_ROOT="/build/obj"
PUBLISH_MODE="copy" # none|local|copy|script|rsync
PUBLISH_DIR="/dist"
# For PUBLISH_MODE="script":
# PUBLISH_SCRIPT="scripts/publish-hook-example.sh"Notes:
NO_X=0enables xsrc/X11 build flow (--with-x).NO_X=1disables xsrc/X11 build flow (--no-x).BUILD_STEPSaccepts a space-separated list ("release sourcesets"),allexpands to the default full sequence.MACHINE_ARCHITECTUREmaps tobuild.sh -a.- For
MACHINE=amd64, useMACHINE_ARCHITECTURE=x86_64. BUILD_BRAND_NAMEsetsBUILDINFOforbuild.shas<brand> <release-tag-or-id>.BUILD_ID_PREFIXsetsbuild.sh -Bas<prefix>-<release-tag-or-id>.- If
BUILD_BRAND_NAMEorBUILD_ID_PREFIXare unset, pipeline does not pass those values tobuild.sh. - If the selected object path already exists, preflight aborts unless
--cleanis set.
scripts/validate-series.sh --target neobsd-11scripts/run-pipeline.sh --profile profiles/neobsd-11-amd64-x86_64Override per run:
scripts/run-pipeline.sh \
--profile profiles/neobsd-11-amd64-x86_64 \
--release-tag 26.2 \
--clean \
--build-steps "release sourcesets" \
--jobs 24When PUBLISH_MODE="script" (or --publish-mode script) is used, the hook is executed without positional arguments. Pipeline context is passed via environment variables:
PIPELINE_SOURCE_DIR(required)PIPELINE_ARTIFACT_DIR(deprecated alias)PIPELINE_TARGET(required)PIPELINE_RELEASE_ID(required)PIPELINE_RELEASE_TAG(optional)PIPELINE_MACHINE(optional)PIPELINE_MACHINE_ARCHITECTURE(optional)PIPELINE_PLATFORM_KEY(required)PIPELINE_BASE_NAME(optional)PIPELINE_BASE_COMMIT(optional)
Example hook:
scripts/publish-hook-example.sh
release_tag: git tag label in formatYY.<sequence>(for example26.0,26.1,26.2)release_id: technical id used in output directory layout
scripts/run-pipeline.sh resolves release_tag:
- value from profile/CLI (
--release-tag), if set - otherwise exact git tag at
HEAD, if present
release_tag must match YY.<sequence>, sequence starts at 0.
If release_id is not set:
release_tagis used (if present)- otherwise
dev-<utc-timestamp>-<shortsha>
Build metadata (BUILDINFO / -B) uses release_tag when available, otherwise release_id.
Use one-letter directories under patches/:
a: base/core userland foundationsb: build system, CI, toolingc: cells/containers/runtimek: kernel, low-level drivers, hardwaren: networking stack and servicesp: packaging, release assembly, publish flows: security and hardeningu: userland utilities and admin UXx: experimentalz: local/private temporary work
scripts/validate-series.sh checks:
- entries are relative paths (no absolute paths, no
..) - no duplicate entries
- patch file exists as
<base>.patch - basename starts with
NNNN-(default) - numeric prefixes are non-decreasing (default)
Useful flags:
--check-prefix-order 0to disable ordering checks--require-prefix 0to disable prefix requirement
scripts/run-pipeline.sh: top-level orchestratorscripts/prepare-repos.sh: clone/fetch/reusesrcandxsrcscripts/apply-patches.sh: reset to base commit and apply patch stackscripts/build-netbsd.sh: wrapper around NetBSDbuild.shscripts/publish-artifacts.sh: publishobj/releasedir(none|local|copy|script|rsync)scripts/publish-hook-example.sh: example hook for script publish modescripts/validate-series.sh: validates targetseries
- logs are written to
stderr - usage text and payload output are written to
stdout