- debianパッケージを作るGitHubActionsとrpmパッケージを作るGitHubActionsを作った
- 使い方と仕組みを説明します
なぜ作ろうと思ったか
GitHub Actionsからサクッとdebパッケージやrpmパッケージを作成してアップロードしたかったからです。
debパッケージもrpmパッケージも、作成するのに専用のツールが必要で、環境を整えるのが若干手間だと感じていました。
それならGitHubActionsのDockerベースアクションを使えば、CI環境を汚さずパッケージを作成できるのでは、と考えました。
既存のdebパッケージやrpmパッケージを作成するためのActionsも探していろいろ試した。
しかし直感的にわかりやすく使えるものが見つからなくて、仕方なく自分で作ることにしました。
debパッケージやrpmパッケージを作成するのは初めてだったので、いろんな記事を参考にしました。
debパッケージ作成に際しては以下を参考にしました。
また、rpmパッケージ作成に際しては以下の記事を参考にしました。
ソースコード
ソースコードは以下。
Marketにも公開しています。
- https://github.com/marketplace/actions/build-deb-action
- https://github.com/marketplace/actions/build-rpm-action
使い方
前述のMarketのREADMEにも書いているのですが、以下のように使います。
build-deb-action
name: build
on:
push:
tags:
- 'v*.*.*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: create sample script
run: |
mkdir -p .debpkg/usr/bin
mkdir -p .debpkg/usr/lib/samplescript
echo -e "echo sample" > .debpkg/usr/bin/samplescript
chmod +x .debpkg/usr/bin/samplescript
echo -e "a=1" > .debpkg/usr/lib/samplescript/samplescript.conf
- uses: jiro4989/build-deb-action@v2
with:
package: samplescript
package_root: .debpkg
maintainer: your_name
version: ${{ github.ref }} # refs/tags/v*.*.*
arch: 'amd64'
desc: 'this is sample package.'
build-rpm-action
name: build
on:
push:
tags:
- 'v*.*.*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: create sample script
run: |
mkdir -p .rpmpkg/usr/bin
mkdir -p .rpmpkg/usr/lib/testbin
echo -e "echo hello" > .rpmpkg/usr/bin/testbin
echo -e "echo hello2" > .rpmpkg/usr/bin/testbin2
echo -e "a=1" > .rpmpkg/usr/lib/testbin/testbin.conf
chmod +x .rpmpkg/usr/bin/*
- uses: jiro4989/build-rpm-action@v2
with:
summary: 'testbin is a test script'
package: testbin
package_root: .rpmpkg
maintainer: jiro4989
version: ${{ github.ref }} # refs/tags/v*.*.*
arch: 'x86_64'
desc: 'test package'
どちらも同じような使い方をします。
package_root
変数に指定のディレクトリ配下に、配置したコマンド、設定ファイルをインストール時に同じ場所に配置するようにdebファイル、rpmファイルを作ります。
どういうことか、というと
<package_root>/usr/bin/samplescript
ディレクトリにスクリプトを配置してbuild-deb-actionを実行してdebファイルを作ると、dpkg -i
でインストールした時samplescript
ファイルは/usr/bin
ディレクトリにインストールされます。
仕組み
パッケージ情報の埋め込み
どちらもActionsの入力変数 (input)にパッケージ情報と、パッケージに含めるファイルのパスを指定します。
渡されたinput変数は、build-deb-actionもbuild-rpm-actionも、それぞれのパッケージに必須のパッケージ情報を記述するファイルに埋め込まれます。
debパッケージでは DEBIAN/control
ファイルに、rpmパッケージではspecファイルに埋め込まれます。
Actionsではユーザ入力を埋め込むためのテンプレートファイルを保持しており、ユーザ入力でテンプレートを置換します。
ユーザ入力を埋め込んだ後、所定のパスに配置し、パッケージを作成するコマンドを実行して各種パッケージを作成しています。
置換処理にはなんとなくNimを使いました。正直Nimである必要はなかったです。コンパイラのインストールに時間がかかるので、そのうちもっと早く処理が終わる何かに置き換えるかもしれません。
置換処理には何使っても良かったのですがsed
は使えません。ユーザ入力をsed
の置換式に使うと、sed
のセパレータ文字がユーザ入力に含まれていた時に式不正でエラーになるからです。
INPUT=1/3
echo test | sed "s/test/$INPUT/g" # エラーになる
バージョン番号処理
バージョン番号はGitHubのrefを使う前提にしています。
以下の処理でバージョン番号を加工しています。
INPUT_VERSION="$(echo "$INPUT_VERSION" | sed -E "s,^refs/tags/,,")"
前述の通り、どちらのワークフローもActionsの起動トリガーにon.push.tags
を指定しています。
この時github.ref
はrefs/tags/
で始まり、その後にgit tag
で設定したタグ名が続きます。
この入力を受取る前提で実装しています。
欠点
欠点としては、かなり単純なdebパッケージ、rpmパッケージしか作れない点です。
debパッケージもrpmパッケージも、インストール処理の前後にスクリプトを呼び出したりできるのですが、そこは特にサポートしていません。
「とにかく簡単なインタフェースで、コマンド、設定ファイルを所定の場所に配置できれば良い」としています。
一応こちらのissuesの通り、Actionsの作りを知っていればpostinstしたりできます。
https://github.com/jiro4989/build-deb-action/issues/20
が、推奨はしていないです。Actionsの作りを知っていないとできないやり方ですし。
感想
サクッと作れるようになって満足です。
すでにいくつかの自分のリポジトリでも導入しており、自作のツールの公開に大いに役立てています。
- https://github.com/jiro4989/nimjson
- https://github.com/jiro4989/textimg
- https://github.com/jiro4989/relma
まとめ
以下の内容について書きました。
- debianパッケージを作るGitHubActionsのbuild-deb-actionの説明をしました
- rpmパッケージを作るGitHubActionsのbuild-rpm-actionの説明をしました
- どちらもディレクトリ構造を配布先に合わせるだけです
自作ツール公開の一助となれば幸いです。