I built my Crystal language tool with Github Actions and added the deb created by checkinstall to the release page...
Tags: crystal, github, deb
Published: 2022-03-08 09:18:21

## Distributing tools created in the Crystal language

People use the Crystal language for different purposes, but looking at the trends on Github, many people are creating web applications, perhaps because the Crsytal language has deep connections with the Ruby language. But I want to make command line tools with Crystal. Rust has a convenient build and package manager like Cargo, but Crystal does not.

So you must built crystal tools from source. This is a major obstacle to distributing the tool to non-Crystal users. Unlike Python or Perl, Crystal is a language that cannot be expected to be pre-installed in your computer at all. So you lose a lot of potential users here.

I want to distribute my tool as Debian package (deb).

So I wrote Github Actions that will create a deb package and add it to the release page when I push the release tag.

* Firing when a release tag is pushed, such as v0.0.0
* deb is created with a classic tool called checkinstall
* Automatically upload the deb file to the release page

https://github.com/bio-crystal/bam-filter/blob/main/.github/workflows/build.yml

```yaml
name: build

on:
  push:
    tags:
      - "v*.*.*"

jobs:
  release:
    name: Release
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ 'ubuntu-20.04' ]
    steps:
      - uses: actions/checkout@v2
      - uses: crystal-lang/install-crystal@v1
      - run: sudo apt -qy install libhts-dev checkinstall
      - run: shards install
      - run: make
      - run: sudo checkinstall
　　　　　　　　　--pkgname=bam-filter
               --pkgversion=$(echo ${{ github.ref }} | sed -e "s#refs/tags/v##g")
               --maintainer=2xijok@gmail.com
               --requires=libhts3,libc6,libpcre3,libevent-dev,libgc-dev
               --nodoc -y
      - uses: softprops/action-gh-release@v1
        with:
          files: "bam-filter*.deb"
```

* `--pkgversion=$(echo ${{ github.ref }} | sed -e "s#refs/tags/v##g")` extracts the version number from the tags.

* `--requires=libhts3,libc6,libpcre3,libevent-dev,libgc-dev` For dependencies, I installed the tools on bare Ubuntu using Docker, checked them with ldd, and added any missing dependencies.

I wrote `libevent-dev` and `libgc-dev` instead of `libevent-2.1-7` and `libgc1c2`. Why is it necessary to specify the dev package? Of course not. However, since normal packages include version numbers in their names, dependencies can easily be broken by using different environment. For example, `libgc-dev` is `libgc1c2` in Ubuntu focal, but `libgc1` in Ubuntu impish. That is why I specified the -dev package here so that it will work in both environments.

If you build `puts 0`, which seems to be one of the minimal Crystal scripts, and `ldd` it, you get something like this:

```
linux-vdso.so.1 (0x00007ffc683a7000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f181a706000)
	libevent-2.1.so.7 => /lib/x86_64-linux-gnu/libevent-2.1.so.7 (0x00007f181a6b0000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f181a696000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f181a46e000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f181a91f000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f181a469000)
```

So, I think `libevent-dev`, `libgc-dev`, `libpcre3` and `libc6` always need to be added to the dependencies. (On Ubuntu, however, `libpcre3` is pre-installed from the start.)

You might think checkinstall is not cool?

Well, maybe not. But this tool works just fine. You know "Done is better than nothing".

But If you know a better way, please let me know in the discussion 👇 

Pull requests are also welcome.

Have a nice day!