0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

資料 - チュートリアル集

Posted at

資料 - チュートリアル集

はじめに

GitHub Actionsは、リポジトリ内でワークフローを自動化できる強力なCI/CDプラットフォームです。本記事では、GitHub Actionsの公式ドキュメントから得られた包括的な情報をもとに、実践的な使い方から高度な活用方法まで、体系的に解説します。

目次

  1. GitHub Actionsの基礎
  2. ワークフローの作成
  3. 言語別ビルド・テスト環境
  4. 既存CI/CDからの移行
  5. パッケージの公開
  6. プロジェクト管理の自動化
  7. コンテナサービスの活用
  8. Actions Runner Controller (ARC)
  9. 実践的なパターン

1. GitHub Actionsの基礎

1.1 ワークフローの構造

GitHub Actionsのワークフローは、YAMLファイルで定義します。基本的な構造は以下の通りです。

1.2 最小限のワークフロー例

name: 基本ワークフロー
on: [push]

jobs:
  hello-world:
    runs-on: ubuntu-latest
    steps:
      - name: "リポジトリをチェックアウト"
        uses: actions/checkout@v5
      - name: "実行"
        run: echo "Hello, GitHub Actions!"

1.3 主要な構成要素

要素 説明
name ワークフローの名前 CI Pipeline
on トリガーイベント push, pull_request, schedule
jobs 実行するジョブの定義 複数のジョブを並列/直列実行
runs-on 実行環境 ubuntu-latest, windows-latest
steps ジョブ内の実行ステップ アクションまたはコマンド

2. ワークフローの作成

2.1 トリガーイベントの設定

GitHub Actionsは様々なイベントでワークフローをトリガーできます。

on:
  # プッシュイベント
  push:
    branches:
      - main
      - 'feature/**'
    paths:
      - 'src/**'
  
  # プルリクエストイベント
  pull_request:
    branches:
      - main
    types:
      - opened
      - synchronize
  
  # スケジュール実行
  schedule:
    - cron: '0 9 * * 1'  # 毎週月曜日9時
  
  # 手動トリガー
  workflow_dispatch:
    inputs:
      environment:
        description: "デプロイ環境"
        required: true
        default: "staging"

2.2 ジョブの依存関係

ジョブ間の依存関係を定義することで、実行順序を制御できます。

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo "ビルド処理"
  
  test:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - run: echo "テスト処理"
  
  deploy:
    needs: [build, test]
    runs-on: ubuntu-latest
    steps:
      - run: echo "デプロイ処理"

2.3 条件付き実行

if条件を使用して、ステップやジョブの実行を制御できます。

jobs:
  production-deploy:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - name: "本番環境へデプロイ"
        run: echo "本番環境にデプロイします"
      
      - name: "失敗時の処理"
        if: failure()
        run: echo "デプロイに失敗しました"
      
      - name: "常に実行"
        if: always()
        run: echo "結果に関わらず実行"

3. 言語別ビルド・テスト環境

GitHub Actionsは、主要な開発言語に対応したテンプレートと豊富なサポートを提供しています。

3.1 Node.js

name: Node.js CI
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: ['18.x', '20.x', '22.x']
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "Node.js ${{ matrix.node-version }} をセットアップ"
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      
      - name: "依存関係をインストール"
        run: npm ci
      
      - name: "ビルド"
        run: npm run build --if-present
      
      - name: "テスト"
        run: npm test

3.2 Python

name: Python CI
on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.9', '3.10', '3.11', '3.12']
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "Python ${{ matrix.python-version }} をセットアップ"
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: 'pip'
      
      - name: "依存関係をインストール"
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      
      - name: "pytest でテスト"
        run: |
          pip install pytest pytest-cov
          pytest tests.py --cov=src --cov-report=xml

3.3 Java (Maven)

name: Java CI with Maven
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "JDK 17 をセットアップ"
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: maven
      
      - name: "Maven でビルド"
        run: mvn --batch-mode --update-snapshots verify

3.4 Go

