Skip to content

シェルアクション

shellアクションはシェルコマンドとスクリプトを安全に実行し、包括的な出力キャプチャとエラーハンドリングを提供します。

基本的な構文

yaml
steps:
  - name: "Execute Build Script"
    uses: shell
    with:
      cmd: "npm run build"
    test: res.code == 0

パラメータ

cmd (必須)

型: String
説明: 実行するシェルコマンド
サポート: テンプレート式

yaml
vars:
  api_url: "{{API_URL}}"

with:
  cmd: "echo 'Hello World'"
  cmd: "npm run {{vars.build_script}}"
  cmd: "curl -f {{vars.api_url}}/health"

shell (オプション)

型: String
デフォルト: /bin/sh
許可値: /bin/sh, /bin/bash, /bin/zsh, /bin/dash, /usr/bin/sh, /usr/bin/bash, /usr/bin/zsh, /usr/bin/dash

yaml
with:
  cmd: "echo $0"
  shell: "/bin/bash"

workdir (オプション)

型: String
説明: コマンド実行用の作業ディレクトリ(絶対パス必須)
サポート: テンプレート式

yaml
with:
  cmd: "pwd && ls -la"
  workdir: "/app/src"
  workdir: "{{vars.project_path}}"

timeout (オプション)

型: String または Duration
デフォルト: 30s
形式: Go duration形式 (30s, 5m, 1h) または数値 (秒)

yaml
with:
  cmd: "npm test"
  timeout: "10m"
  timeout: "300"  # 300秒

env (オプション)

型: Object
説明: コマンドに設定する環境変数
サポート: 値でのテンプレート式

yaml
vars:
  production_api_url: "{{PRODUCTION_API_URL}}"

with:
  cmd: "npm run build"
  env:
    NODE_ENV: "production"
    API_URL: "{{vars.production_api_url}}"
    BUILD_VERSION: "{{vars.version}}"

リトライ機能

shellアクションは統一されたステップレベルのリトライ機能をサポートしています。これにより、一時的な障害やサービス起動時間に対してコマンドを自動的に再実行できます。

yaml
- name: "Wait for Service Startup"
  uses: shell
  with:
    cmd: "curl -f http://localhost:8080/health"
  retry:
    max_attempts: 30      # 最大試行回数 (1-100)
    interval: "2s"        # リトライ間隔
    initial_delay: "5s"   # 初回実行前の待機時間(オプション)
  test: res.code == 0

shellアクションでは、終了コード 0 が成功条件となります。リトライ機能の詳細についてはアクションガイドを参照してください。

レスポンス形式

yaml
res:
  code: 0                    # 終了コード (0 = 成功)
  stdout: "Build successful" # 標準出力
  stderr: ""                 # 標準エラー出力

req:
  cmd: "npm run build"       # 元のコマンド
  shell: "/bin/sh"          # 使用されたシェル
  workdir: "/app"           # 作業ディレクトリ
  timeout: "30s"            # タイムアウト設定
  env:                      # 環境変数
    NODE_ENV: "production"

使用例

基本的なコマンド実行

yaml
- name: "System Information"
  uses: shell
  with:
    cmd: "uname -a"
  test: res.code == 0

ビルドとテストパイプライン

yaml
- name: "Install Dependencies"
  uses: shell
  with:
    cmd: "npm ci"
    workdir: "/app"
    timeout: "5m"
  test: res.code == 0

- name: "Run Tests"
  uses: shell
  with:
    cmd: "npm test"
    workdir: "/app"
    env:
      NODE_ENV: "test"
      CI: "true"
  test: res.code == 0 && (res.stdout | contains("All tests passed"))

環境固有のデプロイ

yaml
vars:
  target_env: "{{TARGET_ENV}}"
  deploy_key: "{{DEPLOY_KEY}}"

- name: "Deploy to Environment"
  uses: shell
  with:
    cmd: "./deploy.sh {{vars.target_env}}"
    workdir: "/deploy"
    shell: "/bin/bash"
    timeout: "15m"
    env:
      DEPLOY_KEY: "{{vars.deploy_key}}"
      TARGET_ENV: "{{vars.target_env}}"
  test: res.code == 0

エラーハンドリングとデバッグ

yaml
- name: "Service Health Check"
  uses: shell
  with:
    cmd: "curl -f http://localhost:8080/health || echo 'Service down'"
  test: res.code == 0 || (res.stderr | contains("Service down"))

- name: "Debug Failed Build"
  uses: shell
  with:
    cmd: "npm run build:debug"
  # デバッグ出力をキャプチャするために失敗を許可
  outputs:
    debug_info: res.stderr

サービス起動とリトライ

yaml
- name: "Wait for Database Startup"
  uses: shell
  with:
    cmd: "pg_isready -h postgres -p 5432"
  retry:
    max_attempts: 30
    interval: "2s"
    initial_delay: "10s"
  test: res.code == 0

- name: "Verify API Health"
  uses: shell
  with:
    cmd: |
      # APIエンドポイントの確認
      curl -f -H "Accept: application/json" \
           http://api:8080/health
  retry:
    max_attempts: 60
    interval: "1s"
  test: res.code == 0

- name: "Wait for Build Artifact"
  uses: shell
  with:
    cmd: |
      # ビルド成果物の確認
      test -f ./dist/app.js && \
      test -s ./dist/app.js
  retry:
    max_attempts: 20
    interval: "500ms"
  test: res.code == 0

セキュリティ機能

シェルアクションはいくつかのセキュリティ対策を実装しています:

  • シェルパス制限: 承認されたシェル実行ファイルのみを許可
  • 作業ディレクトリ検証: 絶対パスとディレクトリの存在を確保
  • タイムアウト保護: 無限実行を防止
  • 環境変数フィルタリング: 環境変数の受け渡しを安全に処理
  • 出力サニタイゼーション: コマンド出力を安全にキャプチャして返す

エラーハンドリング

一般的な終了コードとその意味:

  • 0: 成功
  • 1: 一般的なエラー
  • 2: シェル組み込みコマンドの誤用
  • 126: コマンドを実行できない(権限拒否)
  • 127: コマンドが見つからない
  • 130: Ctrl+Cでスクリプトが終了
  • 255: 終了ステータスが範囲外
yaml
- name: "Handle Different Exit Codes"
  uses: shell
  with:
    cmd: "some_command_that_might_fail"
  test: |
    res.code == 0 ? true :
    res.code == 127 ? (res.stderr | contains("not found")) :
    res.code < 128

Released under the MIT License.