Asc Build Lifecycle

Automate ASC build lifecycle management and integrate continuous integration into your software pipeline

Asc Build Lifecycle is a community skill for managing App Store Connect build processing workflows, covering build upload monitoring, processing state tracking, build expiration management, beta testing distribution, and automated build pipeline integration with App Store Connect API.

What Is This?

Overview

Asc Build Lifecycle provides patterns for automating build management through the App Store Connect API. It covers build upload monitoring that tracks builds from upload through processing to ready state, processing state tracking that polls build status and handles processing failures with retry logic, build expiration management that monitors build validity periods and alerts before expiration, beta testing distribution that assigns builds to TestFlight groups and manages external review submissions, and pipeline integration that connects CI systems to App Store Connect for automated build delivery. The skill enables iOS teams to automate the entire build lifecycle from upload to distribution.

Who Should Use This

This skill serves iOS developers automating build upload and TestFlight distribution, DevOps engineers building CI/CD pipelines for App Store submissions, and release managers tracking build processing and testing status.

Why Use It?

Problems It Solves

Build processing status requires manual checking in the App Store Connect dashboard. Expired builds block TestFlight testing when not replaced before the 90-day limit. Distributing builds to the correct beta groups requires manual assignment after each upload. Build processing failures are discovered late when not monitored automatically.

Core Highlights

Build poller tracks processing state from upload through ready for distribution. Expiration tracker alerts when builds approach the 90-day TestFlight limit. Group distributor assigns builds to internal and external beta groups automatically. Pipeline connector triggers distribution workflows from CI build completion.

How to Use It?

Basic Usage

// Build lifecycle monitor
import Foundation

struct BuildMonitor {
  let apiKey: String
  let issuerId: String
  let keyId: String

  func waitForProcessing(
    appId: String,
    version: String,
    buildNumber: String,
    timeout: TimeInterval
      = 1800
  ) async throws -> Build {
    let deadline =
      Date().addingTimeInterval(
        timeout)

    while Date() < deadline {
      let builds =
        try await fetchBuilds(
          appId: appId,
          version: version)

      if let build =
          builds.first(
            where: {
              $0.buildNumber
              == buildNumber
          }) {
        switch build.state {
        case .valid:
          return build
        case .failed:
          throw BuildError
            .processingFailed(
              build.errors)
        case .processing:
          try await Task
            .sleep(for:
              .seconds(30))
        }
      } else {
        try await Task
          .sleep(for:
            .seconds(30))
      }
    }
    throw BuildError
      .timeout
  }
}

Real-World Examples

// TestFlight distribution
struct TestFlightDistributor {
  let api: ASCClient

  func distribute(
    buildId: String,
    groups: [String]
  ) async throws {
    // Add to beta groups
    for groupId in groups {
      try await api.post(
        path: "/v1/builds/"
        + "\(buildId)/"
        + "relationships/"
        + "betaGroups",
        body: RelationData(
          data: [.init(
            type:
              "betaGroups",
            id: groupId)]))
    }
  }

  func checkExpiration(
    appId: String
  ) async throws
      -> [ExpiringBuild] {
    let builds =
      try await api.get(
        path: "/v1/builds",
        query: [
          "filter[app]":
            appId,
          "filter[processing"
          + "State]":
            "VALID"])

    let threshold =
      Date().addingTimeInterval(
        7 * 86400)
    return builds.filter {
      $0.expirationDate
        < threshold
    }.map {
      ExpiringBuild(
        id: $0.id,
        version: $0.version,
        expiresIn: $0
          .expirationDate
          .timeIntervalSince(
            Date()))
    }
  }
}

Advanced Tips

Use webhook-style polling with exponential backoff to reduce API calls during build processing. Track build numbers programmatically to auto-increment on each CI run avoiding duplicate upload rejections. Set up expiration alerts at 7 and 14 days before the 90-day TestFlight limit to ensure replacement builds are ready.

When to Use It?

Use Cases

Monitor build upload processing and automatically distribute to TestFlight groups when ready. Alert the release team when TestFlight builds approach expiration. Integrate App Store Connect build management into a CI/CD pipeline for automated releases.

Related Topics

App Store Connect API, build management, TestFlight distribution, iOS CI/CD, and release automation.

Important Notes

Requirements

App Store Connect API key with appropriate role permissions. Valid Apple Developer Program membership. Xcode or xcodebuild for archive and upload operations.

Usage Recommendations

Do: implement retry logic for transient API errors during build status polling. Monitor build processing failures and alert immediately for quick resolution. Track build expiration dates to maintain continuous TestFlight availability.

Don't: poll build status too frequently as the API has rate limits that throttle excessive requests. Upload builds without incrementing the build number which causes rejection. Distribute builds to external beta groups before internal testing is complete.

Limitations

Build processing time varies from minutes to hours and cannot be predicted reliably. The App Store Connect API rate limits may delay status polling during high-traffic periods. External TestFlight distribution requires Beta App Review which adds variable review time.