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

Swift Build Script | CD release pipeline #4

Merged
merged 26 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
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
28 changes: 28 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CD

on:
workflow_dispatch:
push:
branches:
- develop

permissions:
id-token: write
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: macos-13-xlarge
steps:
- uses: RDXWorks-actions/checkout@main
- name: Install Rust Toolchain
uses: RDXWorks-actions/toolchain@master
with:
toolchain: nightly-2024-01-11
default: true
target: x86_64-apple-ios aarch64-apple-ios aarch64-apple-ios-sim

- name: Run iOS build script
run: |
sh ./scripts/ios/release.sh
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
tarpaulin-report.html
.vscode
.idea
.build
build_rs_cov.profraw
cobertura.xml
jna-*.jar
jna-*.jar
.swiftpm/*
23 changes: 23 additions & 0 deletions BuildProcess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Swift

## Build script
Ah nevermind the build script in [uniffi-starter/../build-ios.sh](https://github.com/ianthetechie/uniffi-starter/blob/main/rust/build-ios.sh) already contained code to update checksum.

[Blog post about automating checksum update in Package.swift](https://blog.eidinger.info/distribute-binary-frameworks-in-swift-packages-and-how-to-automate-the-process) and here is a [Github Gist which looks nice](https://gist.github.com/litoarias/23bca22bb6161625484b4fb8cd245fe8)

This would allow for us to use a similar pattern like [`ferrostar`'s `Package.swift`](https://github.com/stadiamaps/ferrostar/blob/main/Package.swift) which has a nice `useLocalFramework` setup, and when NOT local uses SPM's setup:

```swift
let releaseTag = "0.1.0"
let releaseChecksum = "deadbeefdeadbeef..."
.binaryTarget(
name: "SargonCoreRS",
url: "https://github.com/radixdlt/sargon/releases/download/\(releaseTag)/libsargon-rs.xcframework.zip",
checksum: releaseChecksum
)
```

The advantage of this over what we are [doing today in Swift-Engine-Toolkit](https://github.com/radixdlt/swift-engine-toolkit/blob/main/Package.swift#L23C3-L23C78) is that the .xcframework files need not be part of Git! They can be put in Github! This will allow for much much faster git clone!

# Android
[See `uniffi-starter`](https://github.com/ianthetechie/uniffi-starter) (also contains Swift, but `@IanTheTech` has also created `ferrostar` which contains more advanced Swift setup).
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ name = "uniffi"
[lib]
crate-type = ["staticlib", "cdylib", "lib"]

[[bin]]
name = "uniffi-bindgen"
path = "src/bin.rs"

[dependencies]
log = "0.4.20"
pretty_env_logger = "0.5.0"
Expand Down
52 changes: 52 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let sargonBinaryTargetName = "SargonCoreRS"
let binaryTarget: Target
let useLocalFramework = true

if useLocalFramework {
binaryTarget = .binaryTarget(
name: sargonBinaryTargetName,
// IMPORTANT: Swift packages importing this locally will not be able to
// import SargonCore unless you specify this as a relative path!
path: "./target/ios/libsargon-rs.xcframework"
)
} else {
let releaseTag = "0.1.0"
let releaseChecksum = "befef7d56108305ff6ff69d67483471395c3e603e299b3b15f5a826328de272b"
binaryTarget = .binaryTarget(
name: sargonBinaryTargetName,
url:
"https://github.com/radixdlt/sargon/releases/download/\(releaseTag)/libsargon-rs.xcframework.zip",
checksum: releaseChecksum
)
}

let package = Package(
name: "Sargon",
platforms: [
.iOS(.v15)
],
products: [
.library(
name: "Sargon",
targets: ["Sargon"]
)
],
targets: [
binaryTarget,
.target(
name: "SargonUniFFI",
dependencies: [.target(name: sargonBinaryTargetName)],
path: "apple/Sources/UniFFI"
),
.target(
name: "Sargon",
dependencies: [.target(name: "SargonUniFFI")],
path: "apple/Sources/Sargon"
),
]
)
94 changes: 93 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,96 @@ cargo tarpaulin --out Html

```sh
cargo nextest run
```
```

# Build local

## iOS

### Prerequisites

#### Rust targets
```sh
rustup target add x86_64-apple-ios aarch64-apple-ios aarch64-apple-ios-sim
```

### Build
Find [script here](scripts/ios/build-sargon.sh)

```sh
./scripts/build-ios.sh
```

## Android
TBD

# Release

## iOS
### Locally

#### Prerequisites

> [!IMPORTANT]
> You will need the prerequisites of _Build local_ above.

##### Install `gh`

```sh
brew install gh
```

##### Github PAT
Create a Github Personal Access Token (PAT) labeled "Classic" and give it these permissions:
`write:packages`
`admin:org -> read:org`

#### Manually release

For the first time, you must:
```sh
gh auth login
```

Do this:
```sh
? What account do you want to log into? GitHub.com
? What is your preferred protocol for Git operations on this host? SSH
? Upload your SSH public key to your GitHub account? Skip
? How would you like to authenticate GitHub CLI? Paste an authentication token
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens
The minimum required scopes are 'repo', 'read:org'.
? Paste your authentication token: ****************************************
```

If successful you should see:
```sh
- gh config set -h github.com git_protocol ssh
✓ Configured git protocol
✓ Logged in as <YOUR_GH_USERNAME>
```

Find [script here](scripts/ios/release.sh)
```sh
./scripts/ios/release.sh
```

### CD
See [`.github/workflows/release.yml`](.github/workflows/release.yml)


## Android
TBD

# Example apps
## iOS

Find [script here](scripts/ios/run-example-app.sh)

```sh
./scripts/ios/run-example-app.sh
```


## Android
TBD
7 changes: 6 additions & 1 deletion _typos.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
[files]
extend-exclude = ["tarpaulin-report.html", "tests/vectors/fixtures/*.json"]
extend-exclude = [
"scripts/**",
"apple/Sources/UniFFI/Sargon.swift",
"tarpaulin-report.html",
"tests/vectors/fixtures/*.json",
]
2 changes: 2 additions & 0 deletions apple/Sources/Sargon/Exports.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@_exported import SargonUniFFI
@_exported import Foundation
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//extension Decimal192: Comparable {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extension SecureStorageKey {
public var identifier: String {
secureStorageKeyIdentifier(key: self)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Account+Swiftified.swift
//
//
// Created by Alexander Cyon on 2024-02-16.
//

import Foundation

extension Account: Sendable {}
extension Account: Identifiable {
public typealias ID = AccountAddress
public var id: ID {
address
}
}
extension Account {
public var appearanceID: AppearanceID {
appearanceId
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extension AccountAddress: Sendable {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
public typealias AppearanceID = AppearanceId

extension AppearanceID: Sendable {}
extension AppearanceID: CaseIterable {
public static var allCases: [Self] {
appearanceIdsAll()
}
}
13 changes: 13 additions & 0 deletions apple/Sources/Sargon/Extensions/Swiftified/BagOfBytes+Random.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
extension BagOfBytes {
public init(data: Data) {
self = newBagOfBytesFrom(bytes: data)
}
public static func random(byteCount: Int) -> Self {
var data = Data(repeating: 0, count: byteCount)
data.withUnsafeMutableBytes {
assert($0.count == byteCount)
$0.initializeWithRandomBytes(count: byteCount)
}
return Self(data: data)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extension Decimal192: Sendable {}
//extension Decimal192: ExpressibleByStringLiteral {
//
//}
//extension Decimal192: ExpressibleByFloatLiteral {
//
//}
//extension Decimal192: SignedNumeric /* Numeric, ExpressibleByIntegerLiteral AdditiveArithmetic */
//{
//
//}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
extension DisplayName: Sendable {}
extension DisplayName {
public init(validating name: String) throws {
self = try newDisplayName(name: name)
}
}