name: Go CI
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go-version: ['1.21.x', '1.22.x']
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "Go ${{ matrix.go-version }} をセットアップ"
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}
      
      - name: "依存関係を取得"
        run: go get .
      
      - name: "ビルド"
        run: go build -v ./...
      
      - name: "テスト"
        run: go test -v ./...

3.5 Ruby

name: Ruby CI
on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        ruby-version: ['3.1', '3.2', '3.3']
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "Ruby ${{ matrix.ruby-version }} をセットアップ"
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true
      
      - name: "テスト"
        run: bundle exec rake

3.6 .NET

name: .NET CI
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        dotnet-version: ['6.0.x', '8.0.x']
    
    steps:
      - uses: actions/checkout@v5
      
      - name: ".NET ${{ matrix.dotnet-version }} をセットアップ"
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: ${{ matrix.dotnet-version }}
      
      - name: "依存関係を復元"
        run: dotnet restore
      
      - name: "ビルド"
        run: dotnet build --no-restore
      
      - name: "テスト"
        run: dotnet test --no-build --logger trx

3.7 マトリックス戦略の活用

複数のバージョンや環境でテストを実行する場合、マトリックス戦略が有効です。

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [18, 20, 22]
        exclude:
          - os: macos-latest
            node-version: 18
    
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm test

4. 既存CI/CDからの移行

GitHub Actionsは、既存のCI/CDプラットフォームからの移行を支援する「GitHub Actions Importer」を提供しています。

4.1 サポートされているプラットフォーム

  • Azure DevOps
  • Bamboo
  • Bitbucket Pipelines
  • CircleCI
  • GitLab CI/CD
  • Jenkins
  • Travis CI

4.2 GitHub Actions Importerの使用

4.2.1 インストール

# GitHub CLI拡張機能としてインストール
gh extension install github/gh-actions-importer

# 最新版に更新
gh actions-importer update

4.2.2 認証情報の設定

gh actions-importer configure

対話式のプロンプトで、以下の情報を入力します:

  • GitHub個人アクセストークン(workflowスコープ必須)
  • 移行元CI/CDプラットフォームのアクセストークン
  • インスタンスURL
  • 組織名/プロジェクト名

4.2.3 監査の実行

現在のCI/CDフットプリントを分析します。

# Jenkins の場合
gh actions-importer audit jenkins --output-dir tmp/audit

# GitLab の場合
gh actions-importer audit gitlab --output-dir tmp/audit --namespace my-namespace

# CircleCI の場合
gh actions-importer audit circle-ci --output-dir tmp/audit

監査レポートには以下の情報が含まれます:

  • パイプラインの変換成功率
  • 既知/未知のビルドステップ
  • 手動で対応が必要なタスク
  • 使用されているアクション一覧

4.2.4 ドライラン

実際にプルリクエストを作成せず、変換結果を確認できます。

# Jenkins の場合
gh actions-importer dry-run jenkins \
  --source-url http://jenkins.example.com/job/my-job \
  --output-dir tmp/dry-run

# GitLab の場合
gh actions-importer dry-run gitlab \
  --namespace my-namespace \
  --project my-project \
  --output-dir tmp/dry-run

4.2.5 本番移行

実際にワークフローファイルを作成し、プルリクエストを開きます。

gh actions-importer migrate jenkins \
  --source-url http://jenkins.example.com/job/my-job \
  --target-url https://github.com/organization/repository \
  --output-dir tmp/migrate

4.3 手動移行のポイント

自動移行ツールで対応できない場合、以下のポイントに注意して手動で移行します。

4.3.1 Jenkins からの移行例

Jenkinsfile(Declarative Pipeline)

pipeline {
  agent any
  environment {
    MAVEN_PATH = '/usr/local/maven'
  }
  stages {
    stage('Build') {
      steps {
        sh 'mvn clean install'
      }
    }
    stage('Test') {
      steps {
        sh 'mvn test'
      }
    }
  }
}

GitHub Actions ワークフロー

