Skip to content

Adding WASM support, Mise migration, swift-format, workflow updates, and openapi.yaml improvements#26

Merged
leogdion merged 12 commits intomainfrom
atleast-v1.0.0-beta.4
Apr 10, 2026
Merged

Adding WASM support, Mise migration, swift-format, workflow updates, and openapi.yaml improvements#26
leogdion merged 12 commits intomainfrom
atleast-v1.0.0-beta.4

Conversation

@leogdion
Copy link
Copy Markdown
Member

@leogdion leogdion commented Apr 9, 2026

…flow updates, and openapi.yaml improvements

  • Add WASI emulation flags and conditional OpenAPIURLSession dependency for WASM builds
  • Migrate from Mint to Mise (spm: backend for swift-format and swift-openapi-generator)
  • Replace nicklockwood/SwiftFormat with apple/swift-format 602.0.0
  • Rewrite GitHub Actions workflow: configure matrix job, WASM/Android/Windows builds, macOS 26/Xcode 26.4, Mise-based linting
  • Update .swiftlint.yml: add one_declaration_per_file, new disabled_rules, remove Mint exclusion
  • Add devcontainers for Swift 6.1, 6.2, 6.3; update VS Code extension to swiftlang.swift-vscode
  • Update openapi.yaml: add interactive field, request headers, url/props constraints, 200 debug response
  • Add userAgent property to Plausible; fix deprecated Servers.server1() → Servers.Server1.url()
  • Add Scripts/header.sh for MIT license header management
  • Fix Scripts/generate.sh package name and use mise exec
  • Refactor testPostEvent for shorter function body

Perform an AI-assisted review on CodePeer.com

Summary by CodeRabbit

  • New Features

    • Events gain an optional interactive flag; API now documents/accepts User-Agent, X-Forwarded-For, and X-Debug-Request headers.
  • Breaking Changes

    • Client initializers now require a User-Agent value.
    • Minimum Swift tools version raised.
  • Improvements

    • Tightened request/JSON validation (URL length, props limit); dependency pins updated.
    • CI, devcontainer, lint/format configs overhauled; contributor guidance and a license-header script added.
  • Tests

    • Test suite migrated to the new Testing framework and adjusted helpers.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Warning

Rate limit exceeded

@leogdion has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 53 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 7 minutes and 53 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5901ce85-012e-4dfe-9434-257b9bf9f1df

📥 Commits

Reviewing files that changed from the base of the PR and between 28757fc and 193e4bf.

📒 Files selected for processing (3)
  • Tests/AviaryInsightsTests/AviaryInsightsTests+Init.swift
  • Tests/AviaryInsightsTests/AviaryInsightsTests.swift
  • Tests/AviaryInsightsTests/MockTransport.swift
📝 Walkthrough

Walkthrough

This PR updates devcontainers and CI, replaces Mint with Mise for tooling, adds swift-format/lint/OpenAPI generator configs and scripts, introduces Event.interactive and Plausible.userAgent (sent as User-Agent), tightens OpenAPI event schema/headers, and migrates tests/mocks to the Testing framework.

Changes

