Pin container toolchains for local module builds

This commit is contained in:
ms2k 2026-10-20 11:04:47 +09:00
commit 28494403f2
5 changed files with 108 additions and 5 deletions

2
.dockerignore Normal file
View file

@ -0,0 +1,2 @@
**
!Containerfile

1
.gitignore vendored
View file

@ -4,3 +4,4 @@
/.idea/
*.iml
/docs/journal
**/bin/

16
Containerfile Normal file
View file

@ -0,0 +1,16 @@
# NeoForm requires Java 21 for Minecraft decompilation; mod compilation uses Java 25.
FROM docker.io/library/eclipse-temurin:21.0.12.1_1-jdk-jammy@sha256:742daacb9316be4b6fc60258f6e4ac2a11882f6c597373c92290a57bfad0d2e0 AS decompiler
FROM ghcr.io/graalvm/jdk-community:25.0.2@sha256:a3bdba6a313cddc89f7e1b2649140e898c68ba356994a9c317b96b01bcb9f982
ADD --checksum=sha256:a17ddd85a26b6a7f5ddb71ff8b05fc5104c0202c6e64782429790c933686c806 https://services.gradle.org/distributions/gradle-9.1.0-bin.zip /tmp/gradle.zip
RUN cd /opt \
&& "$JAVA_HOME/bin/jar" --extract --file /tmp/gradle.zip \
&& chmod +x /opt/gradle-9.1.0/bin/gradle \
&& rm /tmp/gradle.zip
COPY --from=decompiler /opt/java/openjdk /opt/java/21
RUN ln -s "$JAVA_HOME" /opt/java/25
ENV GRADLE_USER_HOME=/cache/gradle
WORKDIR /workspace
ENTRYPOINT ["/opt/gradle-9.1.0/bin/gradle", "--no-daemon", "--console=plain", "-Porg.gradle.java.installations.paths=/opt/java/25,/opt/java/21", "-Porg.gradle.java.installations.auto-detect=false", "-Porg.gradle.java.installations.auto-download=false"]
CMD ["help"]

View file

@ -2,11 +2,13 @@
Small modmods for personal modded Minecraft server and client tuning.
Targets Minecraft 1.21.1 on GraalVM CE 25. Local builds require JDK 25 and Gradle 9.1.0.
Targets Minecraft 1.21.1 on GraalVM CE 25. Local builds prefer a rootless container engine; [Containerfile](Containerfile) pins both JDKs and Gradle.
```sh
gradle --no-daemon :server:format :server:build
gradle --no-daemon :client:format :client:build
```
| Module | Purpose | Local build |
| --------- | ----------------------------------------- | ------------------- |
| `server/` | Inventory, crafting and NBT optimizations | `./build.sh server` |
| `client/` | Create rendering and collision queries | `./build.sh client` |
Requires Podman, nerdctl or Docker. JARs are written to `<module>/build/libs/`.
[License](LICENSE.md) · [Third-party notices](NOTICE.md)

82
build.sh Executable file
View file

@ -0,0 +1,82 @@
#!/usr/bin/env bash
set -euo pipefail
usage() {
printf 'Usage: %s {client|server} [Gradle arguments...]\n' "$0"
}
case "${1:-}" in
client | server) module=$1; shift ;;
-h | --help) usage; exit 0 ;;
*) usage >&2; exit 2 ;;
esac
engine_mode() {
local state
case "$1" in
podman)
state=$("$1" info --format '{{.Host.Security.Rootless}}') || return
[[ $state == true ]] && printf rootless || printf rootful
;;
docker | nerdctl)
state=$("$1" info --format '{{json .SecurityOptions}}') || return
[[ $state == *'"name=rootless"'* ]] && printf rootless || printf rootful
;;
esac
}
engine=${CONTAINER_ENGINE:-}
if [[ -n $engine ]]; then
case "$engine" in
podman | nerdctl | docker) ;;
*) printf 'Unsupported container engine: %s\n' "$engine" >&2; exit 2 ;;
esac
kind=$(engine_mode "$engine")
else
fallback=
for candidate in podman nerdctl docker; do
command -v "$candidate" >/dev/null || continue
kind=$(engine_mode "$candidate" 2>/dev/null) || continue
if [[ $kind == rootless ]]; then
engine=$candidate
break
fi
[[ -n $fallback ]] || fallback=$candidate
done
if [[ -z $engine ]]; then
engine=$fallback
kind=rootful
fi
fi
if [[ -z $engine ]]; then
printf 'No working Podman, nerdctl or Docker engine found.\n' >&2
exit 1
fi
printf 'Building %s with %s (%s)\n' "$module" "$engine" "$kind" >&2
repo=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
cache="${XDG_CACHE_HOME:-$HOME/.cache}/saltatory/gradle"
mkdir -p -- "$cache"
image_file=$(mktemp)
trap 'rm -f -- "$image_file"' EXIT
build=(build --quiet --iidfile "$image_file" --tag localhost/saltatory-build --file "$repo/Containerfile")
[[ $engine != podman ]] || build+=(--layers)
"$engine" "${build[@]}" "$repo" >/dev/null
image=$(<"$image_file")
rm -- "$image_file"
trap - EXIT
user=(--user "$(id -u):$(id -g)")
if [[ $kind == rootless ]]; then
case "$engine" in
podman) user=(--userns keep-id "${user[@]}") ;;
docker | nerdctl) user=(--user 0:0) ;;
esac
fi
exec "$engine" run --rm --init \
--label saltatory.build=true \
"${user[@]}" \
--cap-drop ALL --security-opt no-new-privileges \
--mount "type=bind,src=$repo,dst=/workspace" \
--mount "type=bind,src=$cache,dst=/cache/gradle" \
"$image" ":$module:build" "$@"