はじめに: フロントエンド開発者のための CI/CD
すべてのフロントエンド開発者は、遅かれ早かれ同じ質問に直面します。「どうすれば自動化できるか」 アプリケーションのビルド、テスト、デプロイメントのプロセスは?現代的な答えはこう呼ばれます CI/CD (継続的インテグレーション/継続的デプロイメント)、e GitHub アクション 今日それを代表する プロジェクト リポジトリに直接実装するための最もアクセスしやすく強力なツールです。
このシリーズの最初の記事では フロントエンド開発者のためのDevOps、私たちは構築します Angular アプリケーションの完全なパイプラインをゼロから作成: 最初の継続的統合ワークフローから 実稼働環境への自動デプロイメントまで。それぞれの概念を実践的な例とコードで説明します 使用する準備ができています。
この記事で学べること
- GitHub Actions の基本概念: ワークフロー、ジョブ、ステップ、トリガー
- Angular の CI ワークフローをセットアップする方法 (インストール、lint、テスト、ビルド)
- Firebase と Vercel に自動デプロイメントを実装する方法
- パイプラインを高速化するためのキャッシュ戦略
- Node.js の複数のバージョンでテストするためのマトリックス戦略
- アーティファクトとブランチ保護ルールを構成する方法
- 再利用可能なワークフローを作成する方法
1. GitHub Actionsの基本概念
GitHub Actions は、GitHub に統合された自動化プラットフォームです。すべての自動化は以下に基づいています 正確な階層を形成する 4 つの主要な概念:
GitHub アクションの階層
| コンセプト | 説明 | 類推 |
|---|---|---|
| ワークフロー | YAML ファイル .github/workflows/ これは自動化全体を定義します |
完全なレシピ |
| 求人 | 特定のランナーに対して実行されるステップのグループ | レシピのフェーズ |
| ステップ | ジョブ内の単一のコマンドまたはアクション | 具体的な指示 |
| トリガー | ワークフローを開始するイベント (プッシュ、PR、スケジュールなど) | 始める時間 |
ワークフローには複数のジョブを含めることができ、各ジョブには複数のステップを含めることができます。ジョブが実行される デフォルトでは並列ですが、依存関係を使用して順次実行するように構成できます。
YAML ワークフローの構造
各ワークフローはディレクトリに存在します。 .github/workflows/ リポジトリの。ここにあります
ワークフロー ファイルの基本構造:
# .github/workflows/ci.yml
name: CI Pipeline
# Trigger: quando eseguire il workflow
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
# Variabili di ambiente globali
env:
NODE_VERSION: '20'
# I job da eseguire
jobs:
build:
# Runner: macchina virtuale su cui eseguire
runs-on: ubuntu-latest
# Step del job
steps:
# Step 1: Checkout del codice
- name: Checkout repository
uses: actions/checkout@v4
# Step 2: Setup Node.js
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
# Step 3: Installazione dipendenze
- name: Install dependencies
run: npm ci
# Step 4: Build
- name: Build application
run: npm run build
主なトリガー
トリガーは、ワークフローがいつ開始されるかを決定します。 GitHub Actions は数十のイベントをサポートします。 ただし、フロントエンド プロジェクトで最もよく使用されるのは次のとおりです。
on:
# Su ogni push ai branch specificati
push:
branches: [main, develop]
paths:
- 'src/**'
- 'package.json'
# Su ogni Pull Request verso main
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
# Esecuzione programmata (cron)
schedule:
- cron: '0 6 * * 1' # Ogni lunedi alle 6:00 UTC
# Trigger manuale
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
プッシュ時のトリガーに注意
フィルター paths 無駄なビルドを避けるのに非常に役立ちます。README のみを編集する場合は、
パイプライン全体を再実行するのは意味がありません。ただし、重要なファイルを除外しないように注意してください
どうやって angular.json o tsconfig.json ビルドに影響を与えるもの。
2. Angular の完全な CI ワークフロー
次に、Angular プロジェクトの完全な継続的インテグレーション ワークフローを構築しましょう。これ ワークフローは、依存関係のインストール、リンティング、単体テスト、実稼働ビルドという順序で実行されます。
# .github/workflows/ci.yml
name: Angular CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '20'
jobs:
lint:
name: Lint Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- run: npx ng lint
test:
name: Unit Tests
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- run: npx ng test --watch=false --browsers=ChromeHeadless --code-coverage
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
retention-days: 7
build:
name: Production Build
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- run: npx ng build --configuration=production
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 3
このワークフローでは、キーワードのおかげで 3 つのジョブを順番に定義します。 needs: 最初に糸くず、
次にテスト、最後にビルドです。 lint が失敗した場合、テストは実行されません。テストが失敗した場合、
ビルドが開始されません。
高度な依存関係キャッシュ
キーワード cache: 'npm' アクションの中で setup-node 基本的なキャッシュを提供します。
より詳細に制御するには、アクションを直接使用できます。 actions/cache:
- name: Cache node_modules
id: cache-npm
uses: actions/cache@v4
with:
path: |
node_modules
~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
if: steps.cache-npm.outputs.cache-hit != 'true'
run: npm ci
キャッシュキーはファイルのハッシュを使用します package-lock.json: 依存症のとき
それらは変更されず、キャッシュが再利用され、インストールは完全にスキップされます。これ
実行ごとにパイプライン時間を 30 ~ 60 秒短縮できます。
3. マトリックス戦略: マルチバージョンテスト
La マトリックス戦略 同じジョブを異なる組み合わせで実行できます パラメータの。 Angular プロジェクトの場合、特に Node.js の複数のバージョンにわたるテストに役立ちます。
test-matrix:
name: Test on Node ${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npx ng test --watch=false --browsers=ChromeHeadless
オプション fail-fast: false すべてのマトリックス ジョブが完了することを保証します
たとえ 1 つが失敗したとしても、1 回の実行ですべての非互換性を特定できます。
マトリックス戦略をいつ使用するか
- 複数のバージョンの Node.js (現在および以前の LTS) をテストする
- 複数のオペレーティング システム (ubuntu、windows、macos) でのテスト
- さまざまな環境 (ステージング、実稼働) 向けにビルドする
- さまざまなブラウザバージョンでのテスト
4. CD: Firebase への自動デプロイ
アプリケーションを構築してテストした後、次のステップは自動デプロイです。 最も一般的な選択肢の 1 つである Firebase Hosting でデプロイを構成する方法を見てみましょう。 Angular アプリケーション。
# .github/workflows/deploy.yml
name: Deploy to Firebase
on:
push:
branches: [main]
jobs:
build-and-deploy:
name: Build and Deploy to Production
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build for production
run: npm run build
- name: Deploy to Firebase Hosting
uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
channelId: live
projectId: my-angular-project
プルリクエストのプレビューデプロイ
Firebase Hosting の強力な機能とプレビュー チャネルを作成する機能 プル リクエストごとに自動的に行われるため、チームはマージ前に変更を確認できます。
# .github/workflows/preview.yml
name: Deploy Preview
on:
pull_request:
branches: [main]
jobs:
preview:
name: Deploy Preview Channel
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Deploy to Preview Channel
uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
projectId: my-angular-project
# Senza channelId: crea automaticamente un preview channel
Vercel にデプロイする
ホスティング プラットフォームとして Vercel を好む人にとって、構成は同じです シンプル:
# .github/workflows/deploy-vercel.yml
name: Deploy to Vercel
on:
push:
branches: [main]
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Vercel CLI
run: npm install -g vercel
- name: Pull Vercel Configuration
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Build with Vercel
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy to Vercel
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
5. アーティファクト: ジョブ間でファイルを共有する
Gli アーティファクト 同じワークフローの異なるジョブ間でファイルを共有できるようになります。 これは、再コンパイルせずにビルドとデプロイメントを分離するために不可欠です。
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npx ng build --configuration=production
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: angular-dist
path: dist/my-app/browser/
retention-days: 1
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: angular-dist
path: dist/
- name: Deploy
run: |
# Il contenuto della build e ora in dist/
ls -la dist/
アーティファクトのベスト プラクティス
- 常に設定する
retention-days保管スペースの無駄を避けるために - アーティファクトにはわかりやすい名前を使用します (
angular-dist,coverage-report) - ディレクトリ全体ではなく、必要なファイルのみをアップロードしてください
node_modules - 非常に大きなファイルの場合は、アップロードする前に圧縮を検討してください
6. ブランチ保護ルール
Le ブランチ保護ルール GitHub の機能により、ブランチに制約を課すことができます 批評家。 CI ワークフローと組み合わせると、自動的に品質の壁が作成されます。
ブランチ保護ルールを設定するには、次の場所に移動します。
設定 > ブランチ > ブランチ保護ルールの追加 GitHub リポジトリ内にあります。
ブランチの推奨設定 main 私は:
- マージする前にプルリクエストを要求する: メインへの直接プッシュを防止します
- マージ前にステータスチェックに合格する必要がある: CI ワークフローは合格する必要があります
- マージする前にブランチを最新の状態にする必要がある: ブランチを更新する必要があります
- マージする前に会話の解決が必要です: すべてのコメントに対処する必要があります
どのステータス チェックを要求するかを選択するには、まずワークフローを少なくとも 1 回実行する必要があります。 その後、ジョブ名が選択リストに表示されます。
Status checks richiesti:
[x] Lint Check (dal workflow CI)
[x] Unit Tests (dal workflow CI)
[x] Production Build (dal workflow CI)
7. 再利用可能なワークフロー
同様の構成で複数のリポジトリを管理する場合、 再利用可能なワークフロー
コードの重複を避けます。再利用可能なワークフローはトリガーで定義されます
workflow_call:
# .github/workflows/reusable-angular-ci.yml
name: Reusable Angular CI
on:
workflow_call:
inputs:
node-version:
description: 'Node.js version'
required: false
default: '20'
type: string
build-command:
description: 'Build command to execute'
required: false
default: 'npm run build'
type: string
secrets:
FIREBASE_SA:
description: 'Firebase Service Account'
required: false
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
- run: npx ng lint
- run: npx ng test --watch=false --browsers=ChromeHeadless
- run: ${{ inputs.build-command }}
この再利用可能なワークフローを別のワークフローから使用するには:
# .github/workflows/ci.yml (nel repository che lo consuma)
name: CI
on:
push:
branches: [main]
jobs:
angular-ci:
uses: my-org/shared-workflows/.github/workflows/reusable-angular-ci.yml@main
with:
node-version: '20'
build-command: 'npm run build -- --configuration=production'
secrets:
FIREBASE_SA: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
再利用可能なワークフローの利点
- ドライ: CI/CD ロジックの単一メンテナンス ポイント
- 標準化: すべてのリポジトリは同じプラクティスに従います
- バージョン管理: ワークフローの特定のバージョンを報告できます (
@main,@v1) - 安全性: シークレットは明示的に渡され、グローバルに共有されません
8. 完全な例: エンドツーエンドのパイプライン
すべての概念を、ブランチ保護を備えた CI と CD を処理する完全なパイプラインに結合します。
# .github/workflows/pipeline.yml
name: Full Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: '20'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- run: npx ng lint
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- run: npx ng test --watch=false --browsers=ChromeHeadless --code-coverage
- uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage/
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- run: npx ng build --configuration=production
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
deploy-preview:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
projectId: my-angular-project
deploy-production:
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
needs: build
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
channelId: live
projectId: my-angular-project
オプション concurrency ワークフローの一番上で重要な点: 複数のプッシュを近くで実行した場合
同じブランチでは、以前のワークフローが自動的に削除され、時間を節約できます。
実行の。
9. デバッグとベストプラクティス
ワークフローが失敗すると、デバッグがイライラすることがあります。最も効果的な戦略は次のとおりです。
デバッグログを有効にする
リポジトリにシークレットを追加することで、デバッグ ログを有効にできます。
ACTIONS_RUNNER_DEBUG=true詳細なランナーログについてはACTIONS_STEP_DEBUG=true各ステップの詳細なログについては、
デバッグのための条件付きステップ
- name: Debug info
if: failure()
run: |
echo "Node version: $(node -v)"
echo "NPM version: $(npm -v)"
echo "Directory: $(pwd)"
ls -la
cat package.json
GitHub アクションのベスト プラクティス
- アメリカ合衆国
npm ciの代わりにnpm install決定的なインストールの場合 - 常にアクションのバージョンを設定します (
@v4の代わりに@main) - 設定する
concurrency重複したビルドを避けるため - キャッシュを使用して実行時間を短縮する
- 迅速なフィードバックのためにジョブを分割する (lint はビルド後ではなく、すぐに失敗します)
- アメリカ合衆国
environment生産秘密を守るため - Imposta
timeout-minutesブロックされたジョブを回避するには - アカウントプランで GitHub Actions の消費分を追跡します
結論
この記事では、Angular アプリケーション用の完全な CI/CD パイプラインを構築しました。 GitHub アクションを使用します。基本的な概念 (ワークフロー、ジョブ、ステップ、トリガー) を検討しました。 依存関係のキャッシュを実装し、マルチバージョン テスト用のマトリックス戦略を構成しました。 Firebase と Vercel での自動デプロイメントを設定します。
CI/CD パイプラインとプログレッシブ反復で成功する鍵: ワークフローから始める シンプル (lint + ビルド)、次にテストを追加、最後に自動デプロイメント。しようとしないでください すべてを一度に実装します。
シリーズの次の記事では、次のことを検討します。 フロントエンド開発者向けの Docker、 マルチステージ Dockerfile を使用して Angular アプリケーションをコンテナ化し、管理する方法を学習します。 Docker Compose を使用した開発環境。







