GitLab Runner가 지원하는 셸 종류

Tier: Free, Premium, Ultimate
Offering: GitLab.com, Self-managed

GitLab Runner는 다양한 시스템에서 빌드를 실행할 수 있도록 해주는 셸 스크립트 생성기를 구현합니다.

셸 스크립트는 빌드의 모든 단계를 실행하는 명령을 포함합니다:

  1. git clone
  2. 빌드 캐시 복원
  3. 빌드 명령
  4. 빌드 캐시 업데이트
  5. 빌드 아티팩트 생성 및 업로드

셸에는 구성 옵션이 없습니다. 빌드 단계는 script 지시문이 정의된 .gitlab-ci.yml에서 수신됩니다.

지원되는 셸은 다음과 같습니다:

Shell Status Description
bash Fully Supported Bash (Bourne Again Shell). 모든 명령은 Bash 컨텍스트에서 실행됩니다(모든 Unix 시스템의 기본값)
sh Fully Supported Sh (Bourne shell). 모든 명령은 Sh 컨텍스트에서 실행됩니다(모든 Unix 시스템의 bash에 대한 폴백)
powershell Fully Supported PowerShell 스크립트입니다. 모든 명령은 PowerShell Desktop 컨텍스트에서 실행됩니다.
pwsh Fully Supported PowerShell 스크립트입니다. 모든 명령은 PowerShell Core 컨텍스트에서 실행됩니다. GitLab Runner 14.0 이상에서는 Windows에서 새 러너를 등록할 때 기본값입니다.

기본값이 아닌 특정 셸을 선택하려면 config.toml 파일에서 셸을 지정해야 합니다.

Sh/Bash 셸

이는 모든 Unix 기반 시스템에서 사용되는 기본 셸입니다. .gitlab-ci.yml에서 사용되는 bash 스크립트는 다음 명령 중 하나에 셸 스크립트를 파이핑하여 실행됩니다:

# 이 명령은 빌드를 다른 사용자(셸 실행자)의 컨텍스트에서 실행해야 하는 경우 사용됩니다.
cat generated-bash-script | su --shell /bin/bash --login user

# 이 명령은 빌드를 현재 사용자로 실행해야 하지만 로그인 환경에서 사용하는 경우 사용됩니다.
cat generated-bash-script | /bin/bash --login

# 이 명령은 빌드를 Docker 환경에서 실행해야 하는 경우 사용됩니다.
cat generated-bash-script | /bin/bash

셸 프로파일 로드

특정 실행자의 경우, 러너는 위와 같이 --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

셸 프로파일을 로드하는 실행기:

  • shell
  • parallels (대상 가상 머신의 셸 프로파일이 로드됩니다)
  • virtualbox (대상 가상 머신의 셸 프로파일이 로드됩니다)
  • ssh (대상 머신의 셸 프로파일이 로드됩니다)

PowerShell

PowerShell Desktop Edition은 GitLab Runner 12.0-13.12를 사용하여 Windows에서 새로운 러너가 등록될 때 기본 셸입니다.

14.0 이상에서는 기본이 PowerShell Core Edition입니다.

PowerShell은 다른 사용자의 컨텍스트에서 빌드를 실행하는 것을 지원하지 않습니다.

생성된 PowerShell 스크립트는 내용을 파일로 저장하고 다음 명령어에 파일 이름을 전달하여 실행됩니다:

  • PowerShell Desktop Edition의 경우:

    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" # 이 값은 PowerShell Core를 대상으로 할 때 'Stop'으로 설정됩니다.

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로 이식되지 않은 배치 스크립트에 해당됩니다.

PowerShell이 기본값일 때 CMD 셸 접근

프로젝트: GitLab CI에서 기본 PowerShell로 CMD 호출하기는 PowerShell이 러너의 기본 셸일 때 CMD 셸에 접근하는 방법을 보여줍니다.

PowerShell 예제 동영상 walkthrough

GitLab CI에서 PowerShell로 Slicing and Dicing 동영상은 GitLab CI의 PowerShell 파이프라인 가이드 탐색 프로젝트에 대한 walkthrough입니다. 이는 다음에서 테스트되었습니다:

이 예제는 테스트를 위해 본인의 그룹이나 인스턴스로 복사할 수 있습니다. 다른 GitLab CI 패턴에 대한 세부정보는 프로젝트 페이지에서 확인할 수 있습니다.

Windows 배치 (제거됨)

이 기능은 GitLab 15.7에서 사용 중단되었습니다 그리고 17.0에서 삭제되었습니다.