A github action template for do release/assets when push a tag. it should fitable for any shards

I push my first hello world crystal shards to github today.

the main purpose for this shard is to write a github action, to build a static version binary, automatically, when i push a tag into github, then i can download from there to use anywhere (linux only)

because i found many famous shards in github never use this automate process, so i share my action file here.

Almost just copy from our gh-actions document, with a little improvement for do release and create a tarball, it good to as a start point anyway.

There is one more question, from [document](Static Linking - Crystal]., i saw this:

With pre-installed crystal compiler, shards, and static libraries of all of stdlib's dependencies these Docker images allow to easily build static Crystal binaries even from glibc-based systems. The official Crystal compiler builds for Linux are created using these images.

so, i consider build static binary directly from normal distro (e.g. i use arch linux) is possible nowaday, right?

The context is, i installed musl packages correctly, i can build several C program binary use make like make LDFLAGS=-static CC=musl-gcc successful, i even can build some rust package e.g. famous fd successful use following command.

$: cargo build --target x86_64-unknown-linux-musl --release

But, i don’t know how to do this with Crystal, there are some discuss several years ago,
maybe it time to open a new thread for discuss this, so, in fact when i try to build on my own distro, i get following error msg:

 ╰─ $ 130  CC=musl-gcc shards build --production --release --progress --static --no-debug --link-flags="-s -Wl,-z,relro,-z,now"
Dependencies are satisfied
Building: crystal_hello_world
Error target crystal_hello_world failed to compile:
/usr/sbin/ld: cannot find -lpcre (this usually means you need to install the development package for libpcre): No such file or directory
/usr/sbin/ld: cannot find -levent (this usually means you need to install the development package for libevent): No such file or directory
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: `musl-gcc "${@}" -o /home/common/Study/Crystal/crystal_hello_world/bin/crystal_hello_world -s -Wl,-z,relro,-z,now -rdynamic -static -L/home/zw963/Crystal/bin/../lib/crystal -lpcre -lm -lgc -lpthread -levent  -lrt -lpthread -ldl`

could anyone help on how to resolve this?

Thank you.

2 Likes

I’m not intimately familiar with GitHub Actions, but if you’re building with an Alpine container, the only thing you need to do to get a static binary is add --static. This is an example of the Dockerfile I use to build Kubernetes operators, which gives me 5-6MB container images:

All I’m doing is running shards build --release --static and copying the resulting binary to an empty container image so that the container I deploy only contains the single binary.

2 Likes

All I’m doing is running shards build --release --static and copying the resulting binary to an empty container image so that the container I deploy only contains the single binary.

I guess i know what you means, it similar to docker multi-staging feature, when done build, copy the result to a refresh new container to reduce size.

What i done is similar, but different, i just build a static binary use Alpine when push a tag to github, and let user can download directly from git release page, e.g. it can build a release download link like this:

https://github.com/zw963/crystal_hello_world/releases/download/v0.0.9/crystal_hello_world-v0.0.9-x86_64-unknown-linux-musl.tar.gz

@jgaskins , BTW, It really nice to see familiar face here, i have used your clear water, though, just for play a while, do you think if there is any chance to generate Javascript use Crystal as does with Opal ?

2 Likes

Interesting approach @zw963, I’m currently using my own dev container to build these static binaries:

It uses docker run directly (exp-crystal-hello-binary/build.yml at main · luislavena/exp-crystal-hello-binary · GitHub) since I’m going to publish multi-arch container images soon (both amd64 and arm64).

Then using Docker QEMU support you can docker run --platform linux/arm64 all on the same host.

I’m also working on getting static binaries for macOS (both x86_64 and arm64), that’s a bit challenging as requires the dependencies be statically compiled as well, but not impossible:


The binary is cross-compiled using zig cc and linked against the static libraries generated previously.

(I know, using another language as toolchain, but seems I’m not the only one)

Happy to see others interested in getting the static binaries of their Crystal programs!

5 Likes

Awesome, you build your’s binary from the scratch!

Hope you can share how you build macOS binary from linux! (maybe use VirtualBox)?

And from after visit your’s repo, i learned to use a new good tool, watchexec, thank you!