name: CI
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      MAVEN_PATH: '/usr/local/maven'
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "JDK をセットアップ"
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: maven
      
      - name: "ビルド"
        run: mvn clean install
      
      - name: "テスト"
        run: mvn test

4.3.2 GitLab CI/CD からの移行例

GitLab CI/CD(.gitlab-ci.yml)

image: node:20-bookworm-slim

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/

stages:
  - build
  - test

build:
  stage: build
  script:
    - npm install
    - npm run build

test:
  stage: test
  script:
    - npm test

GitHub Actions ワークフロー

name: CI
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    container: node:20-bookworm-slim
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "依存関係をキャッシュ"
        uses: actions/cache@v4
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      
      - name: "依存関係をインストール"
        run: npm install
      
      - name: "ビルド"
        run: npm run build
      
      - name: "テスト"
        run: npm test

5. パッケージの公開

GitHub Actionsを使用して、ビルド成果物を各種レジストリに公開できます。

5.1 Dockerイメージの公開

5.1.1 Docker Hubへの公開

name: Docker イメージを公開
on:
  release:
    types: [published]

jobs:
  push_to_registry:
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
      attestations: write
      id-token: write
    
    steps:
      - name: "リポジトリをチェックアウト"
        uses: actions/checkout@v5
      
      - name: "Docker Hub にログイン"
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      
      - name: "メタデータを抽出"
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: my-docker-namespace/my-app
      
      - name: "イメージをビルド・プッシュ"
        id: push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
      
      - name: "成果物の証明を生成"
        uses: actions/attest-build-provenance@v2
        with:
          subject-name: index.docker.io/my-docker-namespace/my-app
          subject-digest: ${{ steps.push.outputs.digest }}
          push-to-registry: true

5.1.2 GitHub Packagesへの公開

name: Docker イメージを GitHub Packages に公開
on:
  push:
    branches: ['main']

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      attestations: write
      id-token: write
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "Container registry にログイン"
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: "メタデータを抽出"
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
      
      - name: "イメージをビルド・プッシュ"
        id: push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
      
      - name: "成果物の証明を生成"
        uses: actions/attest-build-provenance@v2
        with:
          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          subject-digest: ${{ steps.push.outputs.digest }}
          push-to-registry: true

5.2 Node.jsパッケージの公開

5.2.1 npmへの公開

name: npm パッケージを公開
on:
  release:
    types: [published]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    
    steps:
      - uses: actions/checkout@v5
      
      - uses: actions/setup-node@v4
        with:
          node-version: '20.x'
          registry-url: 'https://registry.npmjs.org'
      
      - run: npm ci
      
      - name: "公開(provenance付き)"
        run: npm publish --provenance --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

5.2.2 GitHub Packagesへの公開

name: GitHub Packages に公開
on:
  release:
    types: [published]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    
    steps:
      - uses: actions/checkout@v5
      
      - uses: actions/setup-node@v4
        with:
          node-version: '20.x'
          registry-url: 'https://npm.pkg.github.com'
          scope: '@my-org'
      
      - run: npm ci
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

5.3 Javaパッケージの公開(Maven)

name: Maven Central に公開
on:
  release:
    types: [created]

jobs:
  publish:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "JDK をセットアップ"
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          server-id: ossrh
          server-username: MAVEN_USERNAME
          server-password: MAVEN_PASSWORD
      
      - name: "パッケージを公開"
        run: mvn --batch-mode deploy
        env:
          MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
          MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}

5.4 Pythonパッケージの公開(PyPI)

name: PyPI に公開
on:
  release:
    types: [published]

permissions:
  contents: read

jobs:
  release-build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v5
      
      - uses: actions/setup-python@v5
        with:
          python-version: "3.x"
      
      - name: "リリース配布物をビルド"
        run: |
          python -m pip install build
          python -m build
      
      - name: "配布物をアップロード"
        uses: actions/upload-artifact@v4
        with:
          name: release-dists
          path: dist/
  
  pypi-publish:
    runs-on: ubuntu-latest
    needs: release-build
    permissions:
      id-token: write
    
    environment:
      name: pypi
    
    steps:
      - name: "リリース配布物を取得"
        uses: actions/download-artifact@v5
        with:
          name: release-dists
          path: dist/
      
      - name: "PyPI に公開"
        uses: pypa/gh-action-pypi-publish@release/v1