Cohort / File(s) Summary
Dev Container Configuration
\.devcontainer/devcontainer.json, \.devcontainer/swift-6.1/devcontainer.json, \.devcontainer/swift-6.2/devcontainer.json, \.devcontainer/swift-6.3/devcontainer.json
Bumped devcontainer images to Swift 6.x, swapped VS Code extension sswg.swift-langswiftlang.swift-vscode, set remoteUser: vscode in some configs, and added runtime args/capabilities in 6.3 config.
CI Workflow
\.github/workflows/AviaryInsights.yml
Reworked triggers and concurrency, added configure job producing a dynamic matrix, refactored build jobs to use matrix outputs, added Android/Windows jobs (gated by full-matrix), and adjusted lint/coverage steps and action versions.
Tooling & Formatting Config
\.mise.toml, \.swift-format, \.swiftformat, \.swiftlint.yml, openapi-generator-config.yaml, Mintfile
Added Mise config and .swift-format, removed legacy .swiftformat and Mintfile, updated .swiftlint.yml, and added OpenAPI generator file-level comments.
Scripts
Scripts/lint.sh, Scripts/generate.sh, Scripts/header.sh, Scripts/gh-md-toc
Rewrote lint/generate flows to use mise exec, removed Scripts/generate.sh and Scripts/gh-md-toc, and added Scripts/header.sh to apply license headers.
Package & Dependencies
Package.swift, Package.resolved
Bumped Swift tools to 6.1, advanced several dependency versions, and conditioned OpenAPIURLSession product on Apple platforms.
OpenAPI & Generator
openapi.yaml, openapi-generator-config.yaml
Added required User-Agent and optional X-Forwarded-For/X-Debug-Request headers to POST /event, added interactive boolean to payload, tightened url/props schema, and appended generator file comments.
Runtime API Changes
Sources/AviaryInsights/Event.swift, Sources/AviaryInsights/Operations.swift, Sources/AviaryInsights/Plausible.swift
Added public let interactive: Bool? to Event and propagated it into operation payloads; added userAgent to Plausible, updated initializers (URLSession variants guarded by canImport(OpenAPIURLSession)), and include User-Agent header on postEvent requests.
Tests & Mocks
Tests/AviaryInsightsTests/...
Tests/AviaryInsightsTests/AviaryInsightsTests.swift, Tests/AviaryInsightsTests/MockTransport.swift, Tests/AviaryInsightsTests/Event.swift, Tests/AviaryInsightsTests/Revenue.swift, Tests/AviaryInsightsTests/AviaryInsightsTests+Init.swift
Migrated from XCTest to Testing framework (@Test), switched assertions to #require/#expect, updated MockTransport to capture raw Data bodies, updated test helpers to include interactive, added initializer tests conditioned on canImport(OpenAPIURLSession).
Docs
CLAUDE.md
Added repository usage, tooling guidance, and OpenAPI regeneration instructions.
Codecov
codecov.yml
Excluded generated sources (Sources/AviaryInsights/Generated) from coverage.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client (Plausible)
    participant Transport as Transport (e.g., URLSessionTransport / MockTransport)
    participant Server as Server (POST /event)

    rect rgba(135,206,250,0.5)
    Client->>Transport: prepare request (POST /event)\ninclude JSON payload (interactive, url, props, revenue)\nadd headers: User-Agent, X-Forwarded-For?, X-Debug-Request?
    end

    rect rgba(144,238,144,0.5)
    Transport->>Server: send HTTP request\n(body as Data, headers set)
    Server-->>Transport: respond (202 or 200 debug)
    end

    Transport-->>Client: deliver response (or none for fire-and-forget)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • fixing Windows and WASM #28 — Overlapping code-level changes (devcontainer/CI/tooling, Event.interactive, Plausible.userAgent, MockTransport/test migrations).

Poem

🐰 I hopped through code, a tiny dev's delight,
Headers, tests, and tooling stitched just right,
Mise leads the march where Mint once stood,
Events now whisper if they're playful or good,
A nimble nibble — swift, tidy, and bright.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The PR title is truncated and vague, using ellipsis to hide the actual scope. It mentions only partial objectives (WASM, Mise, swift-format) without clearly conveying the main changes or their significance. Provide a complete, specific title that summarizes the primary objective. For example: 'Add WASM support, migrate to Mise, update to Swift 6.1+, and modernize tooling' or break into focused PRs for each major area.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch atleast-v1.0.0-beta.4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.47%. Comparing base (f1b444a) to head (193e4bf).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main      #26       +/-   ##
===========================================
+ Coverage   75.17%   89.47%   +14.29%     
===========================================
  Files           6        4        -2     
  Lines         141       76       -65     
===========================================
- Hits          106       68       -38     
+ Misses         35        8       -27     
Flag Coverage Δ
5.10 ?
5.9 ?
6.0 ?
6.1 85.18% <100.00%> (?)
6.2 85.18% <100.00%> (?)
6.3 85.18% <100.00%> (?)
focal ?
ios17.0.1 ?
ios17.2 ?
ios18.5 60.52% <24.13%> (?)
ios26.4 60.52% <24.13%> (?)
jammy 85.18% <100.00%> (+10.00%) ⬆️
macos 89.47% <100.00%> (?)
noble 85.18% <100.00%> (+10.00%) ⬆️
spm 89.47% <100.00%> (+14.29%) ⬆️
tvos18.5 60.52% <24.13%> (?)
tvos26.4 60.52% <24.13%> (?)
visionos2.5 60.52% <24.13%> (?)
visionos26.4 89.47% <100.00%> (?)
watchos10.0 ?
watchos10.2 ?
watchos11.5 89.47% <100.00%> (?)
watchos26.4 60.52% <24.13%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

