Closed4

Remix+CloudflareでWebサイトを作る 7(GitHub Action・PRでStaging環境に自動デプロイ・環境毎にD1の参照先を変更・Markdownパーサーの作り方調査)

saneatsusaneatsu

【2024-02-17】GithubActionsで設定できる環境変数周りについてざっくり知る

https://zenn.dev/hashito/articles/aef4de448f341b
https://zenn.dev/yuhei_fujita/articles/deploy-with-github-environment
https://zenn.dev/kou_pg_0131/articles/gh-actions-configurations-variables

Secretsは機密情報を保存して後から見れなくなり、Github Actionsのログではマスクされる。
Variablesも機密情報扱いだけど、後から確認できるしGithub Actionsのログに値が出力される。

Github Actionsのログに値が出力されることはやばいとはわかるけど、実際どのくらいのヤバさなのかがわかってない。具体的にどういうケースのときにログの値が見られてやばくなるんだろうか。

そういえばBasic認証の情報をCloudflareの環境変数として管理するようにした時 に環境変数がデフォルトでは設定後に確認できて、「暗号化」ボタンを押すと「この値は一度保存すると表示されなくなります。」と表示されてたけどこれはデフォルトだとGithubでいうVariablesだけど、「暗号化」ボタンを押すとSecretsになるということかな?

軽くまとめ

「Repository secrets, Repository variables」「Environments secrets, Environments variables」の4種類がある。

  • Repository
    • レポジトリ全体で使うやつを指定する
  • Environments
    • 環境ごとで分けたい時にそれぞれの環境を作成して、その中に環境変数を作成する
  • secrets
    • 見られちゃだめな秘匿情報で後から内容は確認できない
  • variables
    • 機密情報だが後から確認できてログにも出力される

