GitLab Runnerがサポートするシェルの種類

GitLab Runnerは異なるシステム上でビルドを実行できるシェルスクリプトジェネレータを実装しています。

シェルスクリプトには、ビルドのすべてのステップを実行するコマンドが含まれています:

  1. git clone
  2. ビルド・キャッシュの復元
  3. ビルドコマンド
  4. ビルド・キャッシュの更新
  5. ビルドアーティファクトの生成とアップロード

Shellには設定オプションはありません。ビルドステップは.gitlab-ci.yml](https://docs.gitlab.com/ee/ci/yaml/index.html#script) の[script ディレクティブで定義されたコマンドから受け取ります。

サポートされているシェルは以下のとおりです:

Shellステータス説明
bash完全サポートBash (Bourne Again Shell)。すべてのコマンドはBashコンテキストで実行されます(すべてのUnixシステムのデフォルト)。
sh完全サポートSh (Bourne shell)。すべてのコマンドはShコンテキストで実行(すべてのUnixシステムでbash のフォールバック)。
powershell完全サポートPowerShellスクリプト。すべてのコマンドはPowerShell Desktopコンテキストで実行されます。GitLab Runner 12.0-13.12では、これは新しいRunnerを登録するときのデフォルトです。
pwsh完全サポートPowerShellスクリプト。すべてのコマンドはPowerShell Coreコンテキストで実行されます。GitLab Runner 14.0以降では、これは新しいRunnerを登録するときのデフォルトです。
cmd非推奨Windowsバッチスクリプト。すべてのコマンドはバッチコンテキストで実行されます。PowerShell Core のために非推奨。shell が指定されていない場合のデフォルトです。PowerShell がデフォルトのシェルである場合に CMD シェルにアクセスする方法について説明します。

デフォルト以外のシェルを選択する場合は、config.toml ファイルでシェルを指定する必要があります。

Sh/Bash シェル

これはすべてのUnixベースのシステムで使用されるデフォルトのシェルです。.gitlab-ci.yml で使用される Bash スクリプトは、以下のコマンドのいずれかにシェルスクリプトをパイプすることで実行されます:

# This command is used if the build should be executed in context
# of another user (the shell executor)
cat generated-bash-script | su --shell /bin/bash --login user

# This command is used if the build should be executed using
# the current user, but in a login environment
cat generated-bash-script | /bin/bash --login

# This command is used if the build should be executed in
# a Docker environment
cat generated-bash-script | /bin/bash

シェル・プロファイルの読み込み

特定のExecutorでは、Runnerは上記のように--login フラグを渡し、シェルプロファイルもロードします。.bashrc.bash_logoutまたは他のドットファイルにあるものはすべてジョブで実行されます。

のジョブがPrepare environment のステージで失敗する場合、シェルプロファイルの何かが失敗の原因になっている可能性があります。よくある失敗は、コンソールをクリアしようとする.bash_logout がある場合です。

このエラーをトラブルシューティングするには、/home/gitlab-runner/.bash_logout をチェックしてください。たとえば、.bash_logout ファイルに以下のようなスクリプトセクションがある場合、それをコメントアウトしてパイプラインを再起動します:

if [ "$SHLVL" = 1 ]; then
    [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q
fi

シェルプロファイルをロードする Executor:

  • shell
  • parallels (対象仮想マシンのシェルプロファイルがロードされます)
  • virtualbox (対象仮想マシンのシェルプロファイルがロードされます)
  • ssh (ターゲットマシンのシェルプロファイルがロードされます)

PowerShell

PowerShell Desktop Editionは、GitLab Runner 12.0-13.12を使ってWindows上で新しいランナーが登録されたときのデフォルトのシェルです。14.0以降では、デフォルトはPowerShell Core Editionです。

PowerShellは他のユーザーのコンテキストでビルドを実行することをサポートしていません。

生成されたPowerShellスクリプトは、その内容をファイルに保存し、ファイル名を以下のコマンドに渡すことで実行されます:

  • PowerShell デスクトップ版の場合:

     powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command generated-windows-powershell.ps1
    
  • PowerShell Core Edition用:

     pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command generated-windows-powershell.ps1
    

PowerShellスクリプトの例です:

$ErrorActionPreference = "Continue" # This will be set to 'Stop' when targetting PowerShell Core

echo "Running on $([Environment]::MachineName)..."

& {
  $CI="true"
  $env:CI=$CI
  $CI_COMMIT_SHA="db45ad9af9d7af5e61b829442fd893d96e31250c"
  $env:CI_COMMIT_SHA=$CI_COMMIT_SHA
  $CI_COMMIT_BEFORE_SHA="d63117656af6ff57d99e50cc270f854691f335ad"
  $env:CI_COMMIT_BEFORE_SHA=$CI_COMMIT_BEFORE_SHA
  $CI_COMMIT_REF_NAME="main"
  $env:CI_COMMIT_REF_NAME=$CI_COMMIT_REF_NAME
  $CI_JOB_ID="1"
  $env:CI_JOB_ID=$CI_JOB_ID
  $CI_REPOSITORY_URL="Z:\Gitlab\tests\test"
  $env:CI_REPOSITORY_URL=$CI_REPOSITORY_URL
  $CI_PROJECT_ID="1"
  $env:CI_PROJECT_ID=$CI_PROJECT_ID
  $CI_PROJECT_DIR="Z:\Gitlab\tests\test\builds\0\project-1"
  $env:CI_PROJECT_DIR=$CI_PROJECT_DIR
  $CI_SERVER="yes"
  $env:CI_SERVER=$CI_SERVER
  $CI_SERVER_NAME="GitLab CI"
  $env:CI_SERVER_NAME=$CI_SERVER_NAME
  $CI_SERVER_VERSION=""
  $env:CI_SERVER_VERSION=$CI_SERVER_VERSION
  $CI_SERVER_REVISION=""
  $env:CI_SERVER_REVISION=$CI_SERVER_REVISION
  $GITLAB_CI="true"
  $env:GITLAB_CI=$GITLAB_CI
  $GIT_SSL_CAINFO=""
  New-Item -ItemType directory -Force -Path "C:\GitLab-Runner\builds\0\project-1.tmp" | out-null
  $GIT_SSL_CAINFO | Out-File "C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO"
  $GIT_SSL_CAINFO="C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO"
  $env:GIT_SSL_CAINFO=$GIT_SSL_CAINFO
  $CI_SERVER_TLS_CA_FILE=""
  New-Item -ItemType directory -Force -Path "C:\GitLab-Runner\builds\0\project-1.tmp" | out-null
  $CI_SERVER_TLS_CA_FILE | Out-File "C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE"
  $CI_SERVER_TLS_CA_FILE="C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE"
  $env:CI_SERVER_TLS_CA_FILE=$CI_SERVER_TLS_CA_FILE
  echo "Cloning repository..."
  if( (Get-Command -Name Remove-Item2 -Module NTFSSecurity -ErrorAction SilentlyContinue) -and (Test-Path "C:\GitLab-Runner\builds\0\project-1" -PathType Container) ) {
    Remove-Item2 -Force -Recurse "C:\GitLab-Runner\builds\0\project-1"
  } elseif(Test-Path "C:\GitLab-Runner\builds\0\project-1") {
    Remove-Item -Force -Recurse "C:\GitLab-Runner\builds\0\project-1"
  }

  & "git" "clone" "https://gitlab.com/group/project.git" "Z:\Gitlab\tests\test\builds\0\project-1"
  if(!$?) { Exit $LASTEXITCODE }

  cd "C:\GitLab-Runner\builds\0\project-1"
  if(!$?) { Exit $LASTEXITCODE }

  echo "Checking out db45ad9a as main..."
  & "git" "checkout" "db45ad9af9d7af5e61b829442fd893d96e31250c"
  if(!$?) { Exit $LASTEXITCODE }

  if(Test-Path "..\..\..\cache\project-1\pages\main\cache.tgz" -PathType Leaf) {
    echo "Restoring cache..."
    & "gitlab-runner-windows-amd64.exe" "extract" "--file" "..\..\..\cache\project-1\pages\main\cache.tgz"
    if(!$?) { Exit $LASTEXITCODE }

  } else {
    if(Test-Path "..\..\..\cache\project-1\pages\main\cache.tgz" -PathType Leaf) {
      echo "Restoring cache..."
      & "gitlab-runner-windows-amd64.exe" "extract" "--file" "..\..\..\cache\project-1\pages\main\cache.tgz"
      if(!$?) { Exit $LASTEXITCODE }

    }
  }
}
if(!$?) { Exit $LASTEXITCODE }

& {
  $CI="true"
  $env:CI=$CI
  $CI_COMMIT_SHA="db45ad9af9d7af5e61b829442fd893d96e31250c"
  $env:CI_COMMIT_SHA=$CI_COMMIT_SHA
  $CI_COMMIT_BEFORE_SHA="d63117656af6ff57d99e50cc270f854691f335ad"
  $env:CI_COMMIT_BEFORE_SHA=$CI_COMMIT_BEFORE_SHA
  $CI_COMMIT_REF_NAME="main"
  $env:CI_COMMIT_REF_NAME=$CI_COMMIT_REF_NAME
  $CI_JOB_ID="1"
  $env:CI_JOB_ID=$CI_JOB_ID
  $CI_REPOSITORY_URL="Z:\Gitlab\tests\test"
  $env:CI_REPOSITORY_URL=$CI_REPOSITORY_URL
  $CI_PROJECT_ID="1"
  $env:CI_PROJECT_ID=$CI_PROJECT_ID
  $CI_PROJECT_DIR="Z:\Gitlab\tests\test\builds\0\project-1"
  $env:CI_PROJECT_DIR=$CI_PROJECT_DIR
  $CI_SERVER="yes"
  $env:CI_SERVER=$CI_SERVER
  $CI_SERVER_NAME="GitLab CI"
  $env:CI_SERVER_NAME=$CI_SERVER_NAME
  $CI_SERVER_VERSION=""
  $env:CI_SERVER_VERSION=$CI_SERVER_VERSION
  $CI_SERVER_REVISION=""
  $env:CI_SERVER_REVISION=$CI_SERVER_REVISION
  $GITLAB_CI="true"
  $env:GITLAB_CI=$GITLAB_CI
  $GIT_SSL_CAINFO=""
  New-Item -ItemType directory -Force -Path "C:\GitLab-Runner\builds\0\project-1.tmp" | out-null
  $GIT_SSL_CAINFO | Out-File "C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO"
  $GIT_SSL_CAINFO="C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO"
  $env:GIT_SSL_CAINFO=$GIT_SSL_CAINFO
  $CI_SERVER_TLS_CA_FILE=""
  New-Item -ItemType directory -Force -Path "C:\GitLab-Runner\builds\0\project-1.tmp" | out-null
  $CI_SERVER_TLS_CA_FILE | Out-File "C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE"
  $CI_SERVER_TLS_CA_FILE="C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE"
  $env:CI_SERVER_TLS_CA_FILE=$CI_SERVER_TLS_CA_FILE
  cd "C:\GitLab-Runner\builds\0\project-1"
  if(!$?) { Exit $LASTEXITCODE }

  echo "`$ echo true"
  echo true
}
if(!$?) { Exit $LASTEXITCODE }

& {
  $CI="true"
  $env:CI=$CI
  $CI_COMMIT_SHA="db45ad9af9d7af5e61b829442fd893d96e31250c"
  $env:CI_COMMIT_SHA=$CI_COMMIT_SHA
  $CI_COMMIT_BEFORE_SHA="d63117656af6ff57d99e50cc270f854691f335ad"
  $env:CI_COMMIT_BEFORE_SHA=$CI_COMMIT_BEFORE_SHA
  $CI_COMMIT_REF_NAME="main"
  $env:CI_COMMIT_REF_NAME=$CI_COMMIT_REF_NAME
  $CI_JOB_ID="1"
  $env:CI_JOB_ID=$CI_JOB_ID
  $CI_REPOSITORY_URL="Z:\Gitlab\tests\test"
  $env:CI_REPOSITORY_URL=$CI_REPOSITORY_URL
  $CI_PROJECT_ID="1"
  $env:CI_PROJECT_ID=$CI_PROJECT_ID
  $CI_PROJECT_DIR="Z:\Gitlab\tests\test\builds\0\project-1"
  $env:CI_PROJECT_DIR=$CI_PROJECT_DIR
  $CI_SERVER="yes"
  $env:CI_SERVER=$CI_SERVER
  $CI_SERVER_NAME="GitLab CI"
  $env:CI_SERVER_NAME=$CI_SERVER_NAME
  $CI_SERVER_VERSION=""
  $env:CI_SERVER_VERSION=$CI_SERVER_VERSION
  $CI_SERVER_REVISION=""
  $env:CI_SERVER_REVISION=$CI_SERVER_REVISION
  $GITLAB_CI="true"
  $env:GITLAB_CI=$GITLAB_CI
  $GIT_SSL_CAINFO=""
  New-Item -ItemType directory -Force -Path "C:\GitLab-Runner\builds\0\project-1.tmp" | out-null
  $GIT_SSL_CAINFO | Out-File "C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO"
  $GIT_SSL_CAINFO="C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO"
  $env:GIT_SSL_CAINFO=$GIT_SSL_CAINFO
  $CI_SERVER_TLS_CA_FILE=""
  New-Item -ItemType directory -Force -Path "C:\GitLab-Runner\builds\0\project-1.tmp" | out-null
  $CI_SERVER_TLS_CA_FILE | Out-File "C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE"
  $CI_SERVER_TLS_CA_FILE="C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE"
  $env:CI_SERVER_TLS_CA_FILE=$CI_SERVER_TLS_CA_FILE
  cd "C:\GitLab-Runner\builds\0\project-1"
  if(!$?) { Exit $LASTEXITCODE }

  echo "Archiving cache..."
  & "gitlab-runner-windows-amd64.exe" "archive" "--file" "..\..\..\cache\project-1\pages\main\cache.tgz" "--path" "vendor"
  if(!$?) { Exit $LASTEXITCODE }

}
if(!$?) { Exit $LASTEXITCODE }

Windowsバッチの実行

PowerShell に移植されていない古いバッチスクリプトについては、Start-Process "cmd.exe" "/c C:\Path\file.bat" を使って PowerShell からバッチスクリプトを実行できます。

Windows Batch

note
GitLab 11.11では、cmd GitLab Runnerの cmdWindowsバッチ実行ツールであるcmd Shellを cmd 廃止cmdPowerShellをcmd採用することを発表しました。cmd Shellは cmdGitLab Runnerの将来のバージョンにも含まれますが、Windows用の新機能はPowerShellでのみテストされ、サポートされます。cmd シェルに対する致命的なバグやリグレッションのみが調査され、修正されます。

PowerShell に移植されていない古いバッチスクリプトについては、Start-Process "cmd.exe" "/c C:\Path\file.bat" を使って PowerShell からバッチスクリプトを実行できます。

Windows バッチは、shell が指定されていない場合に Windows で使用されるデフォルトのシェルです。

他のユーザーのコンテキストでビルドを実行することはできません。

生成されたバッチスクリプトは、その内容をファイルに保存し、ファイル名を以下のコマンドに渡すことで実行されます:

cmd /Q /C generated-windows-batch.cmd

これがバッチスクリプトの例です:

@echo off
setlocal enableextensions
setlocal enableDelayedExpansion
set nl=^


echo Running on %COMPUTERNAME%...

call :prescript
IF !errorlevel! NEQ 0 exit /b !errorlevel!

call :buildscript
IF !errorlevel! NEQ 0 exit /b !errorlevel!

call :postscript
IF !errorlevel! NEQ 0 exit /b !errorlevel!

goto :EOF
:prescript
SET CI=true
SET CI_COMMIT_SHA=db45ad9af9d7af5e61b829442fd893d96e31250c
SET CI_COMMIT_BEFORE_SHA=d63117656af6ff57d99e50cc270f854691f335ad
SET CI_COMMIT_REF_NAME=main
SET CI_JOB_ID=1
SET CI_REPOSITORY_URL=http://gitlab.example.com/group/project.git
SET CI_PROJECT_ID=1
SET CI_PROJECT_DIR=Z:\Gitlab\tests\test\builds\0\project-1
SET CI_SERVER=yes
SET CI_SERVER_NAME=GitLab CI
SET CI_SERVER_VERSION=
SET CI_SERVER_REVISION=
SET GITLAB_CI=true
md "C:\\GitLab-Runner\\builds\\0\\project-1.tmp" 2>NUL 1>NUL
echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO
SET GIT_SSL_CAINFO=C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO
md "C:\\GitLab-Runner\\builds\\0\\project-1.tmp" 2>NUL 1>NUL
echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
SET CI_SERVER_TLS_CA_FILE=C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
echo Cloning repository...
rd /s /q "C:\GitLab-Runner\builds\0\project-1" 2>NUL 1>NUL
"git" "clone" "http://gitlab.example.com/group/project.git" "Z:\Gitlab\tests\test\builds\0\project-1"
IF !errorlevel! NEQ 0 exit /b !errorlevel!

cd /D "C:\GitLab-Runner\builds\0\project-1"
IF !errorlevel! NEQ 0 exit /b !errorlevel!

echo Checking out db45ad9a as main...
"git" "checkout" "db45ad9af9d7af5e61b829442fd893d96e31250c"
IF !errorlevel! NEQ 0 exit /b !errorlevel!

IF EXIST "..\..\..\cache\project-1\pages\main\cache.tgz" (
  echo Restoring cache...
  "gitlab-runner-windows-amd64.exe" "extract" "--file" "..\..\..\cache\project-1\pages\main\cache.tgz"
  IF !errorlevel! NEQ 0 exit /b !errorlevel!

) ELSE (
  IF EXIST "..\..\..\cache\project-1\pages\main\cache.tgz" (
    echo Restoring cache...
    "gitlab-runner-windows-amd64.exe" "extract" "--file" "..\..\..\cache\project-1\pages\main\cache.tgz"
    IF !errorlevel! NEQ 0 exit /b !errorlevel!

  )
)
goto :EOF

:buildscript
SET CI=true
SET CI_COMMIT_SHA=db45ad9af9d7af5e61b829442fd893d96e31250c
SET CI_COMMIT_BEFORE_SHA=d63117656af6ff57d99e50cc270f854691f335ad
SET CI_COMMIT_REF_NAME=main
SET CI_JOB_ID=1
SET CI_REPOSITORY_URL=Z:\Gitlab\tests\test
SET CI_PROJECT_ID=1
SET CI_PROJECT_DIR=Z:\Gitlab\tests\test\builds\0\project-1
SET CI_SERVER=yes
SET CI_SERVER_NAME=GitLab CI
SET CI_SERVER_VERSION=
SET CI_SERVER_REVISION=
SET GITLAB_CI=true
md "C:\\GitLab-Runner\\builds\\0\\project-1.tmp" 2>NUL 1>NUL
echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO
SET GIT_SSL_CAINFO=C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO
md "C:\\GitLab-Runner\\builds\\0\\project-1.tmp" 2>NUL 1>NUL
echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
SET CI_SERVER_TLS_CA_FILE=C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
cd /D "C:\GitLab-Runner\builds\0\project-1"
IF !errorlevel! NEQ 0 exit /b !errorlevel!

echo $ echo true
echo true
goto :EOF

:postscript
SET CI=true
SET CI_COMMIT_SHA=db45ad9af9d7af5e61b829442fd893d96e31250c
SET CI_COMMIT_BEFORE_SHA=d63117656af6ff57d99e50cc270f854691f335ad
SET CI_COMMIT_REF_NAME=main
SET CI_JOB_ID=1
SET CI_REPOSITORY_URL=Z:\Gitlab\tests\test
SET CI_PROJECT_ID=1
SET CI_PROJECT_DIR=Z:\Gitlab\tests\test\builds\0\project-1
SET CI_SERVER=yes
SET CI_SERVER_NAME=GitLab CI
SET CI_SERVER_VERSION=
SET CI_SERVER_REVISION=
SET GITLAB_CI=true
md "C:\\GitLab-Runner\\builds\\0\\project-1.tmp" 2>NUL 1>NUL
echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO
SET GIT_SSL_CAINFO=C:\GitLab-Runner\builds\0\project-1.tmp\GIT_SSL_CAINFO
md "C:\\GitLab-Runner\\builds\\0\\project-1.tmp" 2>NUL 1>NUL
echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
SET CI_SERVER_TLS_CA_FILE=C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
cd /D "C:\GitLab-Runner\builds\0\project-1"
IF !errorlevel! NEQ 0 exit /b !errorlevel!

echo Archiving cache...
"gitlab-runner-windows-amd64.exe" "archive" "--file" "..\..\..\cache\project-1\pages\main\cache.tgz" "--path" "vendor"
IF !errorlevel! NEQ 0 exit /b !errorlevel!

goto :EOF

PowerShellがデフォルトの場合のCMDシェルへのアクセス

プロジェクトCall CMD From Default PowerShell in GitLabCI は、PowerShell が Runner のデフォルトシェルになっているときに CMD シェルにアクセスする方法を示しています。

PowerShellの動作例のビデオ・ウォークスルー

Slicing and Dicing with PowerShell on GitLab CIビデオは、PowerShell Pipelines on GitLab CIGuided Exploration プロジェクトのウォークスルーです。テストは

このサンプルは、自分のグループやインスタンスにコピーしてテストすることができます。 他のGitLab CIパターンがどのようにデモされているかの詳細は、プロジェクトページで確認できます。