Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Swift CI template #30

Merged
merged 16 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions python-ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ This template:
3. Runs pytest unit tests.
4. Automatically annotates the build based on junit test output

The runtime environment uses the official [Python Docker image](https://hub.docker.com/_/python) with the latest version.

## Next steps

After you select **Use template**, you’ll:
Expand Down
43 changes: 43 additions & 0 deletions swift/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: CI for Swift
description: Build, lint, and test a Swift project using SwiftLint and XCTest.
author: Buildkite
languages: ["Swift"]
use_cases: ["CI", "Mobile", "Web"]
platforms: ["Docker", "macOS", "iOS"]
tools: ["SwiftLint"]
primary_emojis: [":swift:"]
---

# CI for Swift

This template gives you a continuous integration (CI) pipeline that lints, tests, and builds a Swift project.

At a glance:

- For [Swift](https://www.swift.org/) projects
- Requires [Docker](https://docs.docker.com/get-docker/)
- Uses the [Swift Package Manager](https://swift.org/package-manager/)
- Lints code with [SwiftLint](https://github.com/realm/SwiftLint)
- Tests code using [XCTest](https://developer.apple.com/documentation/xctest)

## How it works

This template:

1. Builds your Swift project, caching dependencies for subsequent steps.
2. Lints the code with SwiftLint.
3. Runs tests with XCTest.

The runtime environment uses the official [Swift Docker image](https://hub.docker.com/_/swift) with the latest version.

## Next steps

After you select Use template, you’ll:

1. Connect the Git repository with your Swift project.
2. Modify the commands if necessary.
3. Configure the compute—run locally, on-premises, or in the cloud.
4. Run the pipeline.

You can then play around with the pipeline settings. For example, run the pipeline locally while you iterate on the definition or set a schedule to trigger a nightly build.
12 changes: 12 additions & 0 deletions swift/example-project/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc

# Buildkite artifacts
.cache
cache.tgz
14 changes: 14 additions & 0 deletions swift/example-project/Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"pins" : [
{
"identity" : "example-package-figlet",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/example-package-figlet",
"state" : {
"branch" : "main",
"revision" : "166eef46de0b094d6d1966e749f727d6c4beba0e"
}
}
],
"version" : 2
}
29 changes: 29 additions & 0 deletions swift/example-project/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "MyLibrary",
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: "MyLibrary",
targets: ["MyLibrary"]),
],
dependencies: [
.package(url: "https://github.com/apple/example-package-figlet", branch: "main"),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "MyLibrary",
dependencies: [
.product(name: "Figlet", package: "example-package-figlet")
]),
.testTarget(
name: "MyLibraryTests",
dependencies: ["MyLibrary"]),
]
)
8 changes: 8 additions & 0 deletions swift/example-project/Sources/MyCLI.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Figlet

@main
struct FigletTool {
static func main() {
Figlet.say("Hello, Swift!")
}
}
30 changes: 30 additions & 0 deletions swift/example-project/Sources/MyLibrary/MyLibrary.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===--------------------------------------------------------------------

import Foundation
import Figlet

struct Email: CustomStringConvertible {
var description: String

public init(_ emailString: String) throws {
let regex = #"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,64}"#
guard let _ = emailString.range(of: regex, options: .regularExpression) else {
throw InvalidEmailError(email: emailString)
}
self.description = emailString
}
}

private struct InvalidEmailError: Error {
let email: String
}
23 changes: 23 additions & 0 deletions swift/example-project/Tests/MyLibraryTests/MyLibraryTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===--------------------------------------------------------------------

@testable import MyLibrary
import XCTest

final class MyLibraryTests: XCTestCase {
func testEmail() throws {
let email = try Email("[email protected]")
XCTAssertEqual(email.description, "[email protected]")

XCTAssertThrowsError(try Email("invalid"))
}
}
30 changes: 30 additions & 0 deletions swift/pipeline.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
env:
SWIFT_CACHE_PATH: .cache

steps:
- label: ":swift: Build"
key: "build"
command: "swift build --cache-path $SWIFT_CACHE_PATH"
plugins:
- docker#v5.9.0:
image: "swift:latest"
- artifacts#v1.9.3:
upload: "$SWIFT_CACHE_PATH"
compressed: cache.tgz

- label: ":swift: Lint"
command: "swiftlint"
plugins:
- docker#v5.9.0:
image: "ghcr.io/realm/swiftlint:latest"
platform: "linux/amd64"

- label: ":swift: Test"
command: "swift test --cache-path $SWIFT_CACHE_PATH"
depends_on: ["build"]
plugins:
- docker#v5.9.0:
image: "swift:latest"
- artifacts#v1.9.3:
download: "$SWIFT_CACHE_PATH"
compressed: cache.tgz