例(あってるのかわからない)

  • Repository secrets
    • SlackのToken
  • Repository variables
    • (思い浮かばなかった...)
  • Environments secrets
    • 環境ごとのAPIトークンやAWSのアカウントID
  • Environments variables
    • 環境ごとのAPIのルートURL(https://app/api/stg, https://app/api/prd
saneatsusaneatsu

【2024-02-17】GithubActionsでProduction/Staging環境ごとにデプロイする

現状

Repository secretsにCLOUDFLARE_ACCOUNT_IDCLOUDFLARE_API_TOKEN を設定している。
環境ごとに分けるためにEnvironment secretsにこの値を書き写して、GithubActionsのYAMLファイルを修正する。

手を動かしながら気付いてしまった

GithubActionsのYAMLを修正してpushしてを繰り返しながら気付いたけどCloudflareはデプロイする環境によってAPIトークンとか変わらないから、わざわざ課金してEnvironments使えるようにして環境別に設定できるようにする意味なかったことに気付いた。

4ドルで済んで良かったと思おう...。

今回やること整理

Production

  • As is
    • mainブランチにpushされた時に、Repository secretsの値を使ってProduction環境にデプロイする
  • To be
    • 現状 + 手動でもProduction環境にデプロイできるようにする

Staging

  • As is
    • GithubActionsによるデプロイができない
  • To be
    • PRが作成された時に、Repository secretsの値を使ってStaging環境にデプロイする
    • 手動でもStaging環境にデプロイできるようにする

できた

PRでStaging環境にデプロイされてる

ファイルの分け方考えるのに時間食った

最初は1つのYAMLファイルで場合分けをしてStagingとProductionにデプロイしようとしていたけど、Production環境はmainにpushされた時に発火すれば良くて、それを明示的にしたかったので環境ごとにファイルは分けた。要するにon: を見た時にどのタイミングでどこにデプロイされるのか把握したいが、その下で色々場合分けが生じると可読性が低くなるし、今後バグの原因にもなるのでは?と思いやめた。
重複しているコードは多いけど一旦これで良しとする。

もっと良い書き方はあるんだろうな。

そして1つのファイルで場合分けをしようとしていたのでこの中の場合分けの方法とかググってて時間食った。

成果物

Production環境にデプロイするGithubActions
production-deploy.yml
name: Production Deploy

# ここを見た時にmainにpushされたときだけ発火するというのがわかるのが嬉しい
on:
  push:
    branches:
      - main
  workflow_dispatch: # 手動でも実行できるようにしておいた

jobs:
  publish:
    runs-on: ubuntu-20.04
    permissions:
      contents: read
      deployments: write
      statuses: write
    steps:
      - name: 🔀 Checkout
        uses: actions/checkout@v3

      - name: ⏬ Install
        run: npm install
        working-directory: ./

      - name: 🔨 Build
        run: npm run build
        working-directory: ./

      - name: 🚀 Deploy
        id: cloudflare-wrangler
        uses: cloudflare/wrangler-action@v3
        with:
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          command: pages deploy ./public --project-name=YOUR_PROJECT_NAME

      - name: 🔗 Add publish URL as commit status
        uses: actions/github-script@v6
        with:
          script: |
            const sha = context.payload.pull_request?.head.sha ?? context.sha;
            await github.rest.repos.createCommitStatus({
              owner: context.repo.owner,
              repo: context.repo.repo,
              context: "Cloudflare Pages", # ここでも絵文字使いたかったけどエラーで落ちる。無理っぽい
              description: "Access Cloudflare Pages deployment",
              state: "success",
              sha,
              target_url: "${{ steps.cloudflare-wrangler.outputs.deployment-url }}",
            });
Staging環境にデプロイするGithubActions
staging-deploy.yml
name: Staging Deploy

on:
  pull_request:
    types: [opened, synchronize, reopened]
  workflow_dispatch:

jobs:
  setup:
    runs-on: ubuntu-latest
    outputs:
      BRANCH: ${{ env.BRANCH }}
    steps:
      - name: ⏳ Setup
        run: echo "BRANCH=${{ github.ref }}" >> "$GITHUB_ENV" # Cloudflareにデプロイする際に必要となる

  publish: # ここからは下はほぼ一緒
    needs: setup
    runs-on: ubuntu-20.04
    permissions:
      contents: read
      deployments: write
      statuses: write
    steps:
      - name: 🔀 Checkout
        uses: actions/checkout@v3
        with:
          ref: ${{ needs.setup.outputs.BRANCH }}

      - name: ⏬ Install
        run: npm install
        working-directory: ./

      - name: 🔨 Build
        run: npm run build
        working-directory: ./

      - name: 🚀 Deploy
        id: cloudflare-wrangler
        uses: cloudflare/wrangler-action@v3
        with:
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          # デプロイコマンドに --branch があるところだけが差分
          # Cloudflareでは初期設定だと--branch=main以外の場合はプレビュー環境にデプロイされる
          command: pages deploy ./public --project-name=YOUR_PROJECT_NAME --branch=${{ needs.setup.outputs.BRANCH }}

      - name: 🔗 Add publish URL as commit status
        uses: actions/github-script@v6
        with:
          script: |
            const sha = context.payload.pull_request?.head.sha ?? context.sha;
            await github.rest.repos.createCommitStatus({
              owner: context.repo.owner,
              repo: context.repo.repo,
              context: "Cloudflare Pages",
              description: "Access Cloudflare Pages deployment",
              state: "success",
              sha,
              target_url: "${{ steps.cloudflare-wrangler.outputs.deployment-url }}",
            });

参考になったサイト

GithubActionsの書き方例

こんな使い方もあるよ

https://zenn.dev/h_sugawara/articles/24488d01fede71

今はやらないけど今後色々いじっていきたい

saneatsusaneatsu

【2024-02-17】環境ごとにDBを分ける

背景

一番最初にここを見ながらDBの設定を行っていたけど、Staging/Production環境でバインディング先を同じにしてしまった。
Staging環境はDBを別にする。

やってみる Part1

1. DBの作成とバインディング

Staging環境用のデータベースを作成し、「Worker &Pages > [任意のアプリ] > 設定 > Functions」からバインディングを変更。

2. wrangler.toml を更新

https://developers.cloudflare.com/d1/configuration/environments/

公式に従い以下のように書く。

wrangler.toml
[env.staging]
d1_databases = [
    { binding = "DB_STAGING", database_name = "YOUR_PROJECT_NAME-staging", database_id = "<UUID1>" },
]

# This is a production environment
[env.production]
d1_databases = [
    { binding = "DB", database_name = "YOUR_PROJECT_NAME", database_id = "<UUID2>" },
]

3. Staging環境にマイグレーションファイルを適用

ローカルから実行してDBにテーブルを作成する

$ npx wrangler d1 migrations apply YOUR_PROJECT_NAME-staging

4. PRを作成してStaging環境のページにアクセスしてみる

StagingのDBに適当なデータを入れてトップページのloaderにそれを取得するコードを書いておいた。
PRを作成するとCloudflare Pagesにデプロイされるのでそのページに適当に入れたデータが表示されたら無事に動いているということになる。

ちーん。

多分env.DBでアクセスすることができていなくて、env.DB_STAGINGとする必要があるから値が取得できないのでは。とは言っても対応方法がわからない。

調べてみる

https://developers.cloudflare.com/workers/wrangler/environments/
https://stackoverflow.com/questions/66788825/detecting-if-we-are-running-in-dev-mode-or-in-production-mode-in-cloudflare-work

公式含めここらへんをみる限り、wranglerコマンドの引数に--env を指定すると wrangler.tomlでそこにアクセスできるようになるっぽい。
以下のようにしてみて、開発環境で試してみるがどうにも動かない。

package.json
"build": "remix build",
"dev": "remix dev --manual -c \"npm run start\"",
"start": "wrangler pages dev --compatibility-date=2023-06-21 ./public --env development",
wrangler.toml
[env.development]
d1_databases = [
  { binding = "DB", database_name = "YOUR_PROJECT_NAME", database_id = <YOUR_DB_ID> },
]

なおった

色々いじってなんやかんやでやり方はわかった。
5時間くらいかかった。

その他

wrangler.toml.gitignore に入れるべきなのか

そういやアプリケーション作成した時に.dev.vars はgitignoreされてて、wrangler.toml はされてなかったけど database_id とかはシークレットな情報ではないのかな?
なんかそのうちセキュアな情報は入りそうだけど一旦トークンとかは入っていないから大丈夫?

この記事ではignoreしてるな。

今回はもうpushしちゃってるしAPIキーとかはGithubのEnvironmentsで管理してるし大丈夫、ということにして一旦進んだ。

因みに、Honoだとデフォルトでignoreされているらしい

Staging環境へデプロイしたときのURLについて

毎回変わるけどURL固定にしたいかもな〜と少し思った。

saneatsusaneatsu

【2024-02-18】Markdownパーサーを作りたいので調べてみよう

背景

Remixで単に管理画面を作って記事を投稿できるだけでは面白みがないので今までやったことないリッチなことをしてみたい。
ということでこのZennの様に独自の記法を使えるMarkdownパーサーを作ってみたい。

ということで一旦調べてみた。

調べる

ZennのPublic Rrepository

https://github.com/zenn-dev/zenn-editor/tree/main/packages/zenn-markdown-html

こういうやつを作りたい。

構文解析器

https://www.m3tech.blog/entry/2021/08/23/124000

構文解析器とかの世界に足を踏み入れることになる。
このブログで作ったコードのPlaygroundを見てみると良さげな感じがする。オリジナルのも作れそう。

作った方のポートフォリオ発見。すごそう。
https://asmsuechan.com/

ブログで紹介されているのはこの方が趣味で開発したminuteというMarkdownパーサーということで、リポジトリが公開されていた。
minuteの方は21Commitしかないし全部読んでみる。

https://github.com/asmsuechan/minute
https://github.com/asmsuechan/minute-playground

やりたいことをやっている人を発見

全部同じ方の記事で特に番号はふられていないけど以下の順で見ていくっぽい。

同じくunified エコシステム周りの記事

https://vivliostyle.github.io/vivliostyle_doc/ja/vivliostyle-user-group-vol2/spring-raining/index.html

ここでも使ってた

https://typescriptbook.jp/writing/markdown

typescriptbookはよく参照しているけど、ここでもMarkdownパーサーを拡張している。
Repositoryは公開されているので除きにいってもみても良いかも。

https://github.com/yytypescript/book

感想

minuteのPlayground を見る限り、これにStyleを適用すれば自分のやりたいことできるなら21Commit全部読んでゼロから実装していくのが勉強になるし面白そうだと思った。

その一方でまだ知らない部分、実は今後必要になる機能が色々あり、そこの開発が自分ではどうにもできないレベルになってくるなら unified を導入したい。

調べてみるとunifiedも2024-02-18現在で401Commitだから読もうとすれば全部読めそうな気はする。

Next Actionはminuteのコードを読みながら構文解析器の勉強をする、になるかな。

https://github.com/unifiedjs/unified

その他

調べながらWYSIWYG(ウィジウィグ)って言葉に出会った。
What You See Is What You Get の略で「見たままを得られる」という意味らしい。

このスクラップは2ヶ月前にクローズされました