周辺を探すの寄せ先を easeTo に変え、視差効果を減らす端末でも効かせる #127
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # mainへのpushで本番用Dockerイメージをビルドし、GHCRへ公開する。 | |
| # 本番環境の更新はこれらをpullするだけでよい(README「本番運用」参照)。 | |
| # ghcr.io/rtcode337/travel-log … アプリ本体(Dockerfileのprodステージ、appサービス)。 | |
| # スキーマとマイグレーションSQLもこれに焼き込まれ、 | |
| # 起動時に scripts/migrate.mjs が当てる | |
| # | |
| # アプリ本体は amd64/arm64 を「それぞれのアーキのネイティブランナー」で並列ビルドし、 | |
| # ダイジェストで push したものを最後の merge ジョブでマニフェストにまとめる。 | |
| # 以前は amd64 ランナー上で arm64 を QEMU エミュレーションしていたが、arm64 の | |
| # `npm ci`(や next build)が極端に遅く、まれにハングしてビルドが 40 分以上 | |
| # 進まないことがあったため、ネイティブランナー方式に変えた(publicリポジトリは | |
| # ubuntu-24.04-arm ランナーを無料で使える)。 | |
| name: docker-publish | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| packages: write | |
| env: | |
| IMAGE: ghcr.io/${{ github.repository }} | |
| jobs: | |
| # 管理画面に表示するビルド番号(JSTの日時 + 短縮コミットハッシュ)を1回だけ決めて、 | |
| # 両アーキのビルドで同じ値を焼き込む(アーキごとに別値にならないように) | |
| prepare: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| build_number: ${{ steps.build_number.outputs.value }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - id: build_number | |
| run: | | |
| echo "value=$(TZ=Asia/Tokyo date +'%Y%m%d-%H%M')-$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" | |
| # アーキごとにネイティブランナーでビルドし、タグを付けずダイジェストで push する | |
| build: | |
| needs: prepare | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: linux/amd64 | |
| runner: ubuntu-latest | |
| - platform: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: docker/setup-buildx-action@v4 | |
| - uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ${{ env.IMAGE }} | |
| - id: build | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| target: prod | |
| platforms: ${{ matrix.platform }} | |
| build-args: | | |
| BUILD_NUMBER=${{ needs.prepare.outputs.build_number }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| # タグではなくダイジェストで push する(マニフェストは merge ジョブで作る) | |
| outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true | |
| cache-from: type=gha,scope=app-${{ matrix.platform }} | |
| cache-to: type=gha,mode=max,scope=app-${{ matrix.platform }} | |
| - name: Export digest | |
| run: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: digests-app-${{ strategy.job-index }} | |
| path: /tmp/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| # 各アーキのダイジェストを1つのマニフェスト(latest / sha-xxxxxxx タグ)にまとめて push する | |
| merge: | |
| needs: [build] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download digests | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: /tmp/digests | |
| pattern: digests-app-* | |
| merge-multiple: true | |
| - uses: docker/setup-buildx-action@v4 | |
| - uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ${{ env.IMAGE }} | |
| # latest(既定ブランチのみ)+ コミットSHA(sha-xxxxxxx)の2タグ。 | |
| # 障害時はSHAタグを指定してpullすれば任意の時点に戻せる | |
| tags: | | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| type=sha | |
| - name: Create manifest list and push | |
| working-directory: /tmp/digests | |
| run: | | |
| docker buildx imagetools create \ | |
| $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
| $(printf '${{ env.IMAGE }}@sha256:%s ' *) | |
| - name: Inspect | |
| run: docker buildx imagetools inspect ${{ env.IMAGE }}:${{ steps.meta.outputs.version }} | |
| # 古い版を消して直近 10 世代だけ残す。 | |
| # | |
| # 公開パッケージなので GHCR の容量・転送は無料枠を消費しないが、版は放っておくと | |
| # 際限なく積み上がる(`latest` を付け替えても前の版は SHA タグ付きで残る)。 | |
| # 一覧が読めなくなるのと、どれが生きているか分からなくなるのを防ぐための掃除。 | |
| # | |
| # **専用のジョブにして、push が終わってから走らせる。** merge に相乗りさせると | |
| # 「新しい版が出来る前に掃除する」順序になりうる。 | |
| # | |
| # **actions/delete-package-versions は使わない。** このリポジトリはマルチアーキで、 | |
| # 1 つのタグが manifest list + アーキごとの子イメージで構成される。あちらは | |
| # 子イメージを「タグ無しの版」として消してしまい、残したはずのタグが壊れる。 | |
| # この action は manifest list を理解して親子まとめて扱う。 | |
| cleanup: | |
| needs: [merge] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| packages: write | |
| steps: | |
| - name: 古いイメージを削除して直近 10 世代だけ残す | |
| uses: dataaxiom/ghcr-cleanup-action@v1 | |
| with: | |
| # travel-log-db-init は廃止(スキーマ適用をアプリへ寄せた)。GHCR に残っている | |
| # 古いパッケージは手で削除する —— ここに残すと存在しない扱いでジョブが落ちる | |
| packages: travel-log | |
| keep-n-tagged: 10 | |
| delete-untagged: true | |
| token: ${{ secrets.GITHUB_TOKEN }} |