slidict.io - GitHub Actions & Release Notes 活用デプロイフロー | slidict.io

JA | EN

i

slidict.io - GitHub Actions & Release Notes 活用デプロイフロー

yubele
yubele
フォロワー 0人
最終更新: 2026/02/19
読む時間: 07:53

共有

コード

slidict.io のデプロイメントパイプラインの全体像

* GitHub Actions を活用した自動化フロー
* Conventional Commits による自動リリースノート作成
* Azure Kubernetes Service (AKS) への継続的デプロイメント
* 3つの環境(Preview, Staging, Production)での段階的デプロイ

[%step]
** Preview: main ブランチ push 時に自動デプロイ
** Staging: PR に staging ラベル付与で手動デプロイ
** Production: GitHub Release 作成時に自動デプロイ

---

[%columns]
====

[%column]
* デプロイフロー概要
* GitHub Actions ワークフロー
* Conventional Commits setup
* リリースノート生成
* Docker イメージビルド

[%column]
* AKS デプロイメント詳細
* Release Tasks 機構
* 環境別設定
* 監視・通知
* ベストプラクティス

====

---

[.center,background-image="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 400'%3E%3Cdefs%3E%3ClinearGradient id='grad1' x1='0%25' y1='0%25' x2='100%25' y2='0%25'%3E%3Cstop offset='0%25' style='stop-color:%23ff6b6b;stop-opacity:1' /%3E%3Cstop offset='100%25' style='stop-color:%23ee5a6f;stop-opacity:1' /%3E%3C/linearGradient%3E%3ClinearGradient id='grad2' x1='0%25' y1='0%25' x2='100%25' y2='0%25'%3E%3Cstop offset='0%25' style='stop-color:%234ecdc4;stop-opacity:1' /%3E%3Cstop offset='100%25' style='stop-color:%2343b099;stop-opacity:1' /%3E%3C/linearGradient%3E%3ClinearGradient id='grad3' x1='0%25' y1='0%25' x2='100%25' y2='0%25'%3E%3Cstop offset='0%25' style='stop-color:%23f9ca24;stop-opacity:1' /%3E%3Cstop offset='100%25' style='stop-color:%23f0932b;stop-opacity:1' /%3E%3C/linearGradient%3E%3C/defs%3E%3Cg%3E%3Crect x='20' y='80' width='140' height='60' fill='url(%23grad1)' rx='5'/%3E%3Ctext x='90' y='115' text-anchor='middle' fill='white' font-size='14' font-weight='bold'%3EGit Push%3C/text%3E%3C/g%3E%3Cg%3E%3Cpolygon points='180,110 200,100 200,120' fill='%23888'/%3E%3C/g%3E%3Cg%3E%3Crect x='220' y='80' width='140' height='60' fill='url(%23grad2)' rx='5'/%3E%3Ctext x='290' y='115' text-anchor='middle' fill='white' font-size='14' font-weight='bold'%3EGitHub Actions%3C/text%3E%3C/g%3E%3Cg%3E%3Cpolygon points='380,110 400,100 400,120' fill='%23888'/%3E%3C/g%3E%3Cg%3E%3Crect x='420' y='80' width='140' height='60' fill='url(%23grad3)' rx='5'/%3E%3Ctext x='490' y='115' text-anchor='middle' fill='black' font-size='14' font-weight='bold'%3EDocker Build%3C/text%3E%3C/g%3E%3Cg%3E%3Cpolygon points='580,110 600,100 600,120' fill='%23888'/%3E%3C/g%3E%3Cg%3E%3Crect x='620' y='80' width='140' height='60' fill='url(%23grad1)' rx='5'/%3E%3Ctext x='690' y='115' text-anchor='middle' fill='white' font-size='14' font-weight='bold'%3EAKS Deploy%3C/text%3E%3C/g%3E%3Cg%3E%3Cpolygon points='780,110 800,100 800,120' fill='%23888'/%3E%3C/g%3E%3Cg%3E%3Crect x='820' y='80' width='140' height='60' fill='url(%23grad2)' rx='5'/%3E%3Ctext x='890' y='115' text-anchor='middle' fill='white' font-size='14' font-weight='bold'%3E🎉 Live%3C/text%3E%3C/g%3E%3C/svg%3E"]

