HerokuでGitHubと直接連携せずに確認用アプリを作る(2022年5月)

Heroku のインシデント

2022年5月現在、OAuthユーザトークン流出の問題でHerokuとGitHubを連携させることができません。(Heroku、全ユーザーのパスワードをリセット - OAuthトークンの漏洩受け | TECH+
HerokuではGitHubと連携させることでプルリクエストを出した時に確認用アプリを作成し、ブランチをその場でデプロイする機能があります。新しいブランチを作成→Heroku環境で確認→develop環境にマージという流れで安全に開発をすることができるので、この機能がないのはなかなか不便です。そこで今回はGitHub Actionsを利用して同じようにプルリクエスト時に確認用アプリを作成する方法を書いていきます。

GitHub Actions

GitHub Actionsとは、GitHub上でのイベントをトリガーとして、決められた様々な処理を実行することができるCI/CDです。これにより自動的にテストやデプロイをすることが可能になります。使い方は簡単で、通常はプロジェクトのルートディレクトリに.github/workflows/を作成し、その中にしたい処理を記述したymlファイルを配置します。ymlファイルの書き方は後述します。

GitHub ActionsでHerokuのアプリを作成しブランチをデプロイ

プルリクエストの時に処理を実行するymlファイルは以下のようになります。onにトリガーとなる処理を書き、jobsにする処理を書いていきます。

# .github/workflows/heroku-pull-request.yml
name: Heroku Pull Request
on:
  pull_request:
    types: [opened, synchronize, reopened, closed]
    branches: [ develop ]
jobs:
  heroku-pull-request:
    runs-on: ubuntu-latest
    env:
      HEROKU_APP_NAME: txt-checker-pr-${{ github.event.number }}

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3
        with:
          fetch-depth: ${{ github.event.action == 'closed' && 1 || 0 }}
          ref: ${{ github.event.action != 'closed' && github.head_ref || '' }}

      - name: Login to Heroku
        uses: akhileshns/heroku-deploy@v3.12.12
        with:
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
          heroku_email: hirokzu08@gmail.com
          heroku_app_name: ${{ env.HEROKU_APP_NAME }}
          justlogin: true

      - name: Create Heroku app
        if: github.event.action == 'opened'
        run: heroku create ${{ env.HEROKU_APP_NAME }} --team six1

      - name: Add Heroku app to pipeline
        if: github.event.action == 'opened'
        run: heroku pipelines:add six1-proofreading --app=${{ env.HEROKU_APP_NAME }} --stage=staging

      - name: Add Heroku remote 
        run: heroku git:remote --app=${{ env.HEROKU_APP_NAME }}

      - name: Push to Heroku
        run: git push heroku ${{ github.head_ref }}:master --force

      - name: Add comment to PR
        if: github.event.action == 'opened'
        run: |
          gh pr comment ${{ github.event.number }} --body '[Heroku app](https://dashboard.heroku.com/apps/${{ env.HEROKU_APP_NAME }}): https://${{ env.HEROKU_APP_NAME }}.herokuapp.com'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Destroy Heroku app
        if: github.event.action == 'closed'
        run: heroku apps:destroy --app=${{ env.HEROKU_APP_NAME }} --confirm=${{ env.HEROKU_APP_NAME }}

気を付ける点は2つです。1つ目は、pull_requestのbranchesで指定するブランチはマージ’される’側のブランチということです。もう一つはHEROKU_API_KEYの登録方法です。リポジトリの設定(Settings)で登録します。次の参考にしてください。
暗号化されたシークレット - GitHub Docs