leogdion and others added 3 commits April 9, 2026 09:51
…flow updates, and openapi.yaml improvements

- Add WASI emulation flags and conditional OpenAPIURLSession dependency for WASM builds
- Migrate from Mint to Mise (spm: backend for swift-format and swift-openapi-generator)
- Replace nicklockwood/SwiftFormat with apple/swift-format 602.0.0
- Rewrite GitHub Actions workflow: configure matrix job, WASM/Android/Windows builds, macOS 26/Xcode 26.4, Mise-based linting
- Update .swiftlint.yml: add one_declaration_per_file, new disabled_rules, remove Mint exclusion
- Add devcontainers for Swift 6.1, 6.2, 6.3; update VS Code extension to swiftlang.swift-vscode
- Update openapi.yaml: add interactive field, request headers, url/props constraints, 200 debug response
- Add userAgent property to Plausible; fix deprecated Servers.server1() → Servers.Server1.url()
- Add Scripts/header.sh for MIT license header management
- Fix Scripts/generate.sh package name and use mise exec
- Refactor testPostEvent for shorter function body

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… Apple platforms

- Add full-matrix output to configure job to gate Windows/Android jobs
- Expand Ubuntu Swift matrix to 6.1/6.2/6.3 on full runs (was only 6.3)
- Exclude wasm/wasm-embedded for Swift 6.1 (unsupported)
- Add download-platform: true to all iOS/watchOS/tvOS/visionOS matrix entries
- Replace single-job build-android with matrix (Swift 6.2/6.3 × API 33-36)
- Replace single-job build-windows with matrix (2022/2025 × Swift 6.1/6.2/6.3)
- Fix lint job to use !cancelled() && !failure() so it runs past skipped jobs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@leogdion leogdion force-pushed the atleast-v1.0.0-beta.4 branch from c52783d to 24da913 Compare April 9, 2026 14:02
leogdion and others added 2 commits April 9, 2026 10:12
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mport

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@leogdion leogdion force-pushed the atleast-v1.0.0-beta.4 branch from 6e070b6 to f885a3f Compare April 9, 2026 20:11
Comment thread .github/workflows/AviaryInsights.yml Outdated
Comment thread .github/workflows/AviaryInsights.yml Outdated
Comment thread .github/workflows/AviaryInsights.yml
Comment thread .github/workflows/AviaryInsights.yml
Comment thread Scripts/generate.sh Outdated
Comment thread .swiftlint.yml Outdated
@leogdion leogdion marked this pull request as ready for review April 9, 2026 21:34
- Update sersoft-gmbh/swift-coverage-action to v5, codecov-action to v6
- Comment out wasmtime-version in Ubuntu build
- Use contains-code-coverage output from swift-build to gate coverage steps
- Remove unused db identifier exclusion from swiftlint config
- Delete Scripts/generate.sh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
Tests/AviaryInsightsTests/AviaryInsightsTests.swift (1)

61-72: ⚠️ Potential issue | 🟡 Minor

Don't normalize the captured payload before asserting it.

Decoding request.body back into jsonPayload throws away unknown keys and collapses null optionals to the same state as omitted fields, so the test can pass with the wrong on-the-wire JSON. Compare canonicalized raw JSON instead of round-tripping through the generated type.

🔎 Suggested assertion change
       let data = try `#require`(request.body)
-      let actualJSONPayload = try decoder.decode(
-        Operations.post_sol_event.Input.Body.jsonPayload.self,
-        from: data
-      )
       let expectedJSONPayload = Operations.post_sol_event.Input.Body.jsonPayload(
         event: event,
         defaultDomain: defaultDomain
       )
