swift-travis

一个 Swift 接口,用于访问 travis-ci v3 API。 支持 travis-ci.org, travis-ci.com & 本地部署。

构建状态 | 阅读文档

安装

用例 接口 目标
iOS & Mac 应用 URLSession .product(name: "TravisClient", package: "swift-travis")
CLI & 服务器应用 EventLoopFuture .product(name: "TravisClientNIO", package: "swift-travis")
构建您自己的包 Codable 结构体 .product(name: "TravisV3Core", package: "swift-travis")

快速示例

import TravisClient

let key: String = ProcessInfo().environment["TRAVIS_TOKEN]"!
let client = TravisClient(token: key, host: .org)

client.userBuilds(query: query) { result in
  switch result {
    case let .success(builds):
      builds.count
      builds.first?.pullRequestTitle
    case let .failure(error):
      // error handling
  }
}

Swift NIO 示例

import TravisClientNIO

let key: String = ProcessInfo().environment["TRAVIS_TOKEN]"!
let client = TravisClient(token: key, host: .org) // You can also pass an `EventLoopGroup`

let builds = try client.builds(forRepository: repo).wait()
print(builds.count)
print(builds.first?.pullRequestTitle)

Travis API 概念。

该 API 镜像了官方 Travis API 文档中的名称和概念。

最小化 vs 标准化表示。

每个模型对象都有两种表示形式。 一种包含所有属性的标准表示形式,以及一种包含某些属性的最小化表示形式。

public struct MinimalJob: Codable, Minimal {
  public typealias Full = Job
  public let id: Int
}

public struct Job: Codable {
  public let id: Int
  public let number: String
  public let state: String
  // 10 other properties
}

最小化 vs 标准化 Job 示例 Travis 文档

如果您需要更多信息,可以使用 client.follow(embed:completion:) 方法加载标准表示形式

let build: Meta<Build>
let minimalJob: Embed<MinimalJob> = build.jobs.first! // don't do this in production code

client.follow(embed: minimalJob) { fullJob in
    print(fullJob.state)
}
建模超媒体 API

Travis v3 API 使用自定义的超媒体 API 规范,该规范在 他们的网站上进行了描述TravisV3Core 目标具有通用的 Metadata<Object> 结构体。

@dynamicMemberLookup
public struct Metadata<Object: Codable>: Codable {
  public let type: String
  public let path: String
  public let pagination: Pagination<Object>?
  public let object: Object
}

let builds: Metadata<[Build]>
// dynamicMemberLookup means we can often use Metadata<[Build]> as [Build]
builds.count == builds.object.count

Metadata 允许我们通过 dynamicMemberLookup 直接访问 Pagination 数据和底层 Object

travis API 经常嵌套资源,这使用 Embed<Object> 结构体进行建模。

@dynamicMemberLookup
public struct Embed<Object: Codable>: Codable {
  public let type: String
  public let path: String?
  public let object: Object
}

struct Build {
  public let repository: Embed<MinimalRepository>
  public let branch: Embed<MinimalBranch>
  public let commit: Embed<MinimalCommit>
}

let build: Metadata<Build>
let branchName: String = build.branch.name
链接
import TravisClient

client.activeBuilds { (result: Result<MetaData<[Build]>, TravisError>) in

    /// You can also switch over the result
    switch result {
    case success(let builds: MetaData<[Build]>)
        // Find the number of active builds
        builds.count

        // Find the jobs associated with this build
        guard let job: Embed<MinimalJob> = jobs.first else { return }

        // Each API call returns one resource that has a 'standard representation' full object in this case supports hyper media so you can easily load the full object in a second request.
        client.follow(embed: job) { (jobResult: Result<MetaData<Job>>) in
            print(jobResult)
        }

        // Or follow a paginated request
        client.follow(page: builds.pagination.next) { nextPage in
            print(nextPage)
        }

    case error(let error):
        // handle error
        print(error)
    }
}

运行测试

# JSON parsing tests
> swift test

# Hit the travis.org API
> TRAVIS_TOKEN=YOUR_TOKEN_HERE swift test

仅当您设置了 TRAVIS_TOKEN 环境变量时,集成测试才会运行。 这使用 XCTSkipIf,需要 Xcode 11.4。 或者,您可以调用 swift test --filter TravisClientTests.JSONTests

支持的 swift 版本

如果您使用的是 Swift 5.1 或更高版本,则可以使用最新版本。如果您需要支持 Swift 5 或更旧的版本,请使用版本 0.2.0

TODO