diff --git a/README.md b/README.md index 6adcfab..3821592 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,7 @@ A Swift library and client for the Buildkite REST and GraphQL APIs. ```swift import Buildkite -let client = BuildkiteClient() -client.token = "..." +let client = BuildkiteClient(token: "...") let response = try await client.send(.pipelines(in: "buildkite")) let pipelines = response.content @@ -17,7 +16,7 @@ print(pipelines) ## Usage -[Getting Started](./Sources/Buildkite/Documentation.docc/Articles/GettingStarted.md) +[Getting Started](./Sources/Buildkite/Buildkite.docc/Articles/GettingStarted.md) ## References diff --git a/Sources/Buildkite/Buildkite.docc/Buildkite.md b/Sources/Buildkite/Buildkite.docc/Buildkite.md index 26df7bb..3e26329 100644 --- a/Sources/Buildkite/Buildkite.docc/Buildkite.md +++ b/Sources/Buildkite/Buildkite.docc/Buildkite.md @@ -26,6 +26,7 @@ The entire publicly documented REST API surface is supported by this package. - ``Organization/Resources`` - ``Pipeline/Resources`` - ``Team/Resources`` +- ``TestAnalytics/Resources`` - ``User/Resources`` - ``Followable`` - ``Resource`` diff --git a/Sources/Buildkite/Models/Trace.swift b/Sources/Buildkite/Models/Trace.swift new file mode 100644 index 0000000..723383c --- /dev/null +++ b/Sources/Buildkite/Models/Trace.swift @@ -0,0 +1,62 @@ +// +// Trace.swift +// Buildkite +// +// Created by Aaron Sky on 6/5/22. +// Copyright © 2022 Aaron Sky. All rights reserved. +// + +import Foundation + +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif + +public struct Trace: Codable, Equatable, Identifiable { + /// a unique identifier for this test result + public var id: UUID + /// a group or topic for the test + /// + /// - `Student.isEnrolled()` + public var scope: String? + /// a name or description for the test + /// + /// - `Manager.isEnrolled()` + /// - `returns_boolean` + public var name: String? + /// a unique identifier for the test. If your test runner supports it, use the identifier needed to rerun this test + /// + /// - `Manager.isEnrolled#returns_boolean` + public var identifier: String? + /// the file and line number where the test originates, separated by a colon (:) + /// + /// - `./tests/Manager/isEnrolled.js:32` + public var location: String? + /// the file where the test originates + /// + /// - `./tests/Manager/isEnrolled.js` + public var fileName: String? + /// the outcome of the test, e.g. `"passed"`, `"failed"`, `"skipped"`, or `"unknown"`` + public var result: String? + /// if applicable, a short summary of why the test failed + /// + /// - `Expected Boolean, got Object` + public var failureReason: String? + /// History object + public var history: Span + + public struct Span: Codable, Equatable { + /// A section category for this span, e.g. `"http"`, `"sql"`, `"sleep"`, or `"annotation"` + public var section: String + /// A monotonically increasing number + public var startAt: TimeInterval? + /// A monotonically increasing number + public var endAt: TimeInterval? + /// How long the span took to run + public var duration: TimeInterval? + /// Any information related to this span + public var detail: [String: String] = [:] + /// array of span objects + public var children: [Span] = [] + } +} diff --git a/Sources/Buildkite/Resources/TestAnalytics/TestAnalyticsUpload.swift b/Sources/Buildkite/Resources/TestAnalytics/TestAnalyticsUpload.swift new file mode 100644 index 0000000..2b50f8f --- /dev/null +++ b/Sources/Buildkite/Resources/TestAnalytics/TestAnalyticsUpload.swift @@ -0,0 +1,79 @@ +// +// TestAnalyticsUpload.swift +// Buildkite +// +// Created by Aaron Sky on 6/5/22. +// Copyright © 2022 Aaron Sky. All rights reserved. +// + +import Foundation + +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif + +public enum TestAnalytics { + /// Resources for requesting information about your organization's Buildkite agents. + public enum Resources {} +} + +extension TestAnalytics.Resources { + /// Get metrics about agents active with the current organization. + public struct Upload: Resource { + public struct Body: Encodable { + public var format: String + public var environment: Environment + public var data: [Trace] + + public struct Environment: Encodable { + public var ci: String + public var key: String + public var number: String? + public var jobId: String? + public var branch: String? + public var commitSha: String? + public var message: String? + public var url: String? + } + + private enum CodingKeys: String, CodingKey { + case format + case environment = "runEnv" + case data + } + } + + public struct Content: Codable, Equatable { + public var id: UUID + public var runId: UUID + public var queued: Int + public var skipped: Int + public var errors: [String] + public var runUrl: URL + } + + public var version: APIVersion { + APIVersion.TestAnalytics.v1 + } + + public let path = "upload" + + /// body of the request + public var body: Body + + public init( + body: Body + ) { + self.body = body + } + } +} + +extension Resource where Self == TestAnalytics.Resources.Upload { + /// Get an object with properties describing Buildkite + /// + /// Returns meta information about Buildkite. + public static func uploadTestAnalytics(_ data: [Trace], environment: Self.Body.Environment) -> Self { + Self(body: .init(format: "json", environment: environment, data: data)) + } +} diff --git a/Tests/BuildkiteTests/Resources/TestAnalytics/TestAnalyticsUploadTests.swift b/Tests/BuildkiteTests/Resources/TestAnalytics/TestAnalyticsUploadTests.swift new file mode 100644 index 0000000..f941a00 --- /dev/null +++ b/Tests/BuildkiteTests/Resources/TestAnalytics/TestAnalyticsUploadTests.swift @@ -0,0 +1,36 @@ +// +// TestAnalyticsUploadTests.swift +// Buildkite +// +// Created by Aaron Sky on 6/6/22. +// Copyright © 2022 Aaron Sky. All rights reserved. +// + +import Foundation +import XCTest + +@testable import Buildkite + +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif + +class TestAnalyticsUpload: XCTestCase { + func testTestAnalyticsUpload() async throws { + typealias Resource = TestAnalytics.Resources.Upload + + let traces: [Trace] = [ + .init(id: .init(), history: .init(section: "http")), + .init(id: .init(), history: .init(section: "http")), + .init(id: .init(), history: .init(section: "http")), + ] + let expected = Resource.Content(id: .init(), runId: .init(), queued: 0, skipped: 0, errors: [], runUrl: .init()) + let context = try MockContext(content: expected) + + let response = try await context.client.send( + .uploadTestAnalytics(traces, environment: .init(ci: "buildkite", key: "test")) + ) + + XCTAssertEqual(expected, response.content) + } +}