6. プロジェクト管理の自動化

GitHub Actionsを使用して、Issueやプルリクエストの管理を自動化できます。

6.1 Issueへのラベル追加

name: Issue にラベルを追加
on:
  issues:
    types:
      - opened
      - reopened

jobs:
  label_issues:
    runs-on: ubuntu-latest
    permissions:
      issues: write
    
    steps:
      - name: "ラベルを追加"
        run: gh issue edit "$NUMBER" --add-label "$LABELS"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_REPO: ${{ github.repository }}
          NUMBER: ${{ github.event.issue.number }}
          LABELS: triage,needs-investigation

6.2 非アクティブなIssueの自動クローズ

name: 非アクティブな Issue をクローズ
on:
  schedule:
    - cron: "30 1 * * *"

jobs:
  close-issues:
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write
    
    steps:
      - uses: actions/stale@v10
        with:
          days-before-issue-stale: 30
          days-before-issue-close: 14
          stale-issue-label: "stale"
          stale-issue-message: "このIssueは30日間活動がないため、staleとマークされました。"
          close-issue-message: "このIssueはstaleマーク後14日間非アクティブのため、クローズされました。"
          days-before-pr-stale: -1
          days-before-pr-close: -1
          repo-token: ${{ secrets.GITHUB_TOKEN }}

6.3 ラベル追加時のコメント

name: ラベル追加時にコメント
on:
  issues:
    types:
      - labeled

jobs:
  add-comment:
    if: github.event.label.name == 'help wanted'
    runs-on: ubuntu-latest
    permissions:
      issues: write
    
    steps:
      - name: "コメントを追加"
        run: gh issue comment "$NUMBER" --body "$BODY"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_REPO: ${{ github.repository }}
          NUMBER: ${{ github.event.issue.number }}
          BODY: |
            このIssueは誰でも取り組むことができます。
            **プルリクエストでこのIssueを参照してください。**
            ご協力ありがとうございます!

6.4 Issueの定期作成

name: 週次ミーティング Issue を作成
on:
  schedule:
    - cron: '20 7 * * 1'  # 毎週月曜日 7:20 UTC

