A Swift interface to the travis-ci v3 API. Supports travis-ci.org, travis-ci.com & on premise deployments.
- Install with SPM
.package(url: "https://github.com/iainsmith/swift-travis", from: "0.3.0"),
- The swift-travis package has the following 3 libraries you can use in your application.
Use-case | interface | target |
---|---|---|
iOS & Mac apps | URLSession | .product(name: "TravisClient", package: "swift-travis") |
CLI & Server APPs | EventLoopFuture | .product(name: "TravisClientNIO", package: "swift-travis") |
Build your own package | Codable structs | .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
}
}
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)
The api mirrors the names & concepts from the official Travis API documentation.
Each model object has two representations. A standard representation that includes all the attributes and a minimal representation that includes some attributes.
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
}
Minimal vs Standard Job Example Travis documentation
If you need more information you can load a standard representation using the client.follow(embed:completion:)
method
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)
}
The Travis v3 API uses a custom hypermedia API spec, that is described on their website. The TravisV3Core
targets has a generic Metadata<Object>
struct.
@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 gives us direct access to the Pagination
data and the underlying Object
through dynamicMemberLookup.
The travis API often nests resources which is modelled with the Embed<Object>
struct.
@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
- You can call
client.follow(page:)
to load the next page of results from the paginated API - Similarly you can call
client.follow(embed:)
to fetch the full version of a MinimalResource. e.gMinimalBranch
->Branch
.
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
The Integration tests only run if you have a TRAVIS_TOKEN
environment variable set. This uses XCTSkipIf
which requires Xcode 11.4. Alternatively you can call swift test --filter TravisClientTests.JSONTests
If you are using Swift 5.1 or newer you can use the latest release
If you need support for Swift 5 or older, use version 0.2.0
- Support paginated requests
- Add User Model
- Add Simple Query parameters
- Add Stages Model
- Add more typed sort parameters
- Support Type safe Eager Loading.