콘텐츠로 이동

CI/CD 통합

Framedash CLI는 모든 CI/CD 시스템과 통합할 수 있습니다. 이 가이드에서는 JenkinsTeamCity의 바로 사용 가능한 예시를 다룹니다.

  1. CI 환경에 CLI를 설치합니다:
Terminal window
npm install -g @framedash/cli
  1. 성능 게이트 예시에서는 jqbc를 사용합니다. CI 에이전트에 설치되어 있는지 확인합니다.
  2. Framedash 대시보드의 설정 > API 키에서 API 키를 생성합니다.
  3. 프로젝트 설정 페이지에서 프로젝트 ID를 확인합니다.

CI 시스템의 시크릿 관리에서 다음을 설정합니다:

변수필수설명
FRAMEDASH_API_KEYAPI 키 (업로드: fd_admin_*, 읽기 전용: fd_*)
FRAMEDASH_PROJECT_ID대상 프로젝트 UUID
FRAMEDASH_BASE_URL아니오커스텀 API 호스트 URL (기본값: https://app.framedash.dev)

API 키를 Jenkins 자격 증명(Secret text)으로 저장합니다:

  1. Jenkins 관리 > Credentials > System > Global credentials로 이동합니다
  2. ID framedash-api-keySecret text 자격 증명을 추가합니다
  3. ID framedash-project-idSecret text 자격 증명을 추가합니다

자동 테스트 실행 후 게임 빌드가 텔레메트리 데이터를 전송하고 있는지 확인합니다:

pipeline {
agent any
environment {
FRAMEDASH_API_KEY = credentials('framedash-api-key')
FRAMEDASH_PROJECT_ID = credentials('framedash-project-id')
}
stages {
stage('Build') {
steps {
sh 'your-game-build-command'
}
}
stage('Automated Test') {
steps {
sh 'your-automated-test-command'
}
}
stage('Verify Telemetry') {
steps {
sh '''
framedash auth
framedash status --format json > status.json
echo "Project status:"
framedash status --format table
'''
}
}
}
}

성능 메트릭이 임계값 이하로 떨어지면 빌드를 실패시킵니다:

pipeline {
agent any
environment {
FRAMEDASH_API_KEY = credentials('framedash-api-key')
FRAMEDASH_PROJECT_ID = credentials('framedash-project-id')
}
stages {
stage('Build & Test') {
steps {
sh 'your-game-build-and-test-command'
}
}
stage('Performance Gate') {
steps {
sh '''
RESULT=$(framedash query \
"SELECT avg(fps) as avg_fps, \
avg(frame_time_ms) as avg_frame_time \
FROM events \
WHERE event_name = 'performance_sample' \
AND timestamp > now() - INTERVAL 1 HOUR" \
--format json)
AVG_FPS=$(echo "$RESULT" | jq -r '.data[0].avg_fps // 0')
echo "Average FPS: $AVG_FPS"
if [ "$(echo "$AVG_FPS < 30" | bc -l)" -eq 1 ]; then
echo "FAILED: FPS below 30 threshold ($AVG_FPS)"
exit 1
fi
echo "PASSED: FPS meets threshold"
'''
}
}
}
post {
failure {
echo 'Performance regression detected. Check the Framedash dashboard for details.'
}
}
}

레벨 빌드 후 맵 이미지를 자동으로 업로드합니다:

pipeline {
agent any
environment {
FRAMEDASH_API_KEY = credentials('framedash-api-key')
FRAMEDASH_PROJECT_ID = credentials('framedash-project-id')
}
stages {
stage('Build Level') {
steps {
sh 'your-level-build-command'
}
}
stage('Capture Maps') {
steps {
sh 'your-map-capture-command --output-dir ./map_captures'
}
}
stage('Upload Maps') {
steps {
sh '''
framedash map-capture \
--input-dir ./map_captures \
--upload
'''
}
}
}
}

게임 데이터와 콘텐츠 레지스트리를 동기화합니다:

pipeline {
agent any
environment {
FRAMEDASH_API_KEY = credentials('framedash-api-key')
FRAMEDASH_PROJECT_ID = credentials('framedash-project-id')
}
stages {
stage('Sync Content') {
steps {
sh '''
framedash content import ./game-content.json
echo "Content registry updated"
framedash content list --format table
'''
}
}
}
}

여러 게임 프로젝트를 가진 조직에서는 Jenkins 공유 라이브러리를 생성할 수 있습니다:

vars/framedashReport.groovy
def call(Map config = [:]) {
def queryDays = config.get('days', 7)
withCredentials([
string(credentialsId: config.apiKeyCredentialId ?: 'framedash-api-key', variable: 'FRAMEDASH_API_KEY'),
string(credentialsId: config.projectIdCredentialId ?: 'framedash-project-id', variable: 'FRAMEDASH_PROJECT_ID')
]) {
sh """
echo "Framedash dashboard (${queryDays}-day summary):"
framedash dashboard --days ${queryDays} --format table
"""
}
}

Jenkinsfile에서의 사용:

@Library('your-shared-lib') _
pipeline {
agent any
stages {
stage('Framedash Report') {
steps {
framedashReport(days: 7)
}
}
}
}

빌드 구성에 Configuration Parameters로 추가합니다:

  1. Build Configuration > Parameters로 이동합니다
  2. 파라미터 env.FRAMEDASH_API_KEY를 추가합니다 (타입: Password, spec: password display='hidden')
  3. 파라미터 env.FRAMEDASH_PROJECT_ID를 추가합니다 (타입: Text)

또는 프로젝트 레벨에서 정의하여 빌드 구성 간에 공유할 수 있습니다.

Command Line 빌드 스텝을 추가합니다:

스텝 이름: Verify Framedash Telemetry

#!/bin/bash
set -euo pipefail
echo "Verifying Framedash authentication..."
framedash auth
echo "Project status:"
framedash status --format table

Command Line 빌드 스텝을 추가합니다:

스텝 이름: Framedash Performance Gate

#!/bin/bash
set -euo pipefail
echo "Querying performance metrics..."
RESULT=$(framedash query \
"SELECT avg(fps) as avg_fps, \
avg(frame_time_ms) as avg_frame_time \
FROM events \
WHERE event_name = 'performance_sample' \
AND timestamp > now() - INTERVAL 1 HOUR" \
--format json)
AVG_FPS=$(echo "$RESULT" | jq -r '.data[0].avg_fps // 0')
echo "Average FPS: $AVG_FPS"
if [ "$(echo "$AVG_FPS < 30" | bc -l)" -eq 1 ]; then
echo "##teamcity[buildProblem description='FPS below threshold: $AVG_FPS']"
exit 1
fi
echo "##teamcity[buildStatisticValue key='framedash.avgFps' value='$AVG_FPS']"
echo "Performance gate passed"

Command Line 빌드 스텝을 추가합니다:

스텝 이름: Upload Map Captures

#!/bin/bash
set -euo pipefail
echo "Validating map captures..."
framedash map-capture --input-dir ./map_captures --dry-run
echo "Uploading map captures..."
framedash map-capture --input-dir ./map_captures --upload

전환 퍼널을 추적하는 Command Line 빌드 스텝을 추가합니다:

#!/bin/bash
set -euo pipefail
echo "Funnel analysis (7-day window):"
framedash funnel \
--steps "tutorial_start,tutorial_complete,first_purchase" \
--days 7 \
--format table

Kotlin DSL을 사용하는 TeamCity 프로젝트용:

import jetbrains.buildServer.configs.kotlin.*
import jetbrains.buildServer.configs.kotlin.buildSteps.script
object FramedashPerformanceGate : BuildType({
name = "Framedash Performance Gate"
params {
password("env.FRAMEDASH_API_KEY", "", display = ParameterDisplay.HIDDEN)
text("env.FRAMEDASH_PROJECT_ID", "")
text("framedash.minFps", "30", label = "Minimum FPS Threshold")
}
steps {
script {
name = "Install Framedash CLI"
scriptContent = "npm install -g @framedash/cli"
}
script {
name = "Performance Gate"
scriptContent = """
#!/bin/bash
set -euo pipefail
MIN_FPS=%framedash.minFps%
RESULT=${'$'}(framedash query \
"SELECT avg(fps) as avg_fps FROM events \
WHERE event_name = 'performance_sample' \
AND timestamp > now() - INTERVAL 1 HOUR" \
--format json)
AVG_FPS=${'$'}(echo "${'$'}RESULT" | jq -r '.data[0].avg_fps // 0')
echo "Average FPS: ${'$'}AVG_FPS (threshold: ${'$'}MIN_FPS)"
if [ "${'$'}(echo "${'$'}AVG_FPS < ${'$'}MIN_FPS" | bc -l)" -eq 1 ]; then
echo "##teamcity[buildProblem description='FPS below threshold']"
exit 1
fi
echo "##teamcity[buildStatisticValue key='framedash.avgFps' value='${'$'}AVG_FPS']"
""".trimIndent()
}
}
})

재사용 가능한 메타 러너를 생성합니다. 프로젝트의 .teamcity/pluginData/metaRunners/ 디렉토리에 Framedash_Performance_Gate.xml로 저장합니다:

<?xml version="1.0" encoding="UTF-8"?>
<meta-runner name="Framedash Performance Gate">
<description>Check game performance metrics via Framedash CLI</description>
<settings>
<parameters>
<param name="framedash.minFps" value="30"
spec="text description='Minimum acceptable FPS' label='Min FPS'" />
<param name="framedash.queryDays" value="7"
spec="text description='Number of days to query' label='Query Days'" />
</parameters>
<build-runners>
<runner name="Framedash Performance Gate" type="simpleRunner">
<parameters>
<param name="script.content"><![CDATA[
#!/bin/bash
set -euo pipefail
framedash auth
MIN_FPS=%framedash.minFps%
RESULT=$(framedash query \
"SELECT avg(fps) as avg_fps FROM events \
WHERE event_name = 'performance_sample' \
AND timestamp > now() - INTERVAL %framedash.queryDays% DAY" \
--format json)
AVG_FPS=$(echo "$RESULT" | jq -r '.data[0].avg_fps // 0')
echo "Average FPS: $AVG_FPS (threshold: $MIN_FPS)"
if [ "$(echo "$AVG_FPS < $MIN_FPS" | bc -l)" -eq 1 ]; then
echo "##teamcity[buildProblem description='FPS below threshold: $AVG_FPS < $MIN_FPS']"
exit 1
fi
echo "##teamcity[buildStatisticValue key='framedash.avgFps' value='$AVG_FPS']"
echo "Performance gate passed"
]]></param>
<param name="teamcity.step.mode" value="default" />
<param name="use.custom.script" value="true" />
</parameters>
</runner>
</build-runners>
</settings>
</meta-runner>

framedash query와 SQL 파일로 반복 가능한 검사를 실행합니다:

-- checks/fps-threshold.sql
SELECT
avg(fps) as avg_fps,
min(fps) as min_fps,
quantile(0.05)(fps) as p5_fps
FROM events
WHERE event_name = 'performance_sample'
AND timestamp > now() - INTERVAL 1 DAY
Terminal window
framedash query --file checks/fps-threshold.sql --format json

CI에서의 파싱에는 --format jsonjq를 사용합니다:

Terminal window
# 단일 값 추출
framedash dashboard --days 1 --format json | jq '.data.kpis.totalEvents'
# 프로젝트 상태 확인
framedash status --format json | jq '.data.project.name'

빌드 로그의 가독성에는 --format table을 사용합니다:

Terminal window
framedash dashboard --days 7 --format table
framedash retention --days 30 --format table

성능 요약을 생성하는 나이틀리 빌드를 스케줄링합니다:

#!/bin/bash
set -euo pipefail
echo "=== Framedash Nightly Report ==="
echo ""
echo "--- Project Status ---"
framedash status --format table
echo ""
echo "--- 7-Day Dashboard ---"
framedash dashboard --days 7 --format table
echo ""
echo "--- Player Retention ---"
framedash retention --days 30 --format table
echo ""
echo "--- Alert Rules ---"
framedash alerts list --format table

Error: Unauthorized (401)
  • FRAMEDASH_API_KEY가 설정되어 있고 유효한지 확인합니다
  • framedash auth로 키를 테스트합니다
  • 맵 업로드에는 관리자 키(fd_admin_*)가 필요합니다
Error: Too Many Requests (429)
  • CLI는 X-RateLimit-Reset의 리셋 시간을 표시합니다
  • 파이프라인 스크립트에 백오프 재시도를 추가합니다
  • 더 높은 제한이 필요하면 플랜 업그레이드를 고려합니다

CI 환경에서 프록시를 사용하는 경우:

Terminal window
export HTTPS_PROXY=http://proxy.example.com:8080
framedash auth

CLI가 CI 에이전트의 PATH에 설치되어 있는지 확인합니다:

Terminal window
# 설치 확인
which framedash || npm install -g @framedash/cli
# 글로벌 설치 없이 npx 사용
npx @framedash/cli auth