jobs:
  create_issue:
    runs-on: ubuntu-latest
    permissions:
      issues: write
    
    steps:
      - name: "Issue を作成"
        run: |
          if [[ $CLOSE_PREVIOUS == true ]]; then
            previous_issue_number=$(gh issue list \
              --label "$LABELS" \
              --json number \
              --jq '.[0].number')
            if [[ -n $previous_issue_number ]]; then
              gh issue close "$previous_issue_number"
              gh issue unpin "$previous_issue_number"
            fi
          fi
          new_issue_url=$(gh issue create \
            --title "$TITLE" \
            --assignee "$ASSIGNEES" \
            --label "$LABELS" \
            --body "$BODY")
          if [[ $PINNED == true ]]; then
            gh issue pin "$new_issue_url"
          fi
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_REPO: ${{ github.repository }}
          TITLE: "週次チームミーティング"
          ASSIGNEES: "yamada-taro,suzuki-hanako"
          LABELS: "weekly-sync,team-meeting"
          BODY: |
            ### アジェンダ
            
            - [ ] 録画開始
            - [ ] チェックイン
            - [ ] ディスカッション
            - [ ] 録画終了
            
            ### ディスカッションポイント
            以下に議題を追加してください
            
            - [今週の作業](https://github.com/orgs/my-org/projects/3)
          PINNED: true
          CLOSE_PREVIOUS: true

7. コンテナサービスの活用

GitHub Actionsでは、データベースやキャッシュなどのサービスコンテナを簡単に統合できます。

7.1 サービスコンテナの概要

7.2 PostgreSQLサービスコンテナの使用

7.2.1 コンテナ内でのジョブ実行

name: PostgreSQL サービスを使用
on: [push]

jobs:
  container-job:
    runs-on: ubuntu-latest
    container: node:20-bookworm-slim
    
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "依存関係をインストール"
        run: npm ci
      
      - name: "PostgreSQL に接続"
        run: node client.js
        env:
          POSTGRES_HOST: postgres
          POSTGRES_PORT: 5432

7.2.2 ランナー上での直接実行

name: PostgreSQL サービス
on: [push]

jobs:
  runner-job:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "依存関係をインストール"
        run: npm ci
      
      - name: "PostgreSQL に接続"
        run: node client.js
        env:
          POSTGRES_HOST: localhost
          POSTGRES_PORT: 5432

7.3 Redisサービスコンテナの使用

name: Redis サービス
on: [push]

jobs:
  redis-test:
    runs-on: ubuntu-latest
    
    services:
      redis:
        image: redis:7
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 6379:6379
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "Node.js をセットアップ"
        uses: actions/setup-node@v4
        with:
          node-version: '20.x'
      
      - name: "依存関係をインストール"
        run: npm install
      
      - name: "Redis に接続"
        run: node redis-client.js
        env:
          REDIS_HOST: localhost
          REDIS_PORT: 6379

7.4 複数のサービスコンテナ

name: フルスタックテスト
on: [push]

jobs:
  integration-test:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      
      redis:
        image: redis:7
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      
      elasticsearch:
        image: elasticsearch:8.11.0
        env:
          discovery.type: single-node
          xpack.security.enabled: false
        ports:
          - 9200:9200
        options: >-
          --health-cmd "curl -f http://localhost:9200/_cluster/health"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 10
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "統合テストを実行"
        run: npm run test:integration
        env:
          DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
          REDIS_URL: redis://localhost:6379
          ELASTICSEARCH_URL: http://localhost:9200

8. Actions Runner Controller (ARC)

Actions Runner Controller(ARC)は、Kubernetes上でGitHub Actionsのセルフホストランナーを自動スケーリングするためのKubernetesオペレーターです。

8.1 ARCのアーキテクチャ

8.2 前提条件

ARCを使用するには、以下が必要です:

  • Kubernetesクラスタ(マネージドまたはローカル)
  • Helm 3
  • GitHub個人アクセストークンまたはGitHub App

8.3 ARCのインストール

8.3.1 オペレーターのインストール

# 名前空間を設定
NAMESPACE="arc-systems"

# Helmチャートをインストール
helm install arc \
    --namespace "${NAMESPACE}" \
    --create-namespace \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller

8.3.2 認証の設定

GitHub Appを使用する場合

# GitHub Appの情報をKubernetesシークレットとして作成
kubectl create secret generic arc-github-app \
   --namespace=arc-runners \
   --from-literal=github_app_id=123456 \
   --from-literal=github_app_installation_id=654321 \
   --from-literal=github_app_private_key='-----BEGIN RSA PRIVATE KEY-----...'

個人アクセストークンを使用する場合

# トークンをKubernetesシークレットとして作成
kubectl create secret generic arc-pat \
   --namespace=arc-runners \
   --from-literal=github_token='ghp_your_token_here'

8.3.3 ランナースケールセットの設定

INSTALLATION_NAME="arc-runner-set"
NAMESPACE="arc-runners"
GITHUB_CONFIG_URL="https://github.com/my-org/my-repo"
GITHUB_PAT="ghp_your_token_here"

helm install "${INSTALLATION_NAME}" \
    --namespace "${NAMESPACE}" \
    --create-namespace \
    --set githubConfigUrl="${GITHUB_CONFIG_URL}" \
    --set githubConfigSecret.github_token="${GITHUB_PAT}" \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set

8.4 カスタムランナーイメージの使用

独自のツールやソフトウェアを含むカスタムランナーイメージを使用できます。

values.yaml

githubConfigUrl: "https://github.com/my-org"
githubConfigSecret: arc-github-app

template:
  spec:
    containers:
    - name: runner
      image: my-registry.example.com/custom-runner:latest
      command: ["/home/runner/run.sh"]
      env:
      - name: CUSTOM_ENV_VAR
        value: "custom-value"
      resources:
        requests:
          cpu: "1"
          memory: "2Gi"
        limits:
          cpu: "2"
          memory: "4Gi"

minRunners: 1
maxRunners: 10

controllerServiceAccount:
  namespace: arc-systems
  name: arc-controller

8.5 ワークフローでのARCランナーの使用

name: ARC ランナーを使用
on: [push]

jobs:
  build:
    runs-on: arc-runner-set  # インストール名を指定
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "ランナー情報を表示"
        run: |
          echo "ランナー名: $RUNNER_NAME"
          echo "OS: $RUNNER_OS"
          echo "アーキテクチャ: $RUNNER_ARCH"
      
      - name: "ビルド実行"
        run: ./build.sh

8.6 スケーリングの設定

ARCは需要に応じて自動的にランナーをスケーリングします。

# values.yaml
minRunners: 0          # 最小ランナー数
maxRunners: 100        # 最大ランナー数

# スケーリング動作
# - ジョブがキューに入ると、新しいランナーPodが作成されます
# - ジョブ完了後、ランナーPodは自動的に削除されます
# - 常に0~100の範囲でランナー数が調整されます

9. 実践的なパターン

9.1 アーティファクトの共有

ジョブ間でファイルを共有する場合、アーティファクトを使用します。

name: アーティファクト共有
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      
      - name: "ビルド"
        run: |
          mkdir -p dist
          echo "ビルド成果物" > dist/output.txt
      
      - name: "アーティファクトをアップロード"
        uses: actions/upload-artifact@v4
        with:
          name: build-artifacts
          path: dist/
          retention-days: 5
  
  test:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: "アーティファクトをダウンロード"
        uses: actions/download-artifact@v5
        with:
          name: build-artifacts
          path: dist/
      
      - name: "アーティファクトを確認"
        run: cat dist/output.txt

9.2 キャッシングの活用

依存関係をキャッシュすることで、ワークフローの実行時間を短縮できます。

name: キャッシング
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "Node.js をセットアップ"
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'  # npm キャッシュを自動で処理
      
      - name: "依存関係をインストール"
        run: npm ci
      
      # 手動でキャッシュを管理する場合
      - name: "カスタムキャッシュ"
        uses: actions/cache@v4
        with:
          path: |
            ~/.cache
            .build-cache
          key: ${{ runner.os }}-build-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-

9.3 環境変数とシークレット

name: 環境変数とシークレット
on: [push]

env:
  GLOBAL_VAR: "グローバル変数"

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    env:
      JOB_VAR: "ジョブレベル変数"
    
    steps:
      - name: "環境変数を使用"
        env:
          STEP_VAR: "ステップレベル変数"
        run: |
          echo "グローバル: $GLOBAL_VAR"
          echo "ジョブ: $JOB_VAR"
          echo "ステップ: $STEP_VAR"
      
      - name: "シークレットを使用"
        run: |
          echo "APIキーは安全に管理されています"
        env:
          API_KEY: ${{ secrets.API_KEY }}
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

9.4 再利用可能なワークフロー

# .github/workflows/reusable-workflow.yml
name: 再利用可能なワークフロー

on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
      version:
        required: false
        type: string
        default: 'latest'
    secrets:
      deploy-token:
        required: true
    outputs:
      deployment-url:
        description: "デプロイされたURL"
        value: ${{ jobs.deploy.outputs.url }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    outputs:
      url: ${{ steps.deploy.outputs.url }}
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "デプロイ"
        id: deploy
        run: |
          echo "環境: ${{ inputs.environment }}"
          echo "バージョン: ${{ inputs.version }}"
          echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUT
        env:
          DEPLOY_TOKEN: ${{ secrets.deploy-token }}
# .github/workflows/main.yml
name: メインワークフロー
on: [push]

jobs:
  call-reusable:
    uses: ./.github/workflows/reusable-workflow.yml
    with:
      environment: 'staging'
      version: 'v1.2.3'
    secrets:
      deploy-token: ${{ secrets.DEPLOY_TOKEN }}
  
  verify:
    needs: call-reusable
    runs-on: ubuntu-latest
    steps:
      - run: echo "デプロイ先: ${{ needs.call-reusable.outputs.deployment-url }}"

9.5 コンポジットアクション

複数のステップを1つのアクションにまとめることができます。

# .github/actions/setup-environment/action.yml
name: '環境をセットアップ'
description: 'プロジェクトの環境を一括セットアップ'

inputs:
  node-version:
    description: 'Node.js バージョン'
    required: false
    default: '20'
  cache:
    description: 'キャッシュを有効化'
    required: false
    default: 'true'

outputs:
  cache-hit:
    description: 'キャッシュがヒットしたか'
    value: ${{ steps.cache.outputs.cache-hit }}

runs:
  using: "composite"
  steps:
    - name: "Node.js をセットアップ"
      uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
    
    - name: "依存関係をキャッシュ"
      if: inputs.cache == 'true'
      id: cache
      uses: actions/cache@v4
      with:
        path: node_modules
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      shell: bash
    
    - name: "依存関係をインストール"
      if: steps.cache.outputs.cache-hit != 'true'
      run: npm ci
      shell: bash
# 使用例
name: コンポジットアクションを使用
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      
      - name: "環境をセットアップ"
        uses: ./.github/actions/setup-environment
        with:
          node-version: '20'
          cache: 'true'
      
      - name: "ビルド"
        run: npm run build

9.6 マトリックス戦略の高度な使用

name: 高度なマトリックステスト
on: [push]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [18, 20, 22]
        include:
          - os: ubuntu-latest
            node-version: 20
            experimental: true
            description: "実験的ビルド"
        exclude:
          - os: macos-latest
            node-version: 18
          - os: windows-latest
            node-version: 18
    
    continue-on-error: ${{ matrix.experimental || false }}
    
    steps:
      - uses: actions/checkout@v5
      
      - name: "Node.js ${{ matrix.node-version }} をセットアップ"
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      
      - name: "テスト実行 (${{ matrix.description || 'standard' }})"
        run: npm test
      
      - name: "OS固有の処理"
        if: runner.os == 'Windows'
        run: echo "Windows固有の処理"

まとめ

GitHub Actionsは、単なるCI/CDツールを超えて、開発ワークフロー全体を自動化する強力なプラットフォームです。本記事で紹介した内容を活用することで、以下のような効果が期待できます。

主要な利点

  1. 開発効率の向上

    • 自動化されたビルド・テスト・デプロイメント
    • マトリックス戦略による複数環境での並列テスト
    • キャッシングによる実行時間の短縮
  2. 品質の維持

    • 一貫性のあるテスト実行
    • 自動化されたコードレビュープロセス
    • 成果物の証明による供給チェーンの保護
  3. 運用コストの削減

    • ARCによる柔軟なランナー管理
    • クラウドとセルフホストの適切な使い分け
    • リソースの効率的な利用
  4. 移行の容易性

    • GitHub Actions Importerによる自動移行
    • 主要CI/CDプラットフォームからのスムーズな移行
    • 段階的な移行戦略のサポート

実装のポイント

GitHub Actionsを導入する際は、以下のステップで進めることを推奨します。

  1. 小規模から開始: まずは単純なワークフローから始める
  2. 段階的な拡張: 必要に応じて機能を追加していく
  3. ベストプラクティスの適用: セキュリティとパフォーマンスを意識する
  4. チームでの共有: 再利用可能なワークフローとアクションを作成する
  5. 継続的な改善: メトリクスを測定し、最適化を続ける

GitHub Actionsは継続的に進化しており、新機能が定期的に追加されています。公式ドキュメントを定期的に確認し、最新の機能とベストプラクティスをキャッチアップすることで、より効果的な自動化を実現できます。

本記事が、GitHub Actionsを活用した開発ワークフローの改善に役立てば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?