-      let actualEncoded = try encoder.encode(actualJSONPayload)
-      let expectedEncoded = try encoder.encode(expectedJSONPayload)
-      `#expect`(actualEncoded == expectedEncoded)
+      let actualObject = try JSONSerialization.jsonObject(with: data)
+      let expectedData = try encoder.encode(expectedJSONPayload)
+      let expectedObject = try JSONSerialization.jsonObject(with: expectedData)
+      let actualCanonical = try JSONSerialization.data(
+        withJSONObject: actualObject,
+        options: [.sortedKeys]
+      )
+      let expectedCanonical = try JSONSerialization.data(
+        withJSONObject: expectedObject,
+        options: [.sortedKeys]
+      )
+      `#expect`(actualCanonical == expectedCanonical)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/AviaryInsightsTests/AviaryInsightsTests.swift` around lines 61 - 72,
The test currently decodes request.body into
Operations.post_sol_event.Input.Body.jsonPayload which normalizes away unknown
keys and null-vs-omitted differences; instead, canonicalize and compare the raw
JSON bytes. Replace the round-trip decode of request.body (the use of
decoder.decode into jsonPayload and creation of actualEncoded) with
canonicalization of the raw request.body bytes (e.g., parse to a JSON object and
re-serialize with a deterministic/canonical form) and compare that canonicalized
data to the canonicalized encoding of the expected
Operations.post_sol_event.Input.Body.jsonPayload; keep references to
request.body, Operations.post_sol_event.Input.Body.jsonPayload,
expectedJSONPayload, and the comparison (actual vs expected canonicalized bytes)
to locate and update the assertion.
openapi.yaml (1)

56-69: ⚠️ Potential issue | 🟠 Major

Mirror the new url/props limits in the public Event API.

These constraints are now part of the contract, but Sources/AviaryInsights/Event.swift:35-89 still accepts any URL length and any props count. That lets callers build requests the spec now rejects.

Based on learnings: Use OpenAPI-first design approach: auto-generate Plausible API client from openapi.yaml using swift-openapi-generator.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openapi.yaml` around lines 56 - 69, Event model currently accepts any URL
length and any number of props while the OpenAPI contract limits url to
maxLength 2000 and props to maxProperties 30; enforce these constraints in the
Event model's initializer/validation (e.g., in Event.init or Event.validate) by
rejecting or throwing when url.count > 2000 or props.count > 30, return/throw a
descriptive error matching API validation, and add/update unit tests to cover
the new validation; also consider regenerating the Swift client from
openapi.yaml with swift-openapi-generator to keep models in sync.
🧹 Nitpick comments (1)
.devcontainer/swift-6.3/devcontainer.json (1)

1-39: Optional: reduce config drift across versioned devcontainers.

