예제
Deplite Swift SDK로 실제 자주 쓰이는 흐름을 모았어요.
모든 예제는 SwiftPM 의존성 추가가 끝난 상태를 가정해요.
External — 트리거 호출
import Deplite
let deplite = Deplite(apiToken: ProcessInfo.processInfo.environment["DEPLITE_API_TOKEN"]!)
let job = try await deplite.triggers.run(
triggerId: triggerId,
params: ["ref": "main", "actor": "sehyun"],
idempotencyKey: "release-\(UUID().uuidString)"
)
print(job.jobId, job.status)External — 파일 올리고 트리거
let uploaded = try await deplite.files.upload(
fileURL: URL(fileURLWithPath: "/tmp/build.ipa"),
cleanupRule: .ttl(seconds: 3600),
contentType: "application/octet-stream"
)
let job = try await deplite.triggers.run(
triggerId: triggerId,
params: ["ipaFileId": .string(uploaded.id), "ref": .string("main")],
idempotencyKey: "release-\(UUID().uuidString)"
)External — Sync 트리거로 결과까지 한 번에
responseMode: sync로 만들어진 트리거를 호출하면 워크플로우 완료까지 기다리고 output까지 그대로 받아요.
let job = try await deplite.triggers.run(
triggerId: syncTriggerId,
params: ["ref": "v1.2.3"]
)
if job.timedOut {
// responseTimeoutMs 초과. 워크플로우는 백그라운드에서 계속 실행
} else if job.status == "success", case let .object(out)? = job.output {
if case let .string(url)? = out["url"] {
print("Deployed:", url)
}
}Embedded — Agent 운영
키오스크·전시 단말처럼 일반 앱 안에 Agent를 심는 시나리오예요.
첫 실행에서 enroll, 결과를 안전 저장소에 보관, 이후 부팅에선 그 자격으로 SSE를 구독해요.
import Deplite
actor AgentRunner {
private var task: Task<Void, Never>?
func start() async throws {
let stored = try KeychainStore.loadAgent()
let agent = try DepliteAgent(
identity: stored.identity,
privateKey: stored.privateKey
)
// 30초 heartbeat (기본값 일치)
Task {
while !Task.isCancelled {
try? await agent.heartbeat()
try? await Task.sleep(for: .seconds(30))
}
}
task = Task {
do {
for try await event in agent.events() {
switch event {
case .deploy(let payload, _):
await self.handleDeploy(agent: agent, payload: payload)
case .syncWorkflows:
_ = try? await agent.workflows.report(loadLocalWorkflows())
case .revoke:
return
case .ping:
continue
case .unknown(let name, _):
print("unknown event:", name)
}
}
} catch {
// .sseClosed 등 외부 재시도 루프에서 다시 시작
}
}
}
private func handleDeploy(agent: DepliteAgent, payload: DeployPayload) async {
do {
try await agent.jobs.appendLogs(
jobId: payload.jobId,
items: [LogItem(seq: 0, stream: .system, content: "started", level: .info)]
)
let output = try await runWorkflow(payload)
try await agent.jobs.reportResult(
jobId: payload.jobId,
result: .success(output: output)
)
} catch {
try? await agent.jobs.reportResult(
jobId: payload.jobId,
result: .failed(exitCode: 1, errorMessage: "\(error)")
)
}
}
}KeychainStore는 예시명이에요.
실제로는 privateKey(raw 32바이트)는 암호화 후 저장하는 것을 추천드려요.
Embedded — 워크플로우 인벤토리 동기화
syncWorkflows 이벤트가 오면 현재 내가 실행 가능한 워크플로우 목록을 서버에 알려요.
실제 YAML 본문은 보내지 않고 이름과 메타만 보고해요.
func reportWorkflows(agent: DepliteAgent) async throws {
try await agent.workflows.report([
WorkflowReport(name: "deploy-prod", verboseSteps: ["build", "push"], secretsKeys: ["DB_URL"]),
WorkflowReport(name: "healthcheck", verboseSteps: ["ping"]),
])
}에러 처리 — 재시도 가능한 케이스만 백오프
func runWithRetry<T>(max: Int = 3, _ block: () async throws -> T) async throws -> T {
var attempt = 0
while true {
do {
return try await block()
} catch DepliteError.unauthorized {
throw DepliteError.unauthorized(statusCode: 401, body: "")
} catch let DepliteError.api(status, _) where status < 500 && status != 429 {
throw DepliteError.api(statusCode: status, body: "")
} catch {
attempt += 1
if attempt >= max { throw error }
try await Task.sleep(for: .milliseconds(500 * (1 << attempt)))
}
}
}관련 문서
최종 수정 일자: