GitHub ActionsでXServerに自動デプロイする

　[以前の投稿](https://qiita.com/ryotaro-fukushima/items/a0e5259960ce39e4bbaa)ではssh接続を利用してXServerに接続していましたが、今回はGitHub ActionsでXServerに自動デプロイを実現させます。
　サイト制作の終盤で先輩がこの機能を実装させていたので、それを研修用のリポジトリでも再現することをゴールにします。
 
:::note
この記事は自身の学習記録です。
:::

# CI CDとは
　GitHub Actionsを利用する上で大事な概念として、CI（継続的インテグレーション）とCD（継続的デリバリー）があります。
  　初めて聞く概念だったので、よく使っている検索特化型AI（perplexity)に聞いてみました。（最近私の会社ではAIの利用を推進しているので、積極的に使うようにしています。）
   　その結果がこちらです。
   ![スクリーンショット 2025-02-03 17.13.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882527/d93b65fd-0799-6df7-bfa3-366f5076997d.png)
　一言で言うと、今まで手動で行なってきたことを自動化してくれるので、効率の良い開発ができるようになるというと言うことでしょうか:thinking:勉強の余地がありそうです。
# github actionsの設定
　以下に、手順を紹介します。（ここの内容は、先輩のコードを参考に、わからないところはChatGPTに聞きながら行いました。）
 1. Actions> set up a workflow yourself を選択
 2. コードを記述
ymlファイルにコードを記述します。
コードの全容
![スクリーンショット 2025-02-03 17.47.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882527/84c9d91c-e15a-f1c2-4788-396b798f5707.png)