---

[options="header",cols="^1,^2,^3,^4"]
|===
| 環境 | URL | トリガー | 用途
| *Preview* | preview.slidict.io | main ブランチへの push | 開発中の最新機能確認
| *Staging* | staging.slidict.io | PR に staging ラベル付与 | リリース前の最終検証
| *Production* | slidict.io | GitHub Release 作成 | ユーザー向け本番環境
|===

[%step]
--
各環境は独立した AKS クラスタ設定を持ち、段階的なテストと検証が可能
--

---

プロジェクトの基本ルール:

[.left]
* **prefix**: `feat:`, `fix:`, `docs:`, `style:`, `refactor:`, `test:`, `chore:` など
* **言語**: 日本語で記述(50文字程度が目安)
* **句点**: 語尾に句点を付けない

[.left.code,source,text]
----
feat: ユーザープロフィールに自己紹介欄を追加
fix: スライド保存時のエラーハンドリングを修正
docs: デプロイメント手順を更新
----

[%step]
--
💡 **効果**: コミット履歴がしっかり解析でき、自動でリリースノート を生成!
--

---

[source,yaml]
----
# main ブランチへの push で以下が自動実行される
- name: Create CHANGELOG
uses: requarks/changelog-action
with:
fromTag: 最後のリリースタグ
toTag: 現在のバージョンタグ
excludeTypes: "" # すべてのコミットタイプを含める
includeInvalidCommits: false # マージコミットは自動除外
----

[%step]
--
**自動除外されるコミット**:
* `Merge pull request ...`
* `Merge branch ...`
* その他マージ関連コミット

これにより、ユーザー向けリリースノートが自動生成される
--

---

[source,yaml]
----
name: main-ci

on:
push:
branches: [main]
workflow_dispatch: # 手動実行も可能

jobs:
main:
# 1. Changelog 自動生成
# 2. Draft Release 作成
# 3. Kroki ダイアグラムサービスをデプロイ
# 4. Preview 環境へのフルデプロイ
----

**実行時間**: 約 10~15分

---

[source,yaml]
----
- name: Build and push image to DockerHub
uses: docker/build-push-action
with:
tags: |
slidict/slidict.io:preview-{{COMMIT_SHA}}
build-args: |
RAILS_ENV=preview
SECRET_KEY_BASE_DUMMY=dummy-secret-key
GITHUB_SHA={{COMMIT_SHA}}
----

[%step]
--
* **イメージタグ**: `環境-コミットSHA` で一意性を確保
* **ビルドキャッシュ**: 層ごとにキャッシュされ、効率化
* **DockerHub**: プライベートレジストリへ自動プッシュ
--

---

[source,yaml]
----
# 1. 証明書管理(cert-manager)
- name: Apply cert-manager manifests
run: |
kubectl apply -f cert/secret.yml
kubectl apply -f cert/clusterissuer.yml
kubectl apply -f cert/certificate.yml

# 2. Redis デプロイ
- name: Deploy redis

# 3. Chrome ブラウザサービス(スクリーンショット用)
- name: Deploy chrome

# 4. Sidekiq Worker(バックグラウンドジョブ)
- name: Deploy worker
----

---

[source,yaml]
----
# 5. データベースマイグレーション
- name: Wait for migration to complete
run: |
kubectl wait --for=condition=complete \
--timeout=120s job/$POD_PREFIX-migrate

# 6. Release Tasks 実行
# 初回デプロイ時のみ実行される一度限りのタスク

# 7. メインアプリケーションデプロイ
- name: Deploy pod and update ingress
with:
manifests: |
ingress.yml
app.yml

# 8. Auto Scaling 設定
- name: Deploy horizontal-pod-autoscaler
----

---

一度だけ実行したいタスクを管理

[source,ruby]
----
# lib/release_tasks/backfill_feature_flag.rb
module ReleaseTasks
class BackfillFeatureFlag < ReleaseTasks::Base
def run
FeatureFlag.find_each do |flag|
flag.update!(enabled: true)
end
end
end
end
----

