GitHub ActionsをMarketplaceに公開してみる

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 アイコンの名前
    • 背景色 whiteblackyellowbluegreenorangeredpurplegray-dark
  • inputs
  • runs

runsは、JavaScriptアクション、複合アクション、Dockerコンテナから選べる。複合アクションはワークフローのstepsのような形で組めるらしい。今回は、lftpをインストールしたDockerコンテナを利用したいのでDockerを使うことにした。

inputsは、ワークフローから呼び出す際にwithで指定できるパラメータとのこと。

https://docs.github.com/ja/actions/sharing-automations/creating-actions/publishing-actions-in-github-marketplace

アクションを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件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です