Skip to content

Commit e7ea0b5

Browse files
authored
[refactor] add cache mount to parallel compilation script (#434)
1 parent 3612db5 commit e7ea0b5

File tree

7 files changed

+44
-85
lines changed

7 files changed

+44
-85
lines changed

.github/dependabot.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ updates:
2424
- /tools/mockgen
2525
- /tools/oapi-codegen
2626
- /tools/panicparse
27-
- /tools/pkgsite
2827
- /tools/sqlc
2928
- /tools/stringer
3029
- /tools/svu

Dockerfile

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,37 @@ ARG APK_BINUTILS_VERSION=~2
1111

1212
RUN apk add --no-cache \
1313
"bash=${APK_BASH_VERSION}" \
14-
"git=${APK_GIT_VERSION}" \
15-
"make=${APK_MAKE_VERSION}" \
16-
"build-base=${APK_BUILDBASE_VERSION}" \
14+
"git=${APK_GIT_VERSION}" \
15+
"make=${APK_MAKE_VERSION}" \
16+
"build-base=${APK_BUILDBASE_VERSION}" \
1717
"gcc=${APK_GCC_VERSION}" \
1818
"binutils-gold=${APK_BINUTILS_VERSION}"
1919

2020
ARG TARGETPLATFORM
2121
ARG BUILDPLATFORM
2222

23+
ENV XDG_CACHE_HOME=/root/.cache \
24+
GOCACHE=/root/.cache/go-build \
25+
GOTMPDIR=/root/.cache/go-build-tmp
26+
ENV GOPATH=/go \
27+
GOMODCACHE=/go/pkg/mod
28+
2329
ENV PROJECT_DIR="/src/github.com/obalunenko/common-go-projects-scripts"
2430
ENV GOBIN=${PROJECT_DIR}/bin
2531

2632
RUN mkdir -p "${PROJECT_DIR}"
27-
2833
WORKDIR "${PROJECT_DIR}"
2934

3035
RUN echo "I am running on ${BUILDPLATFORM}, building for ${TARGETPLATFORM}" > ./log_build.txt
3136

32-
33-
3437
ARG TARGETOS
3538
ARG TARGETARCH
3639
RUN --mount=type=bind,source=./scripts,target=./scripts \
3740
--mount=type=bind,source=./tools,rw,target=./tools \
3841
--mount=type=bind,source=Makefile,target=Makefile \
42+
--mount=type=cache,target=/root/.cache/go-build \
43+
--mount=type=cache,target=/root/.cache/go-build-tmp \
44+
--mount=type=cache,target=/go/pkg/mod \
3945
GOOS=$TARGETOS GOARCH=$TARGETARCH make install-tools
4046

4147

@@ -53,7 +59,7 @@ ARG APK_TINI_VERSION=~0
5359
RUN apk add --no-cache \
5460
"bash=${APK_BASH_VERSION}" \
5561
"git=${APK_GIT_VERSION}" \
56-
"build-base=${APK_BUILDBASE_VERSION}" \
62+
"build-base=${APK_BUILDBASE_VERSION}" \
5763
"docker-cli=${APK_DOCKER_CLI_VERSION}" \
5864
"docker-cli-buildx=${APK_DOCKER_CLI_BUILDX_VERSION}" \
5965
"docker-cli-compose=${APK_DOCKER_CLI_COMPOSE_VERSION}" \
@@ -62,5 +68,4 @@ RUN apk add --no-cache \
6268

6369
ENV GOROOT=/usr/local/go
6470

65-
# don't place it into $GOPATH/bin because Drone mounts $GOPATH as volume
6671
COPY --from=builder /src/github.com/obalunenko/common-go-projects-scripts/bin/. /usr/bin/

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ The base image is built on top of the official image [golang:1.25.1-alpine3.22](
4343
| [mockgen](https://github.com/uber-go/mock) | v0.6.0 | GoMock is a mocking framework for the Go programming language. |
4444
| [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen) | v2.5.0 | Generate Go client and server boilerplate from OpenAPI 3 specifications |
4545
| [pp](https://github.com/maruel/panicparse/v2) | v2.5.0 | Panicparse Parses panic stack traces, densifies and deduplicates goroutines with similar stack traces. Helps debugging crashes and deadlocks in heavily parallelized processes. |
46-
| [pkgsite](https://golang.org/x/pkgsite/cmd/pkgsite) | v0.0.0-20250606033525-6805ff32e9c8 | Pkgsite extracts and generates documentation for Go programs. It runs as a web server and presents the documentation as a web page. |
4746
| [sqlc](https://github.com/sqlc-dev/sqlc) | v1.30.0 | Generate type-safe code from SQL |
4847
| [stringer](https://golang.org/x/tools/cmd/stringer) | v0.36.0 | Stringer is a tool to automate the creation of methods that satisfy the fmt.Stringer interface. |
4948
| [svu](https://github.com/caarlos0/svu) | v3.2.3 | Semantic Version Util |

scripts/install/vendored-tools.sh

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env bash
2-
# Fast parallel tools builder (docker/memory friendly)
2+
# Fast parallel tools builder (docker/memory/disk friendly)
33

44
set -Eeuo pipefail
55

@@ -15,7 +15,7 @@ if [[ ! -d "$TOOLS_DIR" ]]; then
1515
exit 2
1616
fi
1717

18-
for cmd in go xargs awk; do
18+
for cmd in go xargs awk df; do
1919
if ! command -v "$cmd" >/dev/null 2>&1; then
2020
echo "[FATAL]: required command '$cmd' not found"
2121
exit 2
@@ -29,50 +29,58 @@ if [[ -z "$BIN_DIR" ]]; then
2929
fi
3030
mkdir -p "$BIN_DIR"
3131

32-
# ---- memory-aware concurrency -----------------------------------------------
32+
# ---- ensure Go cache and tmp dirs --------------------------------------------
33+
: "${XDG_CACHE_HOME:=${HOME}/.cache}"
34+
: "${GOCACHE:=${XDG_CACHE_HOME}/go-build}"
35+
: "${GOTMPDIR:=${XDG_CACHE_HOME}/go-build-tmp}"
36+
mkdir -p "$GOCACHE" "$GOTMPDIR"
37+
export XDG_CACHE_HOME GOCACHE GOTMPDIR
38+
39+
# ---- memory-aware concurrency ------------------------------------------------
3340
detect_mem_bytes() {
34-
# cgroup v2
3541
if [[ -r /sys/fs/cgroup/memory.max ]]; then
3642
local m
3743
m="$(cat /sys/fs/cgroup/memory.max)"
38-
if [[ "$m" != "max" ]]; then
39-
echo "$m"; return
40-
fi
44+
[[ "$m" != "max" ]] && echo "$m" && return
4145
fi
42-
# cgroup v1
4346
if [[ -r /sys/fs/cgroup/memory/memory.limit_in_bytes ]]; then
4447
local m
4548
m="$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)"
46-
# large 'dummy' numbers indicate no memory limit
47-
if (( m < 1<<60 )); then
48-
echo "$m"; return
49-
fi
49+
(( m < 1<<60 )) && echo "$m" && return
5050
fi
51-
# fallback: доступная память хоста/контейнера
5251
awk '/MemAvailable:/ {print $2*1024}' /proc/meminfo
5352
}
5453

5554
CPU_CORES="$(getconf _NPROCESSORS_ONLN 2>/dev/null || nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)"
5655
MEM_BYTES="$(detect_mem_bytes || echo $((1024*1024*1024*32)))"
5756
MEM_MB=$(( MEM_BYTES / 1048576 ))
5857

59-
# Amount of memory allocated per parallel build job
60-
PER_JOB_MB="${PER_JOB_MB:-900}" # adjust if necessary (500..900)
58+
PER_JOB_MB="${PER_JOB_MB:-900}"
6159
AUTO_JOBS=$(( MEM_MB / PER_JOB_MB ))
6260
(( AUTO_JOBS < 1 )) && AUTO_JOBS=1
63-
# не больше, чем CPU
6461
(( AUTO_JOBS > CPU_CORES )) && AUTO_JOBS=$CPU_CORES
6562

66-
# The user can override JOBS from the environment
67-
JOBS="${JOBS:-$AUTO_JOBS}"
63+
# ---- disk-aware concurrency --------------------------------------------------
64+
disk_free_bytes() {
65+
df -Pk "$GOTMPDIR" | awk 'NR==2 {print $4*1024}'
66+
}
67+
TMP_BYTES="$(disk_free_bytes || echo $((1024*1024*1024)))"
68+
TMP_MB=$(( TMP_BYTES / 1048576 ))
6869

69-
# Internal parallelism of the Go compiler (default 1 to save RAM)
70+
PER_JOB_TMP_MB="${PER_JOB_TMP_MB:-1500}" # примерно 1.5 ГБ на тяжелый тул
71+
AUTO_JOBS_TMP=$(( TMP_MB / PER_JOB_TMP_MB ))
72+
(( AUTO_JOBS_TMP < 1 )) && AUTO_JOBS_TMP=1
73+
74+
(( AUTO_JOBS > AUTO_JOBS_TMP )) && AUTO_JOBS=$AUTO_JOBS_TMP
75+
76+
# ---- final job settings ------------------------------------------------------
77+
JOBS="${JOBS:-$AUTO_JOBS}"
7078
GO_BUILD_P="${GO_BUILD_P:-1}"
7179

72-
echo "[INFO]: CPU=${CPU_CORES}, Mem=${MEM_MB} MiB, PER_JOB_MB=${PER_JOB_MB}, auto-JOBS=${AUTO_JOBS}"
80+
echo "[INFO]: CPU=${CPU_CORES}, Mem=${MEM_MB} MiB, DiskFree=${TMP_MB} MiB, auto-JOBS=${AUTO_JOBS}"
7381
echo "[INFO]: Using ${JOBS} parallel jobs. go build -p ${GO_BUILD_P}. Binaries -> ${BIN_DIR}"
7482

75-
# ---- helpers ----------------------------------------------------------------
83+
# ---- helpers -----------------------------------------------------------------
7684
bin_name() {
7785
local path="$1"
7886
awk -F/ '{
@@ -88,7 +96,6 @@ build_one() {
8896

8997
(
9098
cd "$tool_dir"
91-
9299
local mod_flag="-mod=mod"
93100
[[ -d vendor ]] && mod_flag="-mod=vendor"
94101

@@ -101,10 +108,8 @@ build_one() {
101108

102109
echo "[INFO]: $(basename "$tool_dir"): building ${dep}${modver:+ (${modver})} -> ${out}"
103110

104-
# Ограничиваем внутреннюю параллельность компилятора
105111
if ! go build $mod_flag -p "${GO_BUILD_P}" -o "$out" "$dep"; then
106112
echo "[ERROR]: $(basename "$tool_dir"): build failed for ${dep}"
107-
# 255 requests xargs to terminate the remaining tasks
108113
exit 255
109114
fi
110115

@@ -115,7 +120,7 @@ build_one() {
115120
export -f build_one bin_name
116121
export BIN_DIR GO_BUILD_P
117122

118-
# ---- collect jobs (tool_dir, dep) -------------------------------------------
123+
# ---- collect jobs ------------------------------------------------------------
119124
tmp_jobs="$(mktemp)"
120125
trap 'rm -f "$tmp_jobs"' EXIT
121126

@@ -136,8 +141,6 @@ if [[ ! -s "$tmp_jobs" ]]; then
136141
fi
137142

138143
# ---- run builds in parallel --------------------------------------------------
139-
# Note: paths with spaces are not supported.
140-
cat "$tmp_jobs" \
141-
| xargs -r -n 2 -P "$JOBS" bash -c 'build_one "$1" "$2"' _
144+
cat "$tmp_jobs" | xargs -r -n 2 -P "$JOBS" bash -c 'build_one "$1" "$2"' _
142145

143146
echo "[SUCCESS]: All tools built."

tools/pkgsite/go.mod

Lines changed: 0 additions & 16 deletions
This file was deleted.

tools/pkgsite/go.sum

Lines changed: 0 additions & 24 deletions
This file was deleted.

tools/pkgsite/tools.go

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)