GitHub ActionsをMarketplaceに公開してみる
現在このサイトで使っているサーバが、さくらインターネットの共有サーバなのでアップロードする際にSFTPを利用することにした。パーミッションやディレクトリ設定をまとめておこないたかったのでlftpを利用することに。
あまりFTPを使うことはなさそうだが、lftpのコマンドをワークフローで呼び出す際、やりたい一連の処理をlftpコマンドとして渡せるようにしたいと思った。
こんな感じのscriptでlftpのコマンドを実行できる。
on: push
jobs:
deploy:
name: Checkout and Upload
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Upload Files
uses: pontago/lftp-deploy-action@master
with:
protocol: sftp
host: example.com
username: username
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
mv /home/user1/remote /home/user1/remote_bak
mkdir -p /home/user1/remote
mirror --verbose --reverse ./local/ /home/user1/remote/
mkdir -p /home/user1/logs
chmod 600 /home/user1/logs
ついでに誰でも使いやすいようにこのアクションをMarketplaceに公開してみた。(誰も使わなそう)
GitHub Actions Marketplaceとは
自作のアクションをみんなが手軽に使えるようにMarketplaceに登録できる。登録しなくともGitHubに公開すれば誰でも使うことはできるが、Marketplaceに登録すると見つけやすくなるらしい。
登録するにはメタデータとして、action.ymlを作成する必要がある。最低限下記を設定する必要があるらしい。
- name – アクション名
- description – アクションの説明
- branding
- v4.28.0 Feather アイコンの名前
- 背景色
white
、black
、yellow
、blue
、green
、orange
、red
、purple
、gray-dark
- inputs
- runs
runsは、JavaScriptアクション、複合アクション、Dockerコンテナから選べる。複合アクションはワークフローのstepsのような形で組めるらしい。今回は、lftpをインストールしたDockerコンテナを利用したいのでDockerを使うことにした。
inputsは、ワークフローから呼び出す際にwithで指定できるパラメータとのこと。
アクションをDockerで作る
普段使っているようにDockerfileを作成してリポジトリに置くだけでいいようだ。
lftpをインストールするだけの至ってシンプルなもの。entrypoint.shにアクションの処理を書いていく。
FROM alpine:3.15
RUN apk add --no-cache openssh-client lftp
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
アクションを実装していく
単純にlftpコマンドを呼び出すだけなので、わざわざ解説するほどでもない…。
必要な機能は、FTP、FTPS、SFTPに対応できること。SFTPを利用する際は、公開鍵認証で接続できることくらいだ。あとは、ローカルディレクトリ、アップロード先のディレクトリを指定して自動的にアップロードできる機能。そして欲しかったlftpのコマンドを流し込めるという機能。
まずは、action.ymlのinputsに受け取りたいパラメータを書いていく。
descriptionに説明、requiredは必須項目か、defaultの初期値を設定していく。ここで書いたパラメータが、entrypoint.shに対してINPUT_プレフィックスが付いて大文字になって渡ってくる。
シェルからは、$INPUT_HOSTのような形でアクセスできる。
inputs:
host:
description: "Sever Hostname or IP"
required: true
default: ""
username:
description: "Login Username"
required: true
default: ""
password:
description: "Login Password"
required: false
default: ""
単純に受け取ったscriptパラメータをlftpに渡すといった感じ。
lftp <<EOS
set cmd:fail-exit true
$INPUT_SCRIPT
bye
EOS
exit 0
exitを0以外で返すと異常終了にすることができる。実際の内容は、入力チェックや接続処理の分岐など色々あるが割愛。
https://github.com/pontago/lftp-deploy-action/blob/master/entrypoint.sh
アクションテスト用のワークフローを実装
アクションを作成する際は、前回使用したactというローカルでアクションを実行できるツールを使う。
使い方は、ワークフローをテストする際と何も変わらない。同じように.github/workflowsディレクトリにテスト用のワークフローファイルを作成して、下記のようなコマンドを実行する。
-jオプションに実行したいジョブを指定すれば、それだけテストできる。
act -b -W .github/workflows/main.yml -j 'ftp-test' --container-architecture linux/amd64 --rm
テスト方法は、ワークフロー内でDockerを使ってFTPサーバを立ち上げ、接続確認とlftpコマンドを流し込むといった感じだ。servicesでFTPサーバを立ち上げてもできそうだが、今回はrunの中に直接書いた。
今回作ったアクション用のコンテナから、FTPのコンテナに接続するためにランナーホストのIPをチェックする必要があるので、「get host ip」ステップで確認している。通常は172.17.0.1となるのでチェックするまでもないかもしれない。
環境変数「env.ACT」を確認して、actを使っている場合はローカルホストを使うようにした。
最後に「cleanup」ステップで、立ち上げたDockerコンテナを削除する。こうしないとactでテストする際の異常終了で、コンテナが起動したまま残って面倒になってしまう。
「if: always()」にすることで、前のステップで異常終了した場合でも必ず実行させることができる。
jobs:
ftp-test:
name: FTP Test
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
- name: get host ip
id: get-host-ip
if: ${{ !env.ACT }}
run: |
{
echo 'HOST<<EOF'
ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
echo EOF
} >> "$GITHUB_OUTPUT"
- name: create ftp server
id: create-ftp-server
run: |
docker run -d \
--name ftp-server \
-p "10021:21" -p 21000-21010:21000-21010 \
-e USERS="user1|pass" \
-e ADDRESS=${{ env.ACT && '127.0.0.1' || steps.get-host-ip.outputs.HOST }} \
-e MIN_PORT=21000 \
-e MAX_PORT=21010 \
--restart unless-stopped \
delfer/alpine-ftp-server
- name: ftp upload test
uses: ./
with:
debug: ${{ vars.DEBUG }}
host: ${{ env.ACT && '127.0.0.1' || steps.get-host-ip.outputs.HOST }}
port: 10021
username: user1
password: pass
protocol: ftp
timeout: 10
max_retries: 3
script: |
put README.md
ls
pwd
- name: cleanup
if: always()
run: |
docker stop ftp-server
docker rm ftp-server
https://github.com/pontago/lftp-deploy-action/blob/master/.github/workflows/main.yml
READMEを作成する
あともう一つは、READMEを作成する必要がある。どんな使い方をすればいいのか、まとめなければならない。
そこで使うのは、action-docsというツール。これを使うとaction.ymlからMarkdownを作成してくれる。HomeBrewでインストールして、READMEで挿入したい箇所に「<!– action-docs-inputs source=”action.yml” –>」のような形で埋め込んで、–update-readmeで更新するだけ。
他にはワークフローで使えるアクションもあるので、pushされた時に更新を反映させるということもできるようだ。
# インストール
brew install action-docs
# action.ymlからREADMEを更新
action-docs --update-readme
https://github.com/npalm/action-docs
Marketplaceに公開
ワークフローのテストを作成するのに一番時間がかかったが、なんとか作ることができたので、いよいよMarketplaceに公開する。
GitHubのリポジトリからリリースを作成しようとすると、Marketplaceに公開するか選択できるようになるので、リリースタグを作って公開ボタンを押すだけで無事に公開完了。
軽くGitHub Actionsをさわってみただけだが、CI/CDの世界もなかなか奥が深くて面白い。
https://github.com/marketplace/actions/ftp-deploy-action-via-lftp-ftp-sftp-ftps
「GitHub ActionsをMarketplaceに公開してみる」への1件のフィードバック