[%step]
--
* **実行履歴**: `release_tasks` テーブルで管理
* **二重実行防止**: `executed_at` で判定
* **手動実行**: `make release-tasks` コマンドで可能
--

---

GitHub Release トリガー

[source,yaml]
----
name: production-ci

on:
release:
types: [released] # Draft Release が published されたら実行

permissions: write-all

jobs:
deploy_production:
uses: ./.github/workflows/call-deploy-ci.yml
with:
ENVIRONMENT: "production"
ENVIRONMENT_URL: "https://slidict.io"
POD_PREFIX: "slidict-io"
----

[%step]
--
**重要**: Draft Release → Published Release に変更されたとき
--

---

PR の staging ラベルでトリガー

[source,yaml]
----
name: staging-ci

on:
pull_request_target:
branches: [main]
types: [labeled, synchronize, reopened]

jobs:
deploy_staging:
if: contains(github.event.pull_request.labels.*.name, 'staging')
# → staging ラベルがついている場合のみ実行
----

[%step]
--
**用途**: 本番リリース前の最後の検証環境
--

---

[source,text]
----
1️⃣ コード開発
└─ Conventional Commits でコミット

2️⃣ main ブランチへ merge
└─ main-ci が自動実行
└─ Changelog automatically generated
└─ Draft Release created
└─ Preview 環境へデプロイ ✨

3️⃣ Staging 検証(オプション)
└─ PR に staging ラベル追加
└─ staging-ci が実行
└─ staging.slidict.io で最終検証

4️⃣ GitHub Release の Published
└─ production-ci が自動実行
└─ production 環境へデプロイ 🚀

5️⃣ ユーザーが新機能を利用可能 🎉
----

---

ERB テンプレートで環境別設定を制御

[source,ruby]
----
# manifests/expansion.rb(自動実行)
ruby manifests/expansion.rb \
manifests/azure-kubernetes/production/cert/secret.yml

# 展開対象
- Azure Service Principal 認証情報
- DNS 設定
- 各環境別リソース
----

[source,yaml]
----
# manifests/azure-kubernetes/production/app.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: slidict-io-production
spec:
replicas: <%= ENV['PRODUCTION_REPLICAS'] %> # 環境変数で制御
----

---

[options="header",cols="^1,^2,^2,^2"]
|===
| 要素 | Preview | Staging | Production
| kubeconfig | AKS Slidict | AKS Slidict | AKS Slidict
| Pod Replicas | 2 | 3 | 5
| Min/Max HPA | 2/10 | 3/15 | 5/30
| Resource Limits | small | medium | large
| DNS | *.svc.cluster.local | *.svc.cluster.local | 本番FQDN
| Monitoring | 基本 | 基本 | Prometheus + Grafana
|===

---

[source,yaml]
----
# manifests/azure-kubernetes/nagios/nagios.yaml
monitoring:
- healthz: /healthz # アプリ起動確認
- sns_login: /healthz/sns_login # SNS 認証確認
- https: https://slidict.io(12時間間隔)

configuration:
debug_level: 2048
debug_verbosity: 2
configmap: docker/nagios/nagios.cfg
----

[%step]
--
**注意**: ホスト名は `azure-kubernetes` 内のサービス DNS を使用
* ✅ `*.svc.cluster.local`
* ❌ `slidict.io` や `origin.slidict.io`(外部URL)
--

---

[source,yaml]
----
manifests/azure-kubernetes/
├── grafana/
│ ├── datasources.yml (Prometheus接続)
│ ├── dashboards/
│ │ ├── app-metrics.json (アプリメトリクス)
│ │ ├── k8s-cluster.json (クラスタ状態)
│ │ └── sidekiq-jobs.json (バックグラウンドジョブ)
│ └── grafana-deployment.yaml
----

[%step]
--
* **Prometheus Operator** で自動スクレイピング
* **Alert Rules** で異常検知
* **通知**: Slack, Email など
--

---

AKS Cluster 内で動作

[source,yaml]
----
manifests/azure-kubernetes/kroki/
├── mermaid-deployment.yaml # フローチャート
├── bpmn-deployment.yaml # ビジネスプロセス
├── excalidraw-deployment.yaml # 手書き図
├── kroki-deployment.yaml # メインサービス
└── kroki-ingress.yaml
----

