Skip to Content

예제

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))) } } }

관련 문서

최종 수정 일자: