-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDockerfile
More file actions
232 lines (205 loc) · 11.3 KB
/
Copy pathDockerfile
File metadata and controls
232 lines (205 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# All the tools required to run the tests, lint and coverage Bash scripts
#
# Build modes:
# 1. Extract Rust binaries: docker buildx build --target artifacts -o out .
# 2. Full image (local): docker buildx build .
# 3. Alpine image: docker buildx build --target alpine .
# 4. Full image (CI): Uses GHA cache from the build job so the Rust
# stages are cache hits — only the final assembly
# layers (tools, COPY argsh.min.sh) run fresh.
# ── Rust build stages ────────────────────────────────────────────────────
# minify — build Rust minifier
FROM rust:1-slim-trixie AS minifier-build
WORKDIR /build
COPY minifier/ .
RUN cargo build --release
# shdoc — build Rust documentation generator
FROM rust:1-slim-trixie AS shdoc-build
WORKDIR /build
COPY shdoc/ .
RUN cargo build --release
# builtin — build Rust loadable builtins
# The export_name attributes contain colons (e.g. ":args_struct"), which
# linkers reject UNQUOTED in the rustc-generated version script ("syntax
# error in VERSION script"). Older system lld accepted them, but lld >= 20
# rejects too — the plain system-lld symlink rotted when rust:1-alpine
# moved to lld 22. The shim installed over rustc's gcc-ld/ld.lld quotes
# those symbols in the script (standard version-script syntax, identical
# export semantics) and delegates to system lld — linker-version-proof.
# (-Clinker-features=-lld would be cleaner but is only stable on x86_64.)
# See: https://github.com/rust-lang/rust/issues/38238
# Build on bookworm (glibc 2.36) for maximum glibc compatibility.
FROM rust:1-slim-bookworm AS builtin-build
RUN apt-get update && apt-get install -y --no-install-recommends lld && rm -rf /var/lib/apt/lists/*
COPY .docker/ld-lld-quote-version-script.sh /usr/local/bin/ld-lld-quote-version-script
RUN chmod +x /usr/local/bin/ld-lld-quote-version-script \
&& mv /usr/bin/ld.lld /usr/bin/ld.lld-real \
&& ln -sf /usr/local/bin/ld-lld-quote-version-script /usr/bin/ld.lld \
&& ln -sf /usr/local/bin/ld-lld-quote-version-script "$(rustc --print sysroot)/lib/rustlib/$(rustc -vV | awk '/host/{print $2}')/bin/gcc-ld/ld.lld"
ARG RUSTFLAGS
ARG CARGO_PROFILE_RELEASE_STRIP
ARG CARGO_PROFILE_RELEASE_LTO
ARG CARGO_PROFILE_RELEASE_PANIC
ARG ARGSH_SO_VERSION
ARG ARGSH_SO_COMMIT
ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-fuse-ld=lld"
WORKDIR /build
COPY builtin/ .
RUN ARGSH_SO_VERSION="${ARGSH_SO_VERSION}" ARGSH_SO_COMMIT="${ARGSH_SO_COMMIT}" \
cargo build --release
# Musl build for Alpine — cdylib works with -C target-feature=-crt-static.
FROM rust:1-alpine AS builtin-build-musl
RUN apk add --no-cache lld
# Same version-script-quoting shim as the glibc build (colon symbols in
# export_name; alpine ships lld >= 20 which rejects them unquoted).
COPY .docker/ld-lld-quote-version-script.sh /usr/local/bin/ld-lld-quote-version-script
RUN chmod +x /usr/local/bin/ld-lld-quote-version-script \
&& mv /usr/bin/ld.lld /usr/bin/ld.lld-real \
&& ln -sf /usr/local/bin/ld-lld-quote-version-script /usr/bin/ld.lld \
&& ln -sf /usr/local/bin/ld-lld-quote-version-script "$(rustc --print sysroot)/lib/rustlib/$(rustc -vV | awk '/host/{print $2}')/bin/gcc-ld/ld.lld"
ARG RUSTFLAGS
ARG CARGO_PROFILE_RELEASE_STRIP
ARG CARGO_PROFILE_RELEASE_LTO
ARG CARGO_PROFILE_RELEASE_PANIC
ARG ARGSH_SO_VERSION
ARG ARGSH_SO_COMMIT
ENV RUSTFLAGS="${RUSTFLAGS} -C target-feature=-crt-static -C link-arg=-fuse-ld=lld"
WORKDIR /build
COPY builtin/ .
RUN ARGSH_SO_VERSION="${ARGSH_SO_VERSION}" ARGSH_SO_COMMIT="${ARGSH_SO_COMMIT}" \
cargo build --release
# argsh-lsp / argsh-lint — LSP server + CLI linter (share the same crate).
FROM rust:1-slim-trixie AS lsp-build
WORKDIR /build
COPY crates/ crates/
RUN cargo build --release --manifest-path crates/argsh-lsp/Cargo.toml --bins
# minifier (musl) — statically linked for Alpine
FROM rust:1-alpine AS minifier-build-musl
WORKDIR /build
COPY minifier/ .
RUN cargo build --release
# shdoc (musl) — statically linked for Alpine
FROM rust:1-alpine AS shdoc-build-musl
WORKDIR /build
COPY shdoc/ .
RUN cargo build --release
# argsh-lsp / argsh-lint / argsh-dap (musl) — statically linked for Alpine
FROM rust:1-alpine AS lsp-build-musl
WORKDIR /build
COPY crates/ crates/
RUN cargo build --release --manifest-path crates/argsh-lsp/Cargo.toml --bins
# artifacts — extract just the Rust binaries (used by CI for multi-arch release)
FROM scratch AS artifacts
COPY --from=minifier-build /build/target/release/minifier /minifier
COPY --from=shdoc-build /build/target/release/shdoc /shdoc
COPY --from=builtin-build /build/target/release/libargsh.so /libargsh.so
COPY --from=builtin-build-musl /build/target/release/libargsh.so /libargsh-musl.so
COPY --from=lsp-build /build/crates/argsh-lsp/target/release/argsh-lsp /argsh-lsp
COPY --from=lsp-build /build/crates/argsh-lsp/target/release/argsh-lint /argsh-lint
COPY --from=lsp-build /build/crates/argsh-lsp/target/release/argsh-dap /argsh-dap
COPY --from=minifier-build-musl /build/target/release/minifier /minifier-musl
COPY --from=shdoc-build-musl /build/target/release/shdoc /shdoc-musl
COPY --from=lsp-build-musl /build/crates/argsh-lsp/target/release/argsh-lsp /argsh-lsp-musl
COPY --from=lsp-build-musl /build/crates/argsh-lsp/target/release/argsh-lint /argsh-lint-musl
COPY --from=lsp-build-musl /build/crates/argsh-lsp/target/release/argsh-dap /argsh-dap-musl
# ── Final image ──────────────────────────────────────────────────────────
FROM debian:trixie-slim AS debian
# kcov — bash script coverage (binary copied from pinned kcov image;
# runtime deps installed via apt below to keep them up-to-date with the base)
COPY --from=kcov/kcov@sha256:5c61bd03d2b7f4fa74131b18e4e80356a92a7517872b5b9a505022c38cd6d123 /usr/local/bin/kcov /usr/local/bin/kcov
# test — bats-core + standard helper libraries (support, assert, file)
# Pinned to immutable commit SHAs for reproducibility.
RUN set -eux \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
git bash ca-certificates curl \
# kcov runtime dependencies
libcurl4 libdw1 libelf1 zlib1g \
# envsubst
gettext-base \
&& git init /tmp/bats \
&& git -C /tmp/bats remote add origin https://github.com/bats-core/bats-core.git \
&& git -C /tmp/bats fetch --depth 1 origin 3bca150ec86275d6d9d5a4fd7d48ab8b6c6f3d87 \
&& git -C /tmp/bats checkout FETCH_HEAD \
&& /tmp/bats/install.sh /usr/local \
&& git clone --depth 1 https://github.com/bats-core/bats-support.git /usr/local/lib/bats-support \
&& git -C /usr/local/lib/bats-support fetch --depth 1 origin 24a72e14349690bcbf7c151b9d2d1cdd32d36eb1 \
&& git -C /usr/local/lib/bats-support checkout FETCH_HEAD \
&& git clone --depth 1 https://github.com/bats-core/bats-assert.git /usr/local/lib/bats-assert \
&& git -C /usr/local/lib/bats-assert fetch --depth 1 origin f1e9280eaae8f86cbe278a687e6ba755bc802c1a \
&& git -C /usr/local/lib/bats-assert checkout FETCH_HEAD \
&& git clone --depth 1 https://github.com/bats-core/bats-file.git /usr/local/lib/bats-file \
&& git -C /usr/local/lib/bats-file fetch --depth 1 origin 13ad5e2ffcc360281432db3d43a306f7b3667d60 \
&& git -C /usr/local/lib/bats-file checkout FETCH_HEAD \
&& rm -rf /tmp/bats \
/usr/local/lib/bats-support/.git \
/usr/local/lib/bats-assert/.git \
/usr/local/lib/bats-file/.git \
&& apt-get remove -y git \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/*
# lint
COPY --from=koalaman/shellcheck:stable /bin/shellcheck /usr/local/bin/shellcheck
# tools
COPY --from=ghcr.io/jqlang/jq:1.8.1 /jq /usr/local/bin/jq
COPY --from=mikefarah/yq:4.53.2 /usr/bin/yq /usr/local/bin/yq
# argsh itself
COPY --from=minifier-build /build/target/release/minifier /usr/local/bin/minifier
COPY --from=shdoc-build /build/target/release/shdoc /usr/local/bin/shdoc
COPY --from=builtin-build /build/target/release/libargsh.so /usr/local/lib/argsh.so
COPY --from=lsp-build /build/crates/argsh-lsp/target/release/argsh-lsp /usr/local/bin/argsh-lsp
COPY --from=lsp-build /build/crates/argsh-lsp/target/release/argsh-lint /usr/local/bin/argsh-lint
COPY --from=lsp-build /build/crates/argsh-lsp/target/release/argsh-dap /usr/local/bin/argsh-dap
COPY ./argsh.min.sh /usr/local/bin/argsh
ENV ARGSH_BUILTIN_PATH=/usr/local/lib/argsh.so
ENV BATS_LIB_PATH=/usr/local/lib
ENV PATH_BASE=/workspace
# docker
COPY ./.docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT [ "docker-entrypoint.sh" ]
# ── Alpine image ─────────────────────────────────────────────────────────
# Lightweight variant with musl-linked binaries.
# Build: docker buildx build --target alpine -t argsh:alpine .
FROM alpine:3.21 AS alpine
# Runtime dependencies
RUN apk add --no-cache \
bash git curl ca-certificates gettext
# test — bats-core + standard helper libraries (same pinned SHAs as Debian)
RUN set -eux \
&& git init /tmp/bats \
&& git -C /tmp/bats remote add origin https://github.com/bats-core/bats-core.git \
&& git -C /tmp/bats fetch --depth 1 origin 3bca150ec86275d6d9d5a4fd7d48ab8b6c6f3d87 \
&& git -C /tmp/bats checkout FETCH_HEAD \
&& /tmp/bats/install.sh /usr/local \
&& git clone --depth 1 https://github.com/bats-core/bats-support.git /usr/local/lib/bats-support \
&& git -C /usr/local/lib/bats-support fetch --depth 1 origin 24a72e14349690bcbf7c151b9d2d1cdd32d36eb1 \
&& git -C /usr/local/lib/bats-support checkout FETCH_HEAD \
&& git clone --depth 1 https://github.com/bats-core/bats-assert.git /usr/local/lib/bats-assert \
&& git -C /usr/local/lib/bats-assert fetch --depth 1 origin f1e9280eaae8f86cbe278a687e6ba755bc802c1a \
&& git -C /usr/local/lib/bats-assert checkout FETCH_HEAD \
&& git clone --depth 1 https://github.com/bats-core/bats-file.git /usr/local/lib/bats-file \
&& git -C /usr/local/lib/bats-file fetch --depth 1 origin 13ad5e2ffcc360281432db3d43a306f7b3667d60 \
&& git -C /usr/local/lib/bats-file checkout FETCH_HEAD \
&& rm -rf /tmp/bats \
/usr/local/lib/bats-support/.git \
/usr/local/lib/bats-assert/.git \
/usr/local/lib/bats-file/.git
# lint
COPY --from=koalaman/shellcheck:stable /bin/shellcheck /usr/local/bin/shellcheck
# tools
COPY --from=ghcr.io/jqlang/jq:1.8.1 /jq /usr/local/bin/jq
COPY --from=mikefarah/yq:4.53.2 /usr/bin/yq /usr/local/bin/yq
# argsh itself (musl-linked binaries)
COPY --from=minifier-build-musl /build/target/release/minifier /usr/local/bin/minifier
COPY --from=shdoc-build-musl /build/target/release/shdoc /usr/local/bin/shdoc
COPY --from=builtin-build-musl /build/target/release/libargsh.so /usr/local/lib/argsh.so
COPY --from=lsp-build-musl /build/crates/argsh-lsp/target/release/argsh-lsp /usr/local/bin/argsh-lsp
COPY --from=lsp-build-musl /build/crates/argsh-lsp/target/release/argsh-lint /usr/local/bin/argsh-lint
COPY --from=lsp-build-musl /build/crates/argsh-lsp/target/release/argsh-dap /usr/local/bin/argsh-dap
COPY ./argsh.min.sh /usr/local/bin/argsh
ENV ARGSH_BUILTIN_PATH=/usr/local/lib/argsh.so
ENV BATS_LIB_PATH=/usr/local/lib
ENV PATH_BASE=/workspace
# docker
COPY ./.docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT [ "docker-entrypoint.sh" ]