[%step]
--
* slidict.io エディタから図を生成・埋め込み可能
* 完全クローズド環境で実行(外部API呼び出しなし)
--

---

[source,bash]
----
# 開発環境立ち上げ
docker compose up -d

# Rails サーバー起動
docker compose exec app bin/dev

# テスト実行(codex環境)
RAILS_ENV=codex bundle exec rspec

# キャッシュリセット(Propshaft の問題回避)
rm -rf public/assets/
docker compose restart app
----

[%step]
--
**重要**: `public/assets/` が存在するとプリコンパイル済みアセットを読み込み、
動的生成がスキップされるため、新規のアセットが見つからなくなる
--

---

定期実行ジョブの設定

[source,yaml]
----
# config/sidekiq.yml
:schedule:
check_sns_login_health:
cron: '0 * * * *' # 毎時間
class: SnSLoginHealthCheckJob

regenerate_slide_thumbnails:
cron: '0 3 * * *' # 毎日 3時
class: RegenerateSlideThumbailsJob
----

[%step]
--
* **schedules を使用**: https://github.com/sidekiq-scheduler/sidekiq-scheduler
* **キャッシュからの実行**: Redis database 15
* **テスト**: spec は `config/sidekiq_schedule_spec.rb` ではなく、実装に組み込む
--

---

異なる用途で DB 分離

[options="header",cols="^1,^2"]
|===
| Database | 用途
| 11 | Redcord(キー値ストア)
| 12 | ActionCable(リアルタイム通信)
| 14 | キャッシュストア
| 15 | Sidekiq(バックグラウンドジョブ)
|===

[source,bash]
----
# Redis CLI でデータベース確認
redis-cli -n 15 KEYS "*" # Sidekiq のキー一覧
----

---

コード変更時は必ず関連ドキュメントも更新

[source,text]
----
docs/
├── feature-specs.md # 機能仕様一覧
├── groups.md # グループ共有機能
├── help-center-and-support.md
├── slide_deck_structure.md
├── release-tasks.md # リリースタスク機構
├── infrastructure-manifests.md
├── slide-moderation.md
├── editor/ # エディタ仕様
└── mcp/ # MCP サーバー仕様
----

[%step]
--
* **Help Articles**: `docs/seeds/help_articles/` で更新
* **シード管理**: ユーザー向けの情報は整備が必須
--

---

[%step]
--
* ☐ コミットメッセージが Conventional Commits に準拠
* ☐ RSpec テストが全て PASS: `make rspec`
* ☐ RuboCop が PASS: `make rubocop`
* ☐ Brakeman セキュリティ確認: `docker compose exec base bundle exec brakeman`
* ☐ ERB フォーマット確認: `make htmlbeautifier args='**/*.erb'`
* ☐ TypeScript/JavaScript ビルド: `yarn build`
* ☐ 関連ドキュメント更新
* ☐ Release Tasks が必要な場合は実装済み
--

---

[source,bash]
----
# 1. コード確認・テスト
make rspec
make rubocop

# 2. コミット & push to main
git add .
git commit -m "feat: 新機能を実装"
git push origin main

# 3. GitHub Actions 自動実行
# → Draft Release が作成される

# 4. Release 確認(稼働状況・クリティカルバグなし)

# 5. GitHub Release を Published に変更
# → production-ci が自動実行

# 6. 本番環境にデプロイ完了 🎉
----

---

[source,bash]
----
# 1. GitHub Actions ログを確認
# → Workflow ページで詳細ログを確認

# 2. AKS ポッド状態を確認
kubectl get pods -n default

# 3. ポッドログを確認
kubectl logs <pod-name> -n default

# 4. デバッグモードで再実行
# → Workflow の "Run" ボタンで再実行
# OR
# → デバッグログを有効にして実行
----

---