Consider extracting shared settings into a common template/base generation step to avoid future divergence across swift-6.1, swift-6.2, and swift-6.3.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/swift-6.3/devcontainer.json around lines 1 - 39, Summary:
multiple devcontainer.json files for swift-6.1/6.2/6.3 are diverging; extract
common bits into a shared base to reduce config drift. Fix: create a single base
devcontainer template that contains shared keys (features, runArgs,
customizations.vscode.settings, customizations.vscode.extensions, remoteUser)
and update each variant (the files containing "image": "swift:6.3" / "swift:6.2"
/ "swift:6.1") to reference or be generated from that base while only overriding
the "image" value and any variant-specific settings; ensure unique symbols in
the diff such as "features", "runArgs", "customizations.vscode.settings",
"extensions", and "remoteUser" are moved to the base and removed from
per-version files so future changes are made once in the base.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@openapi-generator-config.yaml`:
- Around line 5-7: Remove the blanket additionalFileComments entries
("swift-format-ignore-file" and "swiftlint:disable all") from
openapi-generator-config.yaml and instead add a nested .swiftlint.yml file under
Sources/AviaryInsights/Generated/ that selectively disables only the
generator-violated rules (e.g., add disabled_rules list containing type_name,
identifier_name, file_length, line_length, nesting); keep repository-root
SwiftLint/format rules intact and let swift-format run normally on handwritten
code (or run swift-format as an explicit post-generation step if you need
generated files formatted).

In `@openapi.yaml`:
- Around line 94-97: The 200 response for the debug path currently lacks a
response body schema so generators treat it as Void; update the '200' response
block in openapi.yaml to include a content section (e.g., application/json) with
a schema describing the debug payload — an object with an "ip" property of type
string and a description indicating it's the IP used for visitor counting — so
tools like swift-openapi-generator will model the debug response payload
correctly.

In `@Package.swift`:
- Line 1: Add the repository-required MIT license header at the top of
Package.swift: insert the standard multi-line MIT header block before the
existing swift-tools-version line so the file begins with the license comment,
ensuring the header matches the project's required format for all .swift files.

In `@Scripts/lint.sh`:
- Around line 29-34: The CI guard in lint.sh prevents header.sh from running
when CI is set, so license headers aren't enforced in CI; update Scripts/lint.sh
to always run header.sh (or at least run it when CI=true and LINT_MODE=STRICT)
instead of only when CI is unset: remove or adjust the if [ -z "$CI" ]
conditional and ensure the calls to header.sh (referenced as bash
"$SCRIPT_DIR/header.sh" "$PACKAGE_DIR/Sources" and "$PACKAGE_DIR/Tests") execute
during CI runs so the MIT header check/enforcement runs in CI as well as
locally.

In `@Sources/AviaryInsights/Event.swift`:
- Around line 57-60: The public docs for the Event.interactive property claim
"Defaults to `true`" but the Event initializer parameter defaults to nil; update
them so they match: either change the Event initializer signature to provide
interactive: Bool = true (so new Event(...) yields interactive == true), or keep
the initializer as interactive: Bool? = nil and reword the doc comment above the
interactive property/initializer to state that the client omits the field by
default (nil) and Plausible's server will treat omitted/undefined as true for
bounce-rate calculations; update the doc near the "Whether the event affects
bounce rate" comment and the Event initializer parameter documentation
accordingly and ensure the symbol Event (initializer) and property interactive
are consistent.

In `@Sources/AviaryInsights/Plausible.swift`:
- Around line 143-154: The initializer `public
init(defaultDomain:userAgent:serverURL:configuration:)` documents
`configuration` as "Defaults to `nil`" but currently requires a non-optional
URLSessionTransport.Configuration; fix this by making the parameter optional
with a default of nil (change the signature to use `configuration:
URLSessionTransport.Configuration? = nil`) and update any uses inside the init
to handle the optional, or alternatively update the doc comment to remove the
"Defaults to `nil`" text if you intend to keep a required configuration; ensure
references to Self.defaultServerURL and URLSessionTransport.Configuration are
preserved.
- Around line 186-189: The Plausible.postEvent wrapper currently hardcodes only
the User-Agent header when calling client.post_sol_event, so add optional
parameters to Plausible.postEvent (e.g., xForwardedFor: String? and
xDebugRequest: String?) or a single optional headers struct, surface them in the
public API, and pass them into the generated client's headers initializer
alongside User_hyphen_Agent; update the Plausible.postEvent signature and call
to client.post_sol_event to include X-Forwarded-For and X-Debug-Request when
non-nil so callers can supply those new optional event headers.

In `@Tests/AviaryInsightsTests/AviaryInsightsTests.swift`:
- Line 60: The test currently iterates with for (event, request) in zip(events,
requests) which silently drops extras when lengths differ; before that loop (and
the similar loop around lines 85-86) assert that events.count == requests.count
(or use XCTAssertEqual) to ensure mismatched send counts fail the test, then
proceed with the zip-based iteration (identifying the variables events and
requests in the test function) so any dropped or extra requests are caught
explicitly.

---

Outside diff comments:
In `@openapi.yaml`:
- Around line 56-69: Event model currently accepts any URL length and any number
of props while the OpenAPI contract limits url to maxLength 2000 and props to
maxProperties 30; enforce these constraints in the Event model's
initializer/validation (e.g., in Event.init or Event.validate) by rejecting or
throwing when url.count > 2000 or props.count > 30, return/throw a descriptive
error matching API validation, and add/update unit tests to cover the new
validation; also consider regenerating the Swift client from openapi.yaml with
swift-openapi-generator to keep models in sync.

In `@Tests/AviaryInsightsTests/AviaryInsightsTests.swift`:
- Around line 61-72: The test currently decodes request.body into
Operations.post_sol_event.Input.Body.jsonPayload which normalizes away unknown
keys and null-vs-omitted differences; instead, canonicalize and compare the raw
JSON bytes. Replace the round-trip decode of request.body (the use of
decoder.decode into jsonPayload and creation of actualEncoded) with
canonicalization of the raw request.body bytes (e.g., parse to a JSON object and
re-serialize with a deterministic/canonical form) and compare that canonicalized
data to the canonicalized encoding of the expected
Operations.post_sol_event.Input.Body.jsonPayload; keep references to
request.body, Operations.post_sol_event.Input.Body.jsonPayload,
expectedJSONPayload, and the comparison (actual vs expected canonicalized bytes)
to locate and update the assertion.

---

Nitpick comments:
In @.devcontainer/swift-6.3/devcontainer.json:
- Around line 1-39: Summary: multiple devcontainer.json files for
swift-6.1/6.2/6.3 are diverging; extract common bits into a shared base to
reduce config drift. Fix: create a single base devcontainer template that
contains shared keys (features, runArgs, customizations.vscode.settings,
customizations.vscode.extensions, remoteUser) and update each variant (the files
containing "image": "swift:6.3" / "swift:6.2" / "swift:6.1") to reference or be
generated from that base while only overriding the "image" value and any
variant-specific settings; ensure unique symbols in the diff such as "features",
"runArgs", "customizations.vscode.settings", "extensions", and "remoteUser" are
moved to the base and removed from per-version files so future changes are made
once in the base.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 06d61742-ad5e-40b8-9065-79508f718634

📥 Commits

Reviewing files that changed from the base of the PR and between f1b444a and c8a7c81.

⛔ Files ignored due to path filters (2)
  • Sources/AviaryInsights/Generated/Client.swift is excluded by !**/generated/**
  • Sources/AviaryInsights/Generated/Types.swift is excluded by !**/generated/**
📒 Files selected for processing (26)
  • .devcontainer/devcontainer.json
  • .devcontainer/swift-6.1/devcontainer.json
  • .devcontainer/swift-6.2/devcontainer.json
  • .devcontainer/swift-6.3/devcontainer.json
  • .github/workflows/AviaryInsights.yml
  • .mise.toml
  • .swift-format
  • .swiftformat
  • .swiftlint.yml
  • CLAUDE.md
  • Mintfile
  • Package.resolved
  • Package.swift
  • Scripts/generate.sh
  • Scripts/gh-md-toc
  • Scripts/header.sh
  • Scripts/lint.sh
  • Sources/AviaryInsights/Event.swift
  • Sources/AviaryInsights/Operations.swift
  • Sources/AviaryInsights/Plausible.swift
  • Tests/AviaryInsightsTests/AviaryInsightsTests.swift
  • Tests/AviaryInsightsTests/Event.swift
  • Tests/AviaryInsightsTests/MockTransport.swift
  • Tests/AviaryInsightsTests/Revenue.swift
  • openapi-generator-config.yaml
  • openapi.yaml
💤 Files with no reviewable changes (3)
  • .swiftformat
  • Scripts/gh-md-toc
  • Mintfile

Comment thread openapi-generator-config.yaml
Comment thread openapi.yaml
Comment thread Package.swift
Comment thread Scripts/lint.sh
Comment thread Sources/AviaryInsights/Event.swift
Comment thread Sources/AviaryInsights/Plausible.swift
Comment thread Sources/AviaryInsights/Plausible.swift
Comment thread Tests/AviaryInsightsTests/AviaryInsightsTests.swift
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.swiftlint.yml (1)

132-138: Consider documenting why each new rule is disabled.

Disabling several style rules at once is fine, but brief inline rationale (per rule or grouped) will make lint policy intent clearer for contributors and reduce config drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.swiftlint.yml around lines 132 - 138, Add brief inline rationale comments
for each disabled SwiftLint rule listed (switch_case_alignment, trailing_comma,
strict_fileprivate, closure_parameter_position, opening_brace,
optional_data_string_conversion, todo) so future contributors understand the
intent; update the .swiftlint.yml by placing a short comment above or beside
each rule explaining why it’s disabled (or group related rules and provide a
grouped rationale), referencing the exact rule names so reviewers can see the
tradeoffs and any temporary or long-term status.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.swiftlint.yml:
- Around line 132-138: Add brief inline rationale comments for each disabled
SwiftLint rule listed (switch_case_alignment, trailing_comma,
strict_fileprivate, closure_parameter_position, opening_brace,
optional_data_string_conversion, todo) so future contributors understand the
intent; update the .swiftlint.yml by placing a short comment above or beside
each rule explaining why it’s disabled (or group related rules and provide a
grouped rationale), referencing the exact rule names so reviewers can see the
tradeoffs and any temporary or long-term status.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e5eb48ba-4fb1-4f9f-a17f-10e6c87d3edf

📥 Commits

Reviewing files that changed from the base of the PR and between c8a7c81 and 250b6fa.

📒 Files selected for processing (3)
  • .github/workflows/AviaryInsights.yml
  • .swiftlint.yml
  • Scripts/generate.sh
💤 Files with no reviewable changes (1)
  • Scripts/generate.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/AviaryInsights.yml

leogdion added 2 commits April 9, 2026 17:53
Added a step to install curl for Codecov when coverage is present.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/AviaryInsights.yml:
- Around line 20-22: The concurrency group can collide for PRs from different
forks using the same branch name; update the concurrency.group expression to use
the PR number when the event is a pull_request and fall back to the full ref for
other events—replace the current group value (${{ github.workflow }}-${{
github.head_ref || github.ref_name }}) with a conditional that includes
github.event.pull_request.number (e.g., use github.event.pull_request.number
when github.event_name == 'pull_request') and otherwise uses github.ref or
github.ref_name so each PR is globally unique while preserving uniqueness for
push/workflow_dispatch events.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5bfc9b1d-a830-44a5-875f-8401a7e018f7

📥 Commits

Reviewing files that changed from the base of the PR and between 250b6fa and adf1631.

📒 Files selected for processing (1)
  • .github/workflows/AviaryInsights.yml

Comment thread .github/workflows/AviaryInsights.yml
…ostEvent

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
Scripts/lint.sh (1)

29-35: ⚠️ Potential issue | 🟠 Major

CI still skips MIT header enforcement.

Line 29 keeps header.sh behind if [ -z "$CI" ], so the CI=true LINT_MODE=STRICT ./Scripts/lint.sh path never validates headers. That leaves the compliance gap open in the exact mode the workflow now uses.

Suggested adjustment
-if [ -z "$CI" ]; then
-	bash "$SCRIPT_DIR/header.sh" "$PACKAGE_DIR/Sources"
-	bash "$SCRIPT_DIR/header.sh" "$PACKAGE_DIR/Tests"
+bash "$SCRIPT_DIR/header.sh" "$PACKAGE_DIR/Sources"
+bash "$SCRIPT_DIR/header.sh" "$PACKAGE_DIR/Tests"
+
+if [ -z "$CI" ]; then
 	mise exec -- swift-format format --in-place --recursive .
 	mise exec -- swiftlint --fix
 	mise exec -- periphery scan
 fi
+
+if [ -n "$CI" ]; then
+	git diff --exit-code -- Sources Tests
+fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Scripts/lint.sh` around lines 29 - 35, The header enforcement is skipped when
CI is set because the header.sh invocations are inside if [ -z "$CI" ]; move
header.sh calls out of that CI-only guard or change the conditional to also run
headers when LINT_MODE=STRICT (check the LINT_MODE env var) so that header.sh
(invoked via SCRIPT_DIR/header.sh against PACKAGE_DIR/Sources and
PACKAGE_DIR/Tests) executes in the CI=true LINT_MODE=STRICT path; update the
conditional logic around the header.sh calls accordingly.
🧹 Nitpick comments (1)
Tests/AviaryInsightsTests/AviaryInsightsTests+Init.swift (1)

