Skip to content

Commit 41dac11

Browse files
committed
Add Crystal 1.12.1
1 parent 77f1554 commit 41dac11

File tree

3 files changed

+301
-1
lines changed

3 files changed

+301
-1
lines changed

.github/workflows/ci.yml

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
include:
16+
- crystal_major_minor: '1.12'
17+
crystal_full: '1.12.1'
18+
target_platforms: linux/amd64,linux/arm64
19+
concurrency_group: compile-crystal
20+
1621
- crystal_major_minor: '1.11'
1722
crystal_full: '1.11.2'
1823
target_platforms: linux/amd64,linux/arm64

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION ?= 1.11
1+
VERSION ?= 1.12
22
REGISTRY ?= ghcr.io
33

44
DOCKERFILE := docker/${VERSION}/Dockerfile

docker/1.12/Dockerfile

+295
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
# syntax=docker/dockerfile:1.4
2+
3+
# ---
4+
# Stages:
5+
#
6+
# stage0: use build platform and existing compiler to cross-compile for target
7+
# stage1: link cross-compiled objects into executables on the target platform
8+
# stage2: prepare directory structure, source code and final executables
9+
# stage3: copy over artifacts and development utilities and dependencies
10+
11+
# ---
12+
# stage0: bootstrap Crystal using Alpine's build of Crystal
13+
FROM --platform=$BUILDPLATFORM alpine:3.19.1 AS stage0
14+
15+
# expose the target architecture to be used in cross-compilation
16+
ARG TARGETARCH
17+
18+
# install dependencies needed for cross-compilation of Crystal and Shards
19+
RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
20+
set -eux; \
21+
apk add \
22+
crystal \
23+
curl \
24+
g++ \
25+
git \
26+
llvm17-dev \
27+
make \
28+
shards \
29+
yaml-dev \
30+
;
31+
32+
# download and compile Crystal source for target platform
33+
RUN set -eux -o pipefail; \
34+
cd /tmp; \
35+
export \
36+
CRYSTAL_VERSION=1.12.1 \
37+
CRYSTAL_SHA256=8f464ec302696c6a60410c4234569989c10bcd5004f1563b8047c5e3e1c8ba1f \
38+
; \
39+
{ \
40+
curl --fail -Lo crystal.tar.gz https://github.com/crystal-lang/crystal/archive/refs/tags/${CRYSTAL_VERSION}.tar.gz; \
41+
echo "${CRYSTAL_SHA256} *crystal.tar.gz" | sha256sum -c - >/dev/null 2>&1; \
42+
tar -xf crystal.tar.gz; \
43+
rm crystal.tar.gz; \
44+
mv crystal-${CRYSTAL_VERSION} crystal; \
45+
}; \
46+
{ \
47+
cd /tmp/crystal; \
48+
# prepare man page
49+
gzip -9 man/crystal.1; \
50+
mkdir -p /usr/local/share/man/man1; \
51+
cp -f man/*.1.gz /usr/local/share/man/man1/; \
52+
# build Compiler for target architecture
53+
mkdir -p .build; \
54+
make crystal release=1 static=1 target=$TARGETARCH-alpine-linux-musl | tail -1 | tee .build/crystal.sh; \
55+
rm -rf src/llvm/ext/llvm_ext.o; \
56+
}
57+
58+
# download and compile Shards source for target platform
59+
RUN set -eux -o pipefail; \
60+
cd /tmp; \
61+
export \
62+
SHARDS_VERSION=0.18.0 \
63+
SHARDS_SHA256=46a830afd929280735d765e59d8c27ac9ba92eddde9647ae7d3fc85addc38cc5 \
64+
; \
65+
{ \
66+
curl --fail -Lo shards.tar.gz https://github.com/crystal-lang/shards/archive/refs/tags/v${SHARDS_VERSION}.tar.gz; \
67+
echo "${SHARDS_SHA256} *shards.tar.gz" | sha256sum -c - >/dev/null 2>&1; \
68+
tar -xf shards.tar.gz; \
69+
rm shards.tar.gz; \
70+
mv shards-${SHARDS_VERSION} shards; \
71+
}; \
72+
{ \
73+
cd /tmp/shards; \
74+
# prepare man pages
75+
gzip -9 man/shards.1 man/shard.yml.5; \
76+
mkdir -p /usr/local/share/man/man1 /usr/local/share/man/man5; \
77+
cp -f man/*.1.gz /usr/local/share/man/man1/; \
78+
cp -f man/*.5.gz /usr/local/share/man/man5/; \
79+
# build for target platform
80+
make bin/shards release=1 static=1 FLAGS="--cross-compile --target $TARGETARCH-alpine-linux-musl" | tail -1 | tee bin/shards.sh; \
81+
}
82+
83+
# ---
84+
# stage1: link compiled objects on target platform
85+
FROM alpine:3.19.1 AS stage1
86+
87+
# install dependencies needed for linking
88+
RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
89+
set -eux; \
90+
apk add \
91+
g++ \
92+
gc-dev \
93+
gcc \
94+
git \
95+
libevent-static \
96+
libxml2-static \
97+
llvm17-dev \
98+
llvm17-static \
99+
make \
100+
musl-dev \
101+
pcre-dev \
102+
pcre2-dev \
103+
yaml-static \
104+
zlib-static \
105+
zstd-static \
106+
;
107+
108+
# copy build artifacts from stage0
109+
COPY --from=stage0 /tmp/crystal/.build /tmp/crystal/.build
110+
COPY --from=stage0 /tmp/crystal/Makefile /tmp/crystal/Makefile
111+
COPY --from=stage0 /tmp/crystal/src/llvm/ext /tmp/crystal/src/llvm/ext
112+
COPY --from=stage0 /tmp/shards/bin /tmp/shards/bin
113+
114+
# link objects to final binaries
115+
RUN set -eux; \
116+
# compile LLVM extension and link the compiler
117+
{ \
118+
cd /tmp/crystal; \
119+
mkdir -p spec/; \
120+
make llvm_ext; \
121+
sh -ex .build/crystal.sh; \
122+
# smoke test
123+
.build/crystal --version; \
124+
# copy final binary
125+
mkdir -p /tmp/usr/local/bin; \
126+
cp -f .build/crystal /tmp/usr/local/bin/; \
127+
}; \
128+
# compile shards
129+
{ \
130+
cd /tmp/shards; \
131+
sh -ex bin/shards.sh; \
132+
# smoke test
133+
bin/shards --version; \
134+
# copy final binary
135+
mkdir -p /tmp/usr/local/bin; \
136+
cp -f bin/shards /tmp/usr/local/bin/; \
137+
}
138+
139+
# ---
140+
# stage2: prepare binaries and code for final image
141+
FROM alpine:3.19.1 AS stage2
142+
143+
# combine source code and final binaries from previous stages
144+
COPY --from=stage0 /tmp/crystal/src /usr/local/share/crystal/src
145+
COPY --from=stage0 /usr/local/share/man /usr/local/share/man
146+
COPY --from=stage1 /tmp/usr/local/bin /usr/local/bin
147+
148+
# ---
149+
# stage3: final image
150+
FROM alpine:3.19.1 AS stage3
151+
152+
# upgrade system and installed dependencies for security patches
153+
RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
154+
set -eux; \
155+
apk upgrade
156+
157+
# copy prepared structure from stage2
158+
COPY --from=stage2 /usr/local /usr/local
159+
160+
# install dependencies and common packages
161+
RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
162+
set -eux; \
163+
apk add \
164+
curl \
165+
gc-dev \
166+
gcc \
167+
git \
168+
libevent-static \
169+
musl-dev \
170+
openssl-dev \
171+
openssl-libs-static \
172+
pcre-dev \
173+
pcre2-dev \
174+
sqlite-static \
175+
tzdata \
176+
yaml-dev \
177+
yaml-static \
178+
zlib-dev \
179+
zlib-static \
180+
; \
181+
# smoke tests
182+
[ "$(command -v crystal)" = '/usr/local/bin/crystal' ]; \
183+
[ "$(command -v shards)" = '/usr/local/bin/shards' ]; \
184+
crystal --version; \
185+
shards --version
186+
187+
# setup non-root user (fixuid)
188+
RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
189+
--mount=type=tmpfs,target=/tmp \
190+
set -eux -o pipefail; \
191+
# create non-root user & give passwordless sudo
192+
{ \
193+
apk add sudo; \
194+
addgroup -g 1000 user; \
195+
adduser -u 1000 -G user -h /home/user -s /bin/sh -D user; \
196+
mkdir -p /etc/sudoers.d; \
197+
echo "user ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/user; \
198+
# cleanup backup copies
199+
rm /etc/group- /etc/passwd- /etc/shadow-; \
200+
}; \
201+
# Install fixuid
202+
{ \
203+
cd /tmp; \
204+
export FIXUID_VERSION=0.6.0; \
205+
case "$(arch)" in \
206+
x86_64) \
207+
export \
208+
FIXUID_ARCH=amd64 \
209+
FIXUID_SHA256=8c47f64ec4eec60e79871796ea4097ead919f7fcdedace766da9510b78c5fa14 \
210+
; \
211+
;; \
212+
aarch64) \
213+
export \
214+
FIXUID_ARCH=arm64 \
215+
FIXUID_SHA256=827e0b480c38470b5defb84343be7bb4e85b9efcbf3780ac779374e8b040a969 \
216+
; \
217+
;; \
218+
esac; \
219+
wget -q -O fixuid.tar.gz https://github.com/boxboat/fixuid/releases/download/v${FIXUID_VERSION}/fixuid-${FIXUID_VERSION}-linux-${FIXUID_ARCH}.tar.gz; \
220+
echo "${FIXUID_SHA256} *fixuid.tar.gz" | sha256sum -c - >/dev/null 2>&1; \
221+
tar -xf fixuid.tar.gz; \
222+
mv fixuid /usr/local/bin/; \
223+
chmod u+s /usr/local/bin/fixuid; \
224+
rm fixuid.tar.gz; \
225+
}; \
226+
# Generate fixuid config
227+
mkdir -p /etc/fixuid; \
228+
{ \
229+
echo "user: user"; \
230+
echo "group: user"; \
231+
} | tee /etc/fixuid/config.yml
232+
233+
# Adjust ENTRYPOINT
234+
ENTRYPOINT [ "/usr/local/bin/fixuid", "-q" ]
235+
CMD [ "/bin/sh" ]
236+
237+
# install development utilities
238+
RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
239+
--mount=type=tmpfs,target=/tmp \
240+
set -eux; \
241+
cd /tmp; \
242+
# Overmind (needs tmux)
243+
{ \
244+
export OVERMIND_VERSION=2.4.0; \
245+
case "$(arch)" in \
246+
x86_64) \
247+
export \
248+
OVERMIND_ARCH=amd64 \
249+
OVERMIND_SHA256=1f7cac289b550a71bebf4a29139e58831b39003d9831be59eed3e39a9097311c \
250+
; \
251+
;; \
252+
aarch64) \
253+
export \
254+
OVERMIND_ARCH=arm64 \
255+
OVERMIND_SHA256=94a3e8393bd718ae9ec1b6cc21740bffa52da20710eaf020a7aa679cdc926104 \
256+
; \
257+
;; \
258+
esac; \
259+
apk add \
260+
tmux \
261+
; \
262+
curl --fail -Lo overmind.gz https://github.com/DarthSim/overmind/releases/download/v${OVERMIND_VERSION}/overmind-v${OVERMIND_VERSION}-linux-${OVERMIND_ARCH}.gz; \
263+
echo "${OVERMIND_SHA256} *overmind.gz" | sha256sum -c - >/dev/null 2>&1; \
264+
gunzip overmind.gz; \
265+
chmod +x overmind; \
266+
mv overmind /usr/local/bin/; \
267+
}; \
268+
# Watchexec
269+
{ \
270+
export WATCHEXEC_VERSION=1.25.1; \
271+
case "$(arch)" in \
272+
x86_64) \
273+
export \
274+
WATCHEXEC_ARCH=x86_64 \
275+
WATCHEXEC_SHA256=f120752ae92a579d40956ebf527fba8cf8a953718b669d1e446ee072cbfd0bd5 \
276+
; \
277+
;; \
278+
aarch64) \
279+
export \
280+
WATCHEXEC_ARCH=aarch64 \
281+
WATCHEXEC_SHA256=e235f2c326122e108dc2c491252487aa596fe4894a1194f7c6dd0b6f728738bb \
282+
; \
283+
;; \
284+
esac; \
285+
curl --fail -Lo watchexec.tar.xz https://github.com/watchexec/watchexec/releases/download/v${WATCHEXEC_VERSION}/watchexec-${WATCHEXEC_VERSION}-${WATCHEXEC_ARCH}-unknown-linux-musl.tar.xz; \
286+
echo "${WATCHEXEC_SHA256} *watchexec.tar.xz" | sha256sum -c - >/dev/null 2>&1; \
287+
tar -xf watchexec.tar.xz; \
288+
mv watchexec-${WATCHEXEC_VERSION}-${WATCHEXEC_ARCH}-unknown-linux-musl/watchexec /usr/local/bin/; \
289+
rm -rf watchexec.tar.xz watchexec-${WATCHEXEC_VERSION}-${WATCHEXEC_ARCH}-unknown-linux-musl; \
290+
}; \
291+
# smoke tests
292+
[ "$(command -v overmind)" = '/usr/local/bin/overmind' ]; \
293+
[ "$(command -v watchexec)" = '/usr/local/bin/watchexec' ]; \
294+
overmind --version; \
295+
watchexec --version

0 commit comments

Comments
 (0)