Skip to content
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
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ body:
attributes:
label: Relevant log output
description: >-
Include any relevant log output under
`~/.amplify/logs/amplify-cli-<issue-date>.log` (See: [Logs Guidance](https://github.com/aws-amplify/amplify-ios/blob/main/LogsGuidance.md))
Include any relevant log output from the Xcode console
(See: [Logs Guidance](https://github.com/aws-amplify/amplify-swift/blob/main/LogsGuidance.md))
value: |
<details>
<summary>Log Messages</summary>
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy_package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,4 @@ jobs:
working-directory: ${{ github.workspace }}
run: |
git checkout -B gh-pages
bash ./CircleciScripts/jazzy_doc_gen.sh
bash ./scripts/jazzy_doc_gen.sh
2 changes: 1 addition & 1 deletion .github/workflows/deploy_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@ jobs:
working-directory: ${{ github.workspace }}
run: |
git checkout -B gh-pages
bash ./CircleciScripts/jazzy_doc_gen.sh
bash ./scripts/jazzy_doc_gen.sh
2 changes: 1 addition & 1 deletion .github/workflows/release_doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ jobs:
env:
GITHUB_EMAIL: aws-amplify-ops@amazon.com
GITHUB_USER: aws-amplify-ops
run: bash ./CircleciScripts/jazzy_doc_gen.sh
run: bash ./scripts/jazzy_doc_gen.sh
2 changes: 1 addition & 1 deletion .github/workflows/swiftformat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
SWIFTFORMAT_VERSION: '0.60.1'
SWIFTFORMAT_SHA256: 'cb4738085cf39c08da00b79b4a3683e77458ca12909934d04e5087d8e73f5e43'
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 #v3.5.3
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1
with:
persist-credentials: false

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
container:
image: ghcr.io/realm/swiftlint:0.54.0
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 #v3.5.3
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1
with:
persist-credentials: false

Expand Down
2 changes: 0 additions & 2 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ excluded:
- Pods
- .build
- AmplifyAsyncTesting
- AmplifyFunctionalTests
- AmplifyTestApp
- AmplifyTestCommon
- AmplifyTests
- AmplifyPlugins/Core/AWSPluginsCoreTests
Expand Down
10 changes: 0 additions & 10 deletions .swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -895,16 +895,6 @@
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AmplifyConnectClientIntegrationTests"
BuildableName = "AmplifyConnectClientIntegrationTests"
BlueprintName = "AmplifyConnectClientIntegrationTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
16 changes: 9 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ Detailed conventions and patterns live closer to the code. Read the relevant gui

- [`Amplify/AGENTS.md`](Amplify/AGENTS.md) — Core framework: categories, plugin protocols, error handling, configuration, Hub
- [`AmplifyPlugins/AGENTS.md`](AmplifyPlugins/AGENTS.md) — Plugin implementations: Auth, API, Storage, DataStore, etc.
- [`AmplifyClients/AGENTS.md`](AmplifyClients/AGENTS.md) — Standalone clients: Foundation, Bridge, Kinesis (new pattern)
- [`AmplifyClients/AGENTS.md`](AmplifyClients/AGENTS.md) — Standalone clients: Kinesis, Firehose, Connect, EventEnrichment, plus shared RecordCache (new pattern)

## Linting & Formatting (MUST pass)

**Always run `swiftformat` on changed files before every commit.** CI enforces both formatting and linting — PRs will fail if files are not formatted. See `.swiftlint.yml` and `.swiftformat` for full rules.
**Always run `swiftformat` on changed files before every commit.** The SwiftFormat and SwiftLint workflows run on pushes to non-default branches (not on `pull_request`), so format locally rather than relying on a PR check to catch it. See `.swiftlint.yml` and `.swiftformat` for full rules.

Note that `.swiftlint.yml` only lints `Amplify/` and `AmplifyPlugins/` — `AmplifyClients/`, `AmplifyFoundation/`, and `AmplifyFoundationBridge/` are outside SwiftLint's `included:` scope, though SwiftFormat covers the whole repo.

```bash
swiftformat <changed-files> # Format changed files before committing
Expand All @@ -42,7 +44,7 @@ swiftlint --fix # Then lint
amplify-swift/
├── Amplify/ # Core framework (categories, protocols, errors, config)
├── AmplifyPlugins/ # AWS service plugins (Auth, API, Storage, DataStore, etc.)
├── AmplifyClients/ # Standalone AWS clients (Kinesis) — new pattern
├── AmplifyClients/ # Standalone AWS clients (Kinesis, Firehose, Connect, EventEnrichment) — new pattern
├── AmplifyFoundation/ # Shared protocols (credentials, logging, errors) — no deps
├── AmplifyFoundationBridge/ # Foundation ↔ AWS SDK adapters
├── AmplifyTests/ # Core unit tests
Expand Down Expand Up @@ -84,7 +86,7 @@ chore: update aws-swift-sdk dependency
```

**Types**: `feat`, `fix`, `chore`, `refactor`, `test`, `docs`, `perf`, `ci`
**Scopes**: `auth`, `api`, `storage`, `datastore`, `geo`, `analytics`, `logging`, `predictions`, `push`, `kinesis`, `core`, `foundation`
**Scopes**: `auth`, `api`, `storage`, `datastore`, `geo`, `analytics`, `logging`, `predictions`, `push`, `kinesis`, `firehose`, `connect`, `core`, `foundation`

No period at end. One feature/bugfix per PR. Reference issues: `fixes #<issue>`.

Expand All @@ -95,7 +97,7 @@ swift test # All unit tests
swift test --filter AWSCognitoAuthPluginUnitTests # Specific target
```

- **Unit tests**: XCTest, defined in Package.swift (19 test targets)
- **Unit tests**: XCTest, defined in Package.swift (23 test targets)
- **Integration tests**: Xcode host app projects under `AmplifyPlugins/<Category>/Tests/<Category>HostApp/`
- **Conventions**: Mock via behavior protocols, use `AmplifyTestCommon` for shared utilities, `AmplifyAsyncTesting` for async helpers
- **Test documentation**: Use Given/When/Then doc comments on all test methods:
Expand All @@ -114,11 +116,11 @@ swift test --filter AWSCognitoAuthPluginUnitTests # Specific target

## Semver

New enum cases = **minor** bump. Breaking API changes = **major** (rare, needs approval). API surface tracked via `api-dump/` JSON snapshots and CI checks.
New enum cases = **minor** bump. Breaking API changes = **major** (rare, needs approval). API surface tracked via `api-dump/` JSON snapshots and CI checks, currently covering four modules only: `Amplify`, `AWSPluginsCore`, `AWSDataStorePlugin`, and `CoreMLPredictionsPlugin`.

## CI/CD

60+ GitHub Actions workflows in `.github/workflows/`: per-category unit tests (`unit_test_*.yml`), integration tests (`integ_test_*.yml`), platform builds, SwiftLint/SwiftFormat checks, API digester, CodeQL, Fortify. Releases via Fastlane.
70 GitHub Actions workflows in `.github/workflows/`: per-category unit tests (`unit_test_*.yml`), integration tests (`integ_test_*.yml`), platform builds, SwiftLint/SwiftFormat checks, API digester, CodeQL, Fortify. Releases via Fastlane.

## Common Agent Tasks

Expand Down
6 changes: 3 additions & 3 deletions Amplify/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Amplify/
│ ├── Auth/ # AuthCategoryBehavior (sign-in, sign-up, session, MFA)
│ ├── DataStore/ # DataStoreCategoryBehavior (sync, query, observe)
│ ├── Geo/ # GeoCategoryBehavior (search, maps)
│ ├── Hub/ # Built-in pub/sub event system (no plugin needed)
│ ├── Hub/ # Pub/sub event system (no user setup needed — backed by the built-in AWSHubPlugin)
│ ├── Logging/ # LoggingCategoryBehavior
│ ├── Notifications/ # Push notification behavior
│ ├── Predictions/ # ML prediction behavior (text, vision, speech)
Expand All @@ -47,7 +47,7 @@ Amplify/
│ ├── Model/ # Model, Schema, Field definitions (DataStore)
│ ├── Plugin/ # Plugin protocol, PluginKey, Resettable
│ └── Support/ # AmplifyError protocol, utilities
├── DefaultPlugins/ # Built-in default plugin implementations
├── DefaultPlugins/ # AWSHubPlugin and AWSUnifiedLoggingPlugin (registered automatically)
└── DevMenu/ # Developer debug menu
```

Expand Down Expand Up @@ -107,7 +107,7 @@ let token = Amplify.Hub.listen(to: .auth) { payload in ... }

## API Surface Stability

API dumps in `api-dump/*.json` track the public surface. Breaking changes detected by CI (`api_digester_check.yml`). New enum cases = minor bump; removing/renaming public APIs = major bump (needs approval).
API dumps in `api-dump/*.json` track the public surface of four modules (`Amplify`, `AWSPluginsCore`, `AWSDataStorePlugin`, `CoreMLPredictionsPlugin`). Breaking changes detected by CI (`api-breaking-changes-detection.yml`; `api_digester_check.yml` separately verifies the digester tool itself against the `api-dump-test/` fixtures). New enum cases = minor bump; removing/renaming public APIs = major bump (needs approval).

## Adding a New API to a Category

Expand Down
24 changes: 17 additions & 7 deletions AmplifyClients/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ Amplify Clients are **standalone AWS service clients** independent of the core `
```
┌─────────────────────────────────────────────────────────┐
│ Amplify Clients (e.g., AmplifyKinesisClient) │
│ High-level APIs, actor-based, local caching, retry │
│ High-level APIs, actor-based, retry │
├─────────────────────────────────────────────────────────┤
│ AmplifyRecordCache (Shared Caching Layer) │
│ SQLite-backed record buffering, used by Kinesis and │
│ Firehose │
├─────────────────────────────────────────────────────────┤
│ AmplifyFoundation (Protocol Layer) │
│ Pure Swift protocols — zero external deps │
Expand Down Expand Up @@ -60,8 +64,8 @@ Deps: `AmplifyFoundation`, `AmplifyFoundationBridge`, `SQLite.swift`, `AWSKinesi

```swift
public class AmplifyKinesisClient {
init(region: String, credentialsProvider: AWSCredentialsProvider, options: Options)
func record(data: Data, partitionKey: String, streamName: String) async throws -> RecordData
init(region: String, credentialsProvider: any AmplifyFoundation.AWSCredentialsProvider, options: Options = Options()) throws
@discardableResult func record(data: Data, partitionKey: String, streamName: String) async throws -> RecordData
func flush() async throws -> FlushData
func enable() async / func disable() async
func clearCache() async throws -> ClearCacheData
Expand All @@ -76,7 +80,7 @@ public enum KinesisError: AmplifyError {
case cache(ErrorDescription, RecoverySuggestion, Error?)
case cacheLimitExceeded(ErrorDescription, RecoverySuggestion, Error?)
case validation(ErrorDescription, RecoverySuggestion, Error?)
case unknown(ErrorDescription, Error?)
case unknown(ErrorDescription, RecoverySuggestion, Error?)
}
```

Expand All @@ -90,18 +94,22 @@ AmplifyClients/Amplify<Service>Client/
│ ├── Amplify<Service>Client.swift # Public facade
│ └── Support/ # Error type, actors, protocols, impls
├── Tests/
│ ├── UnitTests/
│ └── IntegrationTests/
│ └── UnitTests/
```

Integration tests are not co-located per client. `AmplifyConnectClient` has its own host app under `Tests/ConnectClientHostApp/`, Kinesis and Firehose share `AmplifyClients/Tests/IntegrationTests/KinesisFirehoseClientHostApp/`, and `AmplifyEventEnrichmentClient` has unit tests only.

### Package.swift target

```swift
.target(
name: "Amplify<Service>Client",
dependencies: ["AmplifyFoundation", "AmplifyFoundationBridge",
// Add "AmplifyRecordCache" (+ the SQLite product) only if the
// client buffers records locally, as Kinesis and Firehose do.
.product(name: "AWS<Service>", package: "aws-sdk-swift")],
path: "AmplifyClients/Amplify<Service>Client/Sources",
resources: [.copy("Resources/PrivacyInfo.xcprivacy")],
swiftSettings: [.enableUpcomingFeature("StrictConcurrency")]
)
```
Expand Down Expand Up @@ -130,6 +138,8 @@ var config = try AWS<Service>.<Service>Client.<Service>ClientConfiguration(
)
config.httpClientEngine = UserAgentClientEngine(
target: config.httpClientEngine,
additionalMetadata: ["md/amplify-<service>#\(AmplifyMetadata.version)"]
additionalMetadata: ["md/amplify-<service>"]
)
```

Do not append the version here — `UserAgentClientEngine` already injects `lib/amplify-swift#<version>`, so adding `AmplifyMetadata.version` to the `md/` segment stamps it twice.

This file was deleted.

50 changes: 0 additions & 50 deletions AmplifyFunctionalTests/AmplifyConfigurationTests.swift

This file was deleted.

Loading
Loading