#if DEBUG
extension DisplayName: ExpressibleByStringLiteral {
public init(stringLiteral name: String) {
try! self.init(validating: name)
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extension Profile: Sendable {}
extension Profile: Identifiable {
public typealias ID = ProfileID
public var id: ID {
header.id
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// SargonError+Swiftified.swift
//
//
// Created by Alexander Cyon on 2024-02-16.
//

import Foundation

public typealias SargonError = CommonError
extension SargonError: Sendable {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extension Wallet: Sendable {}
43 changes: 43 additions & 0 deletions apple/Sources/Sargon/Util/Buffer+InitializeWithRandomBytes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// from: https://github.com/apple/swift-crypto/blob/64a1a98e47e6643e6d43d30b87a244483b51d8ad/Sources/Crypto/Util/BoringSSL/RNG_boring.swift
// commit: 64a1a98e47e6643e6d43d30b87a244483b51d8ad

//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftCrypto open source project
//
// Copyright (c) 2019-2022 Apple Inc. and the SwiftCrypto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.md for the list of SwiftCrypto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

extension UnsafeMutableRawBufferPointer {
public func initializeWithRandomBytes(count: Int) {
guard count > 0 else {
return
}

precondition(count <= self.count)
var rng = SystemRandomNumberGenerator()

// We store bytes 64-bits at a time until we can't anymore.
var targetPtr = self
while targetPtr.count > 8 {
targetPtr.storeBytes(of: rng.next(), as: UInt64.self)
targetPtr = UnsafeMutableRawBufferPointer(rebasing: targetPtr[8...])
}

// Now we're down to having to store things an integer at a time. We do this by shifting and
// masking.
var remainingWord: UInt64 = rng.next()
while targetPtr.count > 0 {
targetPtr.storeBytes(of: UInt8(remainingWord & 0xFF), as: UInt8.self)
remainingWord >>= 8
targetPtr = UnsafeMutableRawBufferPointer(rebasing: targetPtr[1...])
}
}
}
Loading
Loading