以下コードの解説です。
```yml:ci.yml
name: Release to Develop Environment  # ワークフローの名前
on:
  push:
    branches:
      - main  # mainブランチに変更がプッシュされたときに実行
```
:point_up_2:ワークフローの名前（開発環境へのデプロイ）と実行のタイミングの記述
```yml:ci.yml
permissions:
  contents: read
  deployments: write
```
:point_up_2:権限設定
- contents: read → リポジトリの中身を読む権限（コードを取得できる）
- deployments: write → デプロイに関する書き込み権限（デプロイ情報を記録できる）
```yml:ci.yml
jobs:
  deploy:
    name: Deploy to Xserver
    runs-on: ubuntu-latest # 実行環境
```
:point_up_2:デプロイ処理の本体を定義＆rsync などのコマンドが使いやすい Linux（Ubuntu） を仮想マシンとして定義
```yml:ci.yml
    steps:
      - name: Checkout code
        uses: actions/checkout@v3  # GitHubリポジトリのコードをクローン
```
:point_up_2:GitHub リポジトリのコードを取得
```yml:ci.yml
      - name: "Debug: Check working directory" # 現在のディレクトリ確認
        run: |
          echo "Current Directory:"
          pwd
          echo "Directory Contents:"
          ls -la
```
:point_up_2:デバッグ用（現在のディレクトリの確認）
```yml:ci.yml
      - name: Set up SSH agent # SSHエージェントのセットアップ
        uses: webfactory/ssh-agent@v0.5.4
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
```
:point_up_2:Xserver に SSH 接続するために、秘密鍵を設定
### 秘密鍵の設定方法
Settings>Secrets and variables>Actions>New repository secretで、秘密鍵を記入（以下のSSH_PORT・SSH_USERNAME・SSH_HOST）も同様の方法で記入（GitHub Secrets）
![スクリーンショット 2025-02-03 15.51.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882527/c928a790-e37a-0c61-c1be-d5c27965e031.png)
秘密鍵は[以前の投稿](https://qiita.com/ryotaro-fukushima/items/a0e5259960ce39e4bbaa)で取得しているので、
```bash
cat ~/.ssh/your_key_file
```
出力された秘密鍵をコピペします。
```yml:ci.yml
      - name: Deploy to Xserver using rsync # Xserverへデプロイ（rsyncを使用）
        run: |
          rsync -avz \
          -e "ssh -o StrictHostKeyChecking=no -p ${{ secrets.SSH_PORT }}" \
          --exclude='.git/'
          --exclude='.github/'
          --exclude='node_modules/'
          --exclude='.gitignore' \
          "$GITHUB_WORKSPACE"/ \
          ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/home/ユーザー名/ホスト名/public_html/wp-content/themes/wp-practice
```
:point_up_2:Xserver にデプロイ（rsync を使用）
- rsync コマンドを使って、GitHub のコードを Xserver に転送 する
- -avz → アーカイブ（a）、詳細表示（v）、圧縮（z）を有効化
- -e "ssh -o StrictHostKeyChecking=no -p ${{ secrets.SSH_PORT }}" → SSH で Xserver に接続
- --exclude → 不要なファイルはデプロイしない
    - .git/ → Git 管理用フォルダ（不要）
    - .github/ → GitHub Actions の設定ファイル（不要）
    - node_modules/ → 開発環境の依存ファイル（不要）
    - .gitignore → Git の無視リスト（不要）
- $GITHUB_WORKSPACE → GitHub Actions の仮想環境内のリポジトリの場所
- /public_html/wp-content/themes/wp-practice/ → WordPress テーマディレクトリに配置
- SSH_PORT → 通常は10022（XServerのサーバー管理画面で確認可能）
- SSH_USERNAME → SSHアカウントのユーザー名
- SSH_HOST → SSHアカウントのホスト名

　```${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}```の後にユーザー名とホスト名記述するなら```${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}```要らないんじゃないかと思いましたが、rsync がリモートの Xserver へ接続するためには、SSH_USERNAME と SSH_HOST が必要のようです。
　念の為、GitHub Secretsで設定したSSH_PRIVATE_KEY・SSH_PORT・SSH_USERNAME・SSH_HOSTがきちんと登録されているか確認するコードを作り実行しました。
 ```yml:debug-secrets.yml
 name: Debug Secrets

on: workflow_dispatch  # 手動実行

jobs:
  debug:
    runs-on: ubuntu-latest
    steps:
      - name: Check if SSH_PRIVATE_KEY exists
        run: |
          if [[ -z "${{ secrets.SSH_PRIVATE_KEY }}" ]]; then
            echo "❌ SSH_PRIVATE_KEY is NOT set!"
            exit 1
          else
            echo "✅ SSH_PRIVATE_KEY is set!"
          fi
      - name: Check if SSH Secrets exist
        run: |
          if [[ -z "${{ secrets.SSH_USERNAME }}" ]]; then
            echo "❌ SSH_USERNAME is NOT set!"
          else
            echo "✅ SSH_USERNAME is set!"
          fi

          if [[ -z "${{ secrets.SSH_HOST }}" ]]; then
            echo "❌ SSH_HOST is NOT set!"
          else
            echo "✅ SSH_HOST is set!"
          fi

          if [[ -z "${{ secrets.SSH_PORT }}" ]]; then
            echo "❌ SSH_PORT is NOT set!"
          else
            echo "✅ SSH_PORT is set!"
          fi
```
その結果
![スクリーンショット 2025-02-03 17.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882527/901b3b04-2dda-7be4-89f9-a7f7fecf3f4d.png)
しっかりセットできていることがわかりました。

ci.ymlを実行後
![スクリーンショット 2025-02-03 16.14.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882527/4fdcd4fc-8bc1-7869-59b8-511b47670326.png)
このような画面が出れば成功です！
あとは試しにヘッダーのタイトルの色を変更してpushすると、、、
![スクリーンショット 2025-02-03 16.59.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882527/56708ab3-3ed9-c005-4454-da47b3da00c7.png)
![スクリーンショット 2025-02-03 16.57.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882527/a2183a3b-b5ac-4b9c-d8b8-6d4c08682be5.png)
SEO対策道場の色が変わり、自動デプロイの設定が完了しました！

# まとめ
　エンジニアを初めて５ヶ月が過ぎると、タスクにかかる時間やQiitaを書く時間が短くなってきたなと感じています。５ヶ月前はこんなことができているとは想像もつかなかったと思います。
　エンジニアとして成長できている証なのかな、と思いました。