From ebfed37ab121635e0b93e87ed5d365222c9aff05 Mon Sep 17 00:00:00 2001 From: Igor Somov Date: Fri, 29 May 2026 10:18:55 -0300 Subject: [PATCH 1/4] v2026.5.29 --- RELEASING.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ build.zig.zon | 2 +- 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 RELEASING.md diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..8e07690 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,61 @@ +# Releasing + +NullWatch uses [CalVer](https://calver.org/) with the format `YYYY.M.D` (for example, `v2026.5.29`). + +Pushing a tag matching `v*` triggers the [Release workflow](.github/workflows/release.yml), which calls the shared `nullclaw/nullbuilder` Zig release workflow. It builds binaries for supported platforms and publishes a GitHub Release. + +## Steps + +1. **Checkout and update `main`** + + ```bash + git checkout main + git pull origin main + ``` + +2. **Create a release branch** + + ```bash + git checkout -b release/vYYYY.M.D + ``` + +3. **Bump the version in `build.zig.zon`** + + Update the `.version` field to match today's date: + + ```diff + - .version = "2026.3.16", + + .version = "2026.5.29", + ``` + +4. **Commit the version bump** + + ```bash + git add build.zig.zon + git commit -m "vYYYY.M.D" + ``` + +5. **Push the branch and create a PR** + + ```bash + git push origin release/vYYYY.M.D + gh pr create --title "vYYYY.M.D" --body "Version bump for vYYYY.M.D release." + ``` + +6. **Merge the PR** or get it reviewed and merged. + +7. **Tag the release on `main`** + + ```bash + git checkout main + git pull origin main + git tag vYYYY.M.D + git push origin vYYYY.M.D + ``` + + The tag push triggers the release build and GitHub Release publishing. + +## Notes + +- Pull requests to `main` run the CI workflow through `nullclaw/nullbuilder`. +- If multiple releases happen on the same day, append a patch number, for example `v2026.5.29.1`. diff --git a/build.zig.zon b/build.zig.zon index 65485c3..d853a91 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,6 +1,6 @@ .{ .name = .nullwatch, - .version = "2026.3.16", + .version = "2026.5.29", .fingerprint = 0x331185e774b4ae7a, .minimum_zig_version = "0.16.0", .paths = .{ From 3773af21887c87fb70d93fafa092fd99aae85aa1 Mon Sep 17 00:00:00 2001 From: Igor Somov Date: Fri, 29 May 2026 10:44:07 -0300 Subject: [PATCH 2/4] fix release workflow permissions --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a5fd1ca..332dd04 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,6 +13,7 @@ jobs: uses: nullclaw/nullbuilder/.github/workflows/zig-release.yml@v1 permissions: contents: write + packages: write secrets: inherit with: binary_name: nullwatch From 57098a42e6782af6ee32cd5e9da7eb6cd390b103 Mon Sep 17 00:00:00 2001 From: Igor Somov Date: Fri, 29 May 2026 11:07:22 -0300 Subject: [PATCH 3/4] publish release docker image --- .github/workflows/release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 332dd04..ddcfbf7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,8 @@ on: workflow_dispatch: permissions: - contents: read + contents: write + packages: write jobs: release: @@ -34,3 +35,4 @@ jobs: .git .zig-cache zig-out + publish_docker: true From 769e1b0ded3602a1fbd1b7a4a26c4955d1e9633d Mon Sep 17 00:00:00 2001 From: Igor Somov Date: Fri, 29 May 2026 11:17:07 -0300 Subject: [PATCH 4/4] add release Docker image --- .dockerignore | 3 +++ Dockerfile | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a3923d7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.git +.zig-cache +zig-out diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..dbf82e3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,65 @@ +# syntax=docker/dockerfile:1 + +# -- Stage 1: Build --------------------------------------------------------- +FROM --platform=$BUILDPLATFORM alpine:3.23 AS builder + +ARG ZIG_VERSION=0.16.0 +ARG VERSION=dev + +RUN apk add --no-cache curl musl-dev xz +RUN set -eu; \ + case "$(uname -m)" in \ + x86_64) zig_pkg="zig-x86_64-linux-${ZIG_VERSION}.tar.xz" ;; \ + aarch64|arm64) zig_pkg="zig-aarch64-linux-${ZIG_VERSION}.tar.xz" ;; \ + *) echo "Unsupported build arch: $(uname -m)" >&2; exit 1 ;; \ + esac; \ + curl -fL "https://ziglang.org/download/${ZIG_VERSION}/${zig_pkg}" -o /tmp/zig.tar.xz; \ + mkdir -p /opt/zig; \ + tar -xJf /tmp/zig.tar.xz -C /opt/zig --strip-components=1; \ + ln -s /opt/zig/zig /usr/local/bin/zig; \ + rm -f /tmp/zig.tar.xz + +WORKDIR /app +COPY build.zig build.zig.zon ./ +COPY src/ src/ + +ARG TARGETARCH +RUN --mount=type=cache,target=/root/.cache/zig \ + --mount=type=cache,target=/app/.zig-cache \ + set -eu; \ + arch="${TARGETARCH:-}"; \ + if [ -z "${arch}" ]; then \ + case "$(uname -m)" in \ + x86_64) arch="amd64" ;; \ + aarch64|arm64) arch="arm64" ;; \ + *) echo "Unsupported host arch: $(uname -m)" >&2; exit 1 ;; \ + esac; \ + fi; \ + case "${arch}" in \ + amd64) zig_target="x86_64-linux-musl" ;; \ + arm64) zig_target="aarch64-linux-musl" ;; \ + *) echo "Unsupported TARGETARCH: ${arch}" >&2; exit 1 ;; \ + esac; \ + zig build -Dtarget="${zig_target}" -Doptimize=ReleaseSmall -Dversion="${VERSION}" + +# -- Stage 2: Runtime ------------------------------------------------------- +FROM alpine:3.23 AS release-base + +LABEL org.opencontainers.image.source=https://github.com/nullclaw/nullwatch + +RUN apk add --no-cache ca-certificates tzdata +RUN mkdir -p /nullwatch-data/data && chown -R 65534:65534 /nullwatch-data + +COPY --from=builder /app/zig-out/bin/nullwatch /usr/local/bin/nullwatch + +ENV NULLWATCH_HOME=/nullwatch-data +WORKDIR /nullwatch-data +EXPOSE 7710 +ENTRYPOINT ["nullwatch"] +CMD ["serve", "--host", "0.0.0.0", "--port", "7710", "--data-dir", "/nullwatch-data/data"] + +FROM release-base AS release-root +USER 0:0 + +FROM release-base AS release +USER 65534:65534