40-75: Consider extracting shared assertions to reduce repetition.

The three tests duplicate the same defaultDomain/userAgent expectations; a tiny helper would keep these focused on constructor differences.

Possible cleanup
 extension AviaryInsightsTests {
+  private func expectClientValues(_ client: Plausible, domain: String, agent: String) {
+    `#expect`(client.defaultDomain == domain)
+    `#expect`(client.userAgent == agent)
+  }
+
   `@Test` internal func initWithDefaultTransport() {
     let domain = UUID().uuidString
     let agent = UUID().uuidString
     let client = Plausible(defaultDomain: domain, userAgent: agent)
-    `#expect`(client.defaultDomain == domain)
-    `#expect`(client.userAgent == agent)
+    expectClientValues(client, domain: domain, agent: agent)
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/AviaryInsightsTests/AviaryInsightsTests`+Init.swift around lines 40 -
75, The three tests initWithDefaultTransport, initWithURLSessionConfiguration,
and initWithURLSession duplicate the same assertions for Plausible.defaultDomain
and Plausible.userAgent; extract a small helper like
assertDefaultDomainAndUserAgent(client:defaultDomain:userAgent:) (or a
test-scoped method) and call it from each test to assert client.defaultDomain ==
domain and client.userAgent == agent, leaving each test focused only on the
constructor differences (keep the `#if` canImport(OpenAPIURLSession) guards
intact).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Tests/AviaryInsightsTests/AviaryInsightsTests`+Init.swift:
- Around line 43-49: The tests currently call Issue.record(...) inside the `#else`
branch causing guaranteed failures when OpenAPIURLSession is unavailable; wrap
each entire `@Test` method with `#if` canImport(OpenAPIURLSession) ... `#endif` so the
test functions (the ones creating Plausible(defaultDomain:userAgent:) and
asserting client.defaultDomain / client.userAgent) are not registered on
unsupported platforms, and remove the internal `#else` Issue.record branches so no
test is recorded when the import check fails.

---

Duplicate comments:
In `@Scripts/lint.sh`:
- Around line 29-35: The header enforcement is skipped when CI is set because
the header.sh invocations are inside if [ -z "$CI" ]; move header.sh calls out
of that CI-only guard or change the conditional to also run headers when
LINT_MODE=STRICT (check the LINT_MODE env var) so that header.sh (invoked via
SCRIPT_DIR/header.sh against PACKAGE_DIR/Sources and PACKAGE_DIR/Tests) executes
in the CI=true LINT_MODE=STRICT path; update the conditional logic around the
header.sh calls accordingly.

---

Nitpick comments:
In `@Tests/AviaryInsightsTests/AviaryInsightsTests`+Init.swift:
- Around line 40-75: The three tests initWithDefaultTransport,
initWithURLSessionConfiguration, and initWithURLSession duplicate the same
assertions for Plausible.defaultDomain and Plausible.userAgent; extract a small
helper like assertDefaultDomainAndUserAgent(client:defaultDomain:userAgent:) (or
a test-scoped method) and call it from each test to assert client.defaultDomain
== domain and client.userAgent == agent, leaving each test focused only on the
constructor differences (keep the `#if` canImport(OpenAPIURLSession) guards
intact).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 29662608-f2be-4dd1-af8b-2061d2dc6b21

📥 Commits

Reviewing files that changed from the base of the PR and between adf1631 and 28757fc.

📒 Files selected for processing (5)
  • .mise.toml
  • Scripts/lint.sh
  • Tests/AviaryInsightsTests/AviaryInsightsTests+Init.swift
  • Tests/AviaryInsightsTests/AviaryInsightsTests.swift
  • codecov.yml
✅ Files skipped from review due to trivial changes (2)
  • codecov.yml
  • .mise.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • Tests/AviaryInsightsTests/AviaryInsightsTests.swift

Comment thread Tests/AviaryInsightsTests/AviaryInsightsTests+Init.swift
leogdion and others added 2 commits April 9, 2026 18:48
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread Tests/AviaryInsightsTests/AviaryInsightsTests+Init.swift
@leogdion leogdion merged commit 81dad96 into main Apr 10, 2026
49 checks passed
leogdion added a commit that referenced this pull request Apr 10, 2026
…flow updates, and openapi.yaml improvements (#26)
@leogdion leogdion deleted the atleast-v1.0.0-beta.4 branch April 10, 2026 14:59
@leogdion leogdion changed the title Implement issue #25: WASM support, Mise migration, swift-format, work… Adding WASM support, Mise migration, swift-format, workflow updates, and openapi.yaml improvements Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update swift-format, SwiftLint, GitHub workflows, migrate Mint to Mise, and add WASM support

1 participant