コンテンツにスキップ

GitHub Actions@CIツール

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. GitHub Actionsの仕組み

アーキテクチャ

GitHub Actions Runnerは、GitHubリポジトリの設定ファイルをHTTPSで参照し、定義されたパイプラインを実行する。


GitHub Actions Runner

▼ GitHub Actions Runnerとは

GitHub Actionsの設定ファイルで定義されたパイプラインを実行する。

▼ Self hosted Runner

GitHub Actionsのパイプラインをサーバー (例:オンプレサーバー、AWS EC2、など) 上で実行する。


パイプライン構成

記入中...


GitHub Apps

GitHubとは別の実行環境 (例:AWS Lambda) で稼働し、GitHubのAPIをコールする。

github_apps


ビルトインの静的解析

▼ 脆弱性診断

CodeQLを使用して、ソースコードの脆弱性を検証できる。

CodeQL以外の脆弱性診断ツールを使用するよりも、GitHubと連携しやすい。


02. セットアップ

インストール

repository/
├── .github/
│   └── workflows/
│       └── foo.yml


03. name

nameとは

Workflow名を設定する。

name: foo


push

▼ branch

プッシュを検知するブランチを設定する。

ワイルドカード (*) を使用できる。

on:
  push:
    branches:
      - release/**


04. jobs

jobsとは

Workflowの具体的な処理を設定する。


runs-on

GitHub Actionsの実行環境を設定する。

jobs:
  foo:
    runs-on: ubuntu-latest

▼ インストール済みソフトウェア

使用するOSに応じて、いくつかの汎用的なソフトウェアがプリインストールされている。


steps

▼ continue-on-error

同じstepsキー内のrunキーが失敗しても成功扱いにするか否かを設定する。

jobs:
  build:
    steps:
      - continue-on-error: "true"
        run: |
          exit 1
      - if: failure() # 成功扱いのため、このステップには入らない。
        run: |
          echo failure
      - if: success() # 成功扱いのため、このステップに入る。
        run: |
          echo success

▼ if

条件を満たした場合、後続のrunキーを実行する。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - run: |
          # 何らかの処理
      - if: failure() # 失敗した場合、このステップに入る。GitHub Actionsの失敗表記は消えない。
        run: |
          echo failure
      - if: success() # 成功扱いのため、このステップに入る。
        run: |
          echo success

▼ run

任意のコマンドを実行する。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Git config
        run: |
          git config --local user.email "example@gmail.com"
          git config --local user.name "github-actions"
          git config pull.rebase false

▼ uses

使用するActionsを設定する。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

▼ with

Actionsに設定できるパラメーターをわたす。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 7.4
          # これはエラーになってしまう
          # php-version: $PHP_VERSION

注意点として、環境変数を渡せない。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          # これはエラーになってしまう
          php-version: $PHP_VERSION


05. runs

composite

▼ compositeとは

親ファイルのstepsを別のファイルに切り分け、親ファイルでコールできる。

workflowsディレクトリ配下に任意のサブディレクトリを用意し、そこにactionファイルを配置する。

親ファイルでディレクトリを指定すると、actionファイルが自動的に読み込まれる。

repository/
├── .github/
│   └── workflows/
│       ├── foo.yml
│       └── composite/
│           ├── bar/
│           │   └── action.yml
│           │
│           ├── baz/
│           │   └── action.yml
│           │
...        ...
jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Echo
        # compositeのディレクトリを指定する。
        uses: ./.github/workflows/composite/bar

ファイル名は、『action』とする必要がある。

Error: Can't find 'action.yml', 'action.yaml' ...

▼ Secretsは使用不可

compositeでは、Secretsを使用できない。

そのため、inputキーのパラメーターとして渡す必要がある。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Echo
        uses: ./.github/workflows/composite/echo
        # パラメーターで渡す。
        with:
          foo: ${{ secrets.FOO }}
inputs:
  foo:
    description: foo
    required: "true"

runs:
  using: "composite"
  steps:
    - name: Echo
      shell: bash
      run: |
        echo ${{ inputs.foo }}

▼ Checkoutは使用不可

チェックアウト処理は定義できない。

runs:
  using: "composite"
  steps:
    - name: Checkout # これはエラーになってしまう。
      uses: actions/checkout@v2
    - name: Echo
      shell: bash # シェルの種類を設定する。
      run: |
        echo foo

▼ シェルの種類を要指定

もしstepsを定義する場合は、shellキーでシェルの種類を指定する必要がある。

runs:
  using: "composite"
  steps:
    - name: Echo
      shell: bash # シェルの種類を設定する。
      run: |
        echo foo


06. 環境変数

Workflowレベル

▼ Workflowレベルとは

定義されたworkflow (.yamlファイル) 内のみで参照できる。

▼ env

環境変数を定義する。

Secretの値を設定できない。

env:
  FOO: foo
  BAR: bar

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Echo
        run: |
          echo ${{ env.FOO }}


Jobsレベル

▼ Jobsレベルとは

定義されたjobsキー内のみで参照できる。

▼ env

jobs:
  foo:
    runs-on: ubuntu-latest
    env:
      FOO: foo
    steps:
      - name: Echo
        run: |
          echo ${{ env.FOO }}

▼ 環境ファイル

環境ファイル (GITHUB_ENV) に値を入力することにより、job内の環境変数として使用できるようになる。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Export envs
        run: |
          echo "FOO=foo" >> $GITHUB_ENV
      - name: Echo
        run: |
          echo ${FOO}

注意点として、マスキングされた値は入力できない。


Stepレベル

▼ Stepレベルとは

定義されたstepキー内のみで参照できる。

▼ env

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Echo
        env:
          FOO: foo
        run: |
          echo ${{ env.FOO }}


06-02. Secret変数

Secret変数とは

環境変数と同様にしてGitHub Actions内で使用できる。

また、add-maskコマンドと同様のマスキングが最初から実行されている。


マスキング

▼ スコープ

以降の全ての処理でマスキングが実行される。

もちろん、inputsキーで渡した値にもマスキングが維持される。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Echo
        uses: ./.github/workflows/composite/foo
        with:
          bar: ${{ secrets.FOO }}
inputs:
  bar:
    required: "true"

runs:
  using: "composite"
  steps:
    - name: Echo
      shell: bash
      run: |
        FOO=${{ inputs.bar }}

これに関しては以前は非対応であったため、add-maskコマンドを使用した方法がネット上で見つかることに注意する。

▼ 注意点

注意点として、マスキングされる値と同じ文字列が使用されると、これもマスキングされる。

そのため、例えばinputキーでマスキングされた値と同じ文字列を使用してしまうと、.yamlファイルの構文解析でエラーになってしまう。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Echo
        uses: ./.github/workflows/composite/foo
        with:
          foo: ${{ secrets.FOO }}
inputs:
  foo: # マスキングされ、.yamlファイルの構文解析でエラーになってしまう
    required: "true"

runs:
  using: "composite"
  steps:
    - name: Echo
      shell: bash
      run: |
        FOO=${{ inputs.foo }}


変数のスコープレベル

▼ Projectレベル (Repository Secrets)

リポジトリの設定のSecrets項目に変数名と値を登録する。

プロジェクト内、すなわちリポジトリ内で参照できる。

出力された変数の値は、以降の処理でマスキングされる。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Echo
        run: |
          echo ${{ secrets.FOO }}

▼ Actionレベル (Environment Secrets)

リポジトリの設定のEnvironment項目に変数名と値を登録する。

リポジトリ内のGitHub Actionsのみで参照できる。

また、シェルスクリプト内で環境変数を出力するためにも必要である。

出力された変数の値は、以降の処理でマスキングされる。

Projectレベルとは異なり、envキーに明示的に環境変数を渡す必要がある。

jobs:
  foo:
    runs-on: ubuntu-latest
    env:
      FOO: foo
    steps:
      - name: Echo
        run: |
          echo ${{ secrets.FOO }}
          source ./bar.sh

▼ Stepレベル

jobs.foo.steps.envキーに変数名と値を登録する。

ステップ内のみで参照できる。

また、シェルスクリプト内で環境変数を出力するためにも必要である。

出力された変数の値は、以降の処理でマスキングされる。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Echo
        env:
          FOO: foo
        run: |
          echo ${{ secrets.FOO }}
          source ./bar.sh


07. Actions

actionsパッケージ

▼ checkout

プロジェクトをクローンする。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

▼ upload-artifact、download-artifact

異なるjobsの間でファイルを共有する。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Upload artifact
        uses: actions/upload-artifact@v2
        with:
          name: artifact
          path: ./foo
  bar:
    needs: bar
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Download artifact
        uses: actions/download-artifact@v2
        with:
          name: artifact # 展開するアーティファクトを設定する。


08. Workflowコマンド

add-mask

▼ add-maskとは

変数の値をマスキングする。

以降、ログに出力される場合は、『***』のようにアスタリスクで表示される。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Echo
        run: |
          FOO=foo
          echo "::add-mask::${FOO}"
          echo ${FOO}


set-output

▼ set-outputとは

GitHub Actionsのユーザー定義のパラメーターを入力する。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set output
        id: foo_id
        run: |
          echo "::set-output name=FOO::foo"

▼ 同じstep内では使用不可

同じstep内で、パラメーターの入力と出力を行っても、値は空になる。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set output
        id: foo_id
        run: |
          echo "::set-output name=FOO::foo"
          echo ${{ steps.foo_id.outputs.FOO }}

▼ 異なるstep間での共有

入力したパラメーターは、異なるstepの間で出力できる。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set output
        id: foo_id
        run: |
          echo "::set-output name=FOO::foo"
      - name: Echo
        run: |
          echo "${{ steps.foo_id.outputs.FOO }}"

Secretsやadd-maskコマンドでマスキングされた値も共有でき、またマスキングを維持できる。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set output
        id: foo_id
        run: |
          FOO=foo
          echo "::add-mask::${FOO}"
          echo "::set-output name=FOO::${FOO}"
      - name: Echo
        # 共有可能。マスキング維持可能。
        run: |
          echo "${{ steps.foo_id.outputs.FOO }}"

▼ 異なるjob間での共有

入力したパラメーターは、異なるjobの間で出力できる。

先に実行されるjobキーのoutputキーに入力する必要がある。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set output
        id: foo_id
        run: |
          echo "::set-output name=FOO::foo"
    # 後続のjobに渡すパラメーター
    output:
      FOO: ${{ steps.foo_id.outputs.FOO }}
  bar:
    runs-on: ubuntu-latest
    needs: foo
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Echo
        run: |
          echo "${{ needs.foo.outputs.FOO }}"

ただし異なるjobでは、Secretsやadd-maskコマンドでマスキングされた値は共有できず、空になってしまう。

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set output
        id: foo_id
        run: |
          FOO=foo
          echo "::add-mask::${FOO}"
          echo "::set-output name=FOO::${FOO}"
    output:
      FOO: ${{ steps.foo_id.outputs.FOO }}
  bar:
    runs-on: ubuntu-latest
    needs: foo
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      # 空になってしまう。
      - name: Echo
        run: |
          echo "${{ needs.foo.outputs.FOO }}"