환경 변수와 비밀값
잡에 환경 변수를 넘기는 방법과 규칙, 러너가 미리 넣는 변수, 비밀값을 로그에 남기지 않는 요령과 레시피가 요구하는 변수를 설명합니다
잡 요청의 env는 스크립트가 시작하기 직전에 VM의 환경 변수로 내보내지고, 응답과 잡 조회에는 다시 나오지 않습니다
넘기는 방법
| 진입점 | 방법 |
|---|---|
API POST /v1/jobs | "env": { "NAME": "value" } |
API POST /v1/batches | "env" 모든 잡에 같은 값 |
| 콘솔 플레이그라운드 | 폼의 환경 변수 칸, 한 줄에 NAME=value |
| 콘솔 배치 | 매트릭스의 스킴 축이 XENOCI_SCHEME로 들어감 그 밖의 변수 입력은 없음 |
| CLI, MCP, GitHub Actions | 아직 환경 변수 입력이 없음 스크립트 안에서 정하거나 API를 직접 부름 |
curl -s https://xenoci.com/api/runner/v1/jobs \
-H "Authorization: Bearer $XENOCI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"script": "bash ci.sh",
"env": { "XENOCI_SCHEME": "App", "APP_ENV": "staging", "SENTRY_AUTH_TOKEN": "sntrys_…" },
"source": { "upload_id": "upl_Q2xk7MnP0a" }
}'규칙
- 최대 100개
- 이름은
[A-Za-z_][A-Za-z0-9_]{0,127}(영문, 숫자, 밑줄, 숫자로 시작 불가) - 값은 문자열이고 32,768자 이하 (
.p8키 파일 내용을 그대로 넣을 수 있음) - 어기면
400 invalid_request와details.fields: ["env"]
러너가 미리 넣는 변수
스크립트가 시작할 때 다음 값이 이미 설정되어 있습니다
| 변수 | 값 |
|---|---|
CI | true |
DEVELOPER_DIR | 고른 Xcode의 Developer 폴더 (/Applications/Xcode_27.0.app/Contents/Developer) |
LANG, LC_ALL | en_US.UTF-8 |
HTTPS_PROXY, HTTP_PROXY (소문자 포함) | VM의 외부 접속이 지나는 프록시 주소 |
NO_PROXY | localhost,127.0.0.1 |
PATH | Homebrew(/opt/homebrew/bin)와 Ruby 3.4가 앞에 붙은 경로 |
배치가 만든 잡에는 조합 값인 XENOCI_XCODE, XENOCI_SIMULATOR, XENOCI_SCHEME가 더 들어갑니다
같은 이름을 env에 넣어도 배치 값이 우선합니다
외부 다운로드는 프록시를 지나며 허용되지 않은 호스트는 403으로 막힙니다
스크립트 첫 줄에 러너가 그 안내를 남깁니다
레시피가 요구하는 변수
기본 제공 레시피는 다음 변수를 읽습니다
| 레시피 | 필수 | 선택 |
|---|---|---|
rcp_builtin_ios_build, rcp_builtin_unit_test, rcp_builtin_ui_test, rcp_builtin_archive | XENOCI_SCHEME | XENOCI_SIMULATOR (기본 iPhone 16) |
rcp_builtin_testflight_upload | ASC_KEY_ID, ASC_ISSUER_ID, ASC_KEY_P8 | 없음 |
TestFlight 업로드 레시피는 세 변수가 없으면 VM을 띄우지 않고 400 invalid_request로 거절합니다
응답의 details.missing_env에 빠진 이름, details.guide에 App Store Connect에서 키를 만드는 안내가 들어 있습니다
과금은 없습니다
{
"recipe_id": "rcp_builtin_testflight_upload",
"env": { "ASC_KEY_ID": "ABC123DEFG", "ASC_ISSUER_ID": "11111111-2222-3333-4444-555555555555", "ASC_KEY_P8": "-----BEGIN PRIVATE KEY-----\n…\n-----END PRIVATE KEY-----" },
"source": { "upload_id": "upl_…" }
}이 레시피는 작업 폴더의 서명된 .ipa를 올립니다
서명 인증서와 프로비저닝 프로파일을 보관하는 기능은 아직 없으므로 서명된 .ipa는 소스와 함께 올려야 합니다
비밀값 다루기
env값은 명령줄이 아니라 러너와 VM 사이의 표준 입력으로 전달됩니다, 프로세스 목록에 보이지 않습니다- 잡 조회(
GET /v1/jobs/{job_id}), 잡 목록, 배치 응답에는env와script가 포함되지 않습니다 - 로그는 가려지지 않습니다,
echo "$TOKEN"이나env명령,set -x는 값을 로그에 남기므로 쓰지 마세요 - 잡이 끝나면 VM이 통째로 지워지므로 VM에 쓴 키 파일은 남지 않습니다
- 결과물로 모으는 경로에 키 파일이 섞이지 않게 하세요, 결과물은 7일 동안 내려받을 수 있습니다
- 비밀값은 워크스페이스에 저장해 두는 방식이 아니라 잡마다 요청에 담아 보내는 방식입니다, CI 쪽 시크릿 저장소(GitHub Secrets 등)에 두고 요청을 만들 때 읽으세요
API 키 자체는 Authorization 헤더로만 보내고 env에 넣지 마세요
CLI와 MCP는 출력에서 xci_live_… 문자열을 가리지만 VM 로그는 가리지 않습니다