[%step]
--
1. **小分けコミット**: 1つの PR = 複数の小さなコミット
2. **Conventional Commits**: 自動リリースノート生成に必須
3. **テスト駆動開発**: テストなしで main にマージしない
4. **Preview 環境活用**: main-ci で自動デプロイされる
5. **Staging 検証**: 本番向け大型変更は staging でテスト
6. **Release Notes 確認**: Draft Release をレビューしてから Published
7. **Monitoring 監視**: 本番デプロイ後の動作確認は必須
8. **ドキュメント同期**: コード変更とドキュメント更新は同時に
--

---

[options="header",cols="^1,^2,^3"]
|===
| ワークフロー | 処理内容 | 実行時間
| main-ci | Changelog + Docker Build + AKS Deploy | 10~15分
| staging-ci | Docker Build + AKS Deploy | 8~12分
| production-ci | Docker Build + AKS Deploy | 8~12分
|===

[%step]
--
**最適化のポイント**:
* Docker BuildKit によるレイヤーキャッシュ
* 並列ジョブ実行(cert, setup_configmap 等)
* DockerHub へのプッシュ(レジストリ内キャッシュ活用)
--

---

本番環境での問題発生時

[source,bash]
----
# 1. 前のイメージタグを確認
kubectl get deployment slidict-io-production \
-o jsonpath='{.spec.template.spec.containers[0].image}'

# 2. 前のバージョンにロールアウト
kubectl rollout history deployment/slidict-io-production
kubectl rollout undo deployment/slidict-io-production

# 3. 状態確認
kubectl get pods
kubectl logs <新しいpod>
----

[%step]
--
**GitHub Releases でも可能**: 前のバージョンタグから新しい Release を作成
--

---

GitHub Actions Secrets の活用

[source,text]
----
GitHub Repository Secrets:
- APP_ID: GitHub App ID
- APP_PRIVATE_KEY: GitHub App の秘密鍵
- AKS_SLIDICT_KUBECONFIG: AKS kubeconfig
- AZURE_SUBSCRIPTION_ID: Azure サブスクリプション ID
- DNS_SP: DNS 用サービスプリンシパル(JSON)
- DOCKERHUB_USERNAME: Docker Hub ユーザー名
- DOCKERHUB_TOKEN: Docker Hub トークン
----

[%step]
--
✅ **セキュリティ**:
* すべてのシークレットはマスクされる
* ログには出力されない
* PR では利用できない(`pull_request_target` を使用)
--

---

HPA (Horizontal Pod Autoscaler) による自動スケール

[source,yaml]
----
# manifests/azure-kubernetes/production/horizontal-pod-autoscaler.yml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: slidict-io-production-hpa
spec:
scaleTargetRef:
name: slidict-io-production
minReplicas: 5
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
----

---

よくある質問と回答

[%step]
--
**Q: Release Task を再実行したい**
A: `release_tasks` テーブルの該当レコードの `executed_at` を NULL にする

**Q: Preview デプロイが失敗した**
A: `public/assets/` ディレクトリを削除して再起動

**Q: Staging で本番同様にテストしたい**
A: staging ラベルで PR をデプロイし、staging.slidict.io で検証

**Q: Release Notes を手動で修正したい**
A: Draft Release を編集して公開(GitHub の UI から)

**Q: Rollback したい**
A: `kubectl rollout undo` で前バージョンに戻す
--

---

slidict.io のデプロイメントパイプラインの特徴

[%step]
--
✨ **自動化**: Conventional Commits → 自動 Changelog 生成

🚀 **段階的デプロイ**: Preview → Staging → Production

🔒 **安全性**: PR staging ラベルで検証 → Release で本番化

📊 **可視化**: GitHub Actions + Grafana + Nagios

⚡ **スケーラビリティ**: HPA による自動スケール

🔄 **復旧性**: ロールバック機構で迅速な復旧

💡 **DevOps 文化**: コード品質とドキュメント整備が鍵
--

---

[.large]
--
GitHub Actions + Conventional Commits + AKS = 強力な CI/CD

デプロイパイプラインを理解することで、
チーム全体の開発効率と品質が向上する

**Happy Deploying! 🎉**
--

[%step]
--
_本スライドの最新版は slidict.io で公開中_
--

Background

スライド作成を
無料で始める

AIがあなたのスライドを自動生成。無料で、すぐに体験できます。

